diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 17:18:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 17:18:18 -0400 |
commit | bd22dc17e49973d3d4925970260e9e37f7580a9f (patch) | |
tree | 581a7c7527f628aa91eb2e0680b765a9673bc974 /drivers/gpu | |
parent | 548ed10228093f1036297a333d1c1064f4daefdc (diff) | |
parent | 98c7b42375011ec37251e6fc85a0471cfe499eea (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"One of the smaller drm -next pulls in ages!
Ben (nouveau) has a rewrite in progress but we decided to leave it
stew for another cycle, so just some fixes from him.
- radeon: lots of documentation work, fixes, more ring and locking
changes, pcie gen2, more dp fixes.
- i915: haswell features, gpu reset fixes, /dev/agpgart removal on
machines that we never used it on, more VGA/HDP fix., more DP fixes
- drm core: cleanups from Daniel, sis 64-bit fixes, range allocator
colouring.
but yeah fairly quiet merge this time, probably because I missed half
of it!"
Trivial add-add conflict in include/linux/pci_regs.h
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (255 commits)
drm/nouveau: init vblank requests list
drm/nv50: extend vblank semaphore to generic dmaobj + offset pair
drm/nouveau: mark most of our ioctls as deprecated, move to compat layer
drm/nouveau: move current gpuobj code out of nouveau_object.c
drm/nouveau/gem: fix object reference leak in a failure path
drm/nv50: rename INVALID_QUERY_OR_TEXTURE error to INVALID_OPERATION
drm/nv84: decode PCRYPT errors
drm/nouveau: dcb table quirk for fdo#50830
nouveau: Fix alignment requirements on src and dst addresses
drm/i915: unbreak lastclose for failed driver init
drm/i915: Set the context before setting up regs for the context.
drm/i915: constify mode in crtc_mode_fixup
drm/i915/lvds: ditch ->prepare special case
drm/i915: dereferencing an error pointer
drm/i915: fix invalid reference handling of the default ctx obj
drm/i915: Add -EIO to the list of known errors for __wait_seqno
drm/i915: Flush the context object from the CPU caches upon switching
drm/radeon: fix dpms on/off on trinity/aruba v2
drm/radeon: on hotplug force link training to happen (v2)
drm/radeon: fix hotplug of DP to DVI|HDMI passive adapters (v2)
...
Diffstat (limited to 'drivers/gpu')
172 files changed, 7450 insertions, 3244 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 65f9d231af14..7282c081fb53 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c | |||
@@ -460,8 +460,8 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
460 | } | 460 | } |
461 | 461 | ||
462 | static bool ast_crtc_mode_fixup(struct drm_crtc *crtc, | 462 | static bool ast_crtc_mode_fixup(struct drm_crtc *crtc, |
463 | struct drm_display_mode *mode, | 463 | const struct drm_display_mode *mode, |
464 | struct drm_display_mode *adjusted_mode) | 464 | struct drm_display_mode *adjusted_mode) |
465 | { | 465 | { |
466 | return true; | 466 | return true; |
467 | } | 467 | } |
@@ -680,7 +680,7 @@ static void ast_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
680 | } | 680 | } |
681 | 681 | ||
682 | static bool ast_mode_fixup(struct drm_encoder *encoder, | 682 | static bool ast_mode_fixup(struct drm_encoder *encoder, |
683 | struct drm_display_mode *mode, | 683 | const struct drm_display_mode *mode, |
684 | struct drm_display_mode *adjusted_mode) | 684 | struct drm_display_mode *adjusted_mode) |
685 | { | 685 | { |
686 | return true; | 686 | return true; |
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index 100f6308c509..a44d31aa4e3c 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c | |||
@@ -97,7 +97,7 @@ static void cirrus_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
97 | * to just pass that straight through, so this does nothing | 97 | * to just pass that straight through, so this does nothing |
98 | */ | 98 | */ |
99 | static bool cirrus_crtc_mode_fixup(struct drm_crtc *crtc, | 99 | static bool cirrus_crtc_mode_fixup(struct drm_crtc *crtc, |
100 | struct drm_display_mode *mode, | 100 | const struct drm_display_mode *mode, |
101 | struct drm_display_mode *adjusted_mode) | 101 | struct drm_display_mode *adjusted_mode) |
102 | { | 102 | { |
103 | return true; | 103 | return true; |
@@ -429,8 +429,8 @@ void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
429 | 429 | ||
430 | 430 | ||
431 | static bool cirrus_encoder_mode_fixup(struct drm_encoder *encoder, | 431 | static bool cirrus_encoder_mode_fixup(struct drm_encoder *encoder, |
432 | struct drm_display_mode *mode, | 432 | const struct drm_display_mode *mode, |
433 | struct drm_display_mode *adjusted_mode) | 433 | struct drm_display_mode *adjusted_mode) |
434 | { | 434 | { |
435 | return true; | 435 | return true; |
436 | } | 436 | } |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 348b367debeb..b356c719f2f1 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
@@ -641,8 +641,6 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) | |||
641 | 641 | ||
642 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) | 642 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) |
643 | return -EINVAL; | 643 | return -EINVAL; |
644 | if (dev->queue_count) | ||
645 | return -EBUSY; /* Not while in use */ | ||
646 | 644 | ||
647 | /* Make sure buffers are located in AGP memory that we own */ | 645 | /* Make sure buffers are located in AGP memory that we own */ |
648 | valid = 0; | 646 | valid = 0; |
@@ -704,7 +702,6 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) | |||
704 | buf->next = NULL; | 702 | buf->next = NULL; |
705 | buf->waiting = 0; | 703 | buf->waiting = 0; |
706 | buf->pending = 0; | 704 | buf->pending = 0; |
707 | init_waitqueue_head(&buf->dma_wait); | ||
708 | buf->file_priv = NULL; | 705 | buf->file_priv = NULL; |
709 | 706 | ||
710 | buf->dev_priv_size = dev->driver->dev_priv_size; | 707 | buf->dev_priv_size = dev->driver->dev_priv_size; |
@@ -796,13 +793,11 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
796 | order = drm_order(request->size); | 793 | order = drm_order(request->size); |
797 | size = 1 << order; | 794 | size = 1 << order; |
798 | 795 | ||
799 | DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n", | 796 | DRM_DEBUG("count=%d, size=%d (%d), order=%d\n", |
800 | request->count, request->size, size, order, dev->queue_count); | 797 | request->count, request->size, size, order); |
801 | 798 | ||
802 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) | 799 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) |
803 | return -EINVAL; | 800 | return -EINVAL; |
804 | if (dev->queue_count) | ||
805 | return -EBUSY; /* Not while in use */ | ||
806 | 801 | ||
807 | alignment = (request->flags & _DRM_PAGE_ALIGN) | 802 | alignment = (request->flags & _DRM_PAGE_ALIGN) |
808 | ? PAGE_ALIGN(size) : size; | 803 | ? PAGE_ALIGN(size) : size; |
@@ -904,7 +899,6 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
904 | buf->next = NULL; | 899 | buf->next = NULL; |
905 | buf->waiting = 0; | 900 | buf->waiting = 0; |
906 | buf->pending = 0; | 901 | buf->pending = 0; |
907 | init_waitqueue_head(&buf->dma_wait); | ||
908 | buf->file_priv = NULL; | 902 | buf->file_priv = NULL; |
909 | 903 | ||
910 | buf->dev_priv_size = dev->driver->dev_priv_size; | 904 | buf->dev_priv_size = dev->driver->dev_priv_size; |
@@ -1019,8 +1013,6 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request | |||
1019 | 1013 | ||
1020 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) | 1014 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) |
1021 | return -EINVAL; | 1015 | return -EINVAL; |
1022 | if (dev->queue_count) | ||
1023 | return -EBUSY; /* Not while in use */ | ||
1024 | 1016 | ||
1025 | spin_lock(&dev->count_lock); | 1017 | spin_lock(&dev->count_lock); |
1026 | if (dev->buf_use) { | 1018 | if (dev->buf_use) { |
@@ -1071,7 +1063,6 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request | |||
1071 | buf->next = NULL; | 1063 | buf->next = NULL; |
1072 | buf->waiting = 0; | 1064 | buf->waiting = 0; |
1073 | buf->pending = 0; | 1065 | buf->pending = 0; |
1074 | init_waitqueue_head(&buf->dma_wait); | ||
1075 | buf->file_priv = NULL; | 1066 | buf->file_priv = NULL; |
1076 | 1067 | ||
1077 | buf->dev_priv_size = dev->driver->dev_priv_size; | 1068 | buf->dev_priv_size = dev->driver->dev_priv_size; |
@@ -1177,8 +1168,6 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request | |||
1177 | 1168 | ||
1178 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) | 1169 | if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) |
1179 | return -EINVAL; | 1170 | return -EINVAL; |
1180 | if (dev->queue_count) | ||
1181 | return -EBUSY; /* Not while in use */ | ||
1182 | 1171 | ||
1183 | spin_lock(&dev->count_lock); | 1172 | spin_lock(&dev->count_lock); |
1184 | if (dev->buf_use) { | 1173 | if (dev->buf_use) { |
@@ -1228,7 +1217,6 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request | |||
1228 | buf->next = NULL; | 1217 | buf->next = NULL; |
1229 | buf->waiting = 0; | 1218 | buf->waiting = 0; |
1230 | buf->pending = 0; | 1219 | buf->pending = 0; |
1231 | init_waitqueue_head(&buf->dma_wait); | ||
1232 | buf->file_priv = NULL; | 1220 | buf->file_priv = NULL; |
1233 | 1221 | ||
1234 | buf->dev_priv_size = dev->driver->dev_priv_size; | 1222 | buf->dev_priv_size = dev->driver->dev_priv_size; |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 1c7a1c0d3edd..70b13fc19396 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
@@ -46,7 +46,6 @@ static struct drm_info_list drm_debugfs_list[] = { | |||
46 | {"name", drm_name_info, 0}, | 46 | {"name", drm_name_info, 0}, |
47 | {"vm", drm_vm_info, 0}, | 47 | {"vm", drm_vm_info, 0}, |
48 | {"clients", drm_clients_info, 0}, | 48 | {"clients", drm_clients_info, 0}, |
49 | {"queues", drm_queues_info, 0}, | ||
50 | {"bufs", drm_bufs_info, 0}, | 49 | {"bufs", drm_bufs_info, 0}, |
51 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, | 50 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, |
52 | #if DRM_DEBUG_CODE | 51 | #if DRM_DEBUG_CODE |
diff --git a/drivers/gpu/drm/drm_dma.c b/drivers/gpu/drm/drm_dma.c index cfb4e333ec0f..08f5e5309b22 100644 --- a/drivers/gpu/drm/drm_dma.c +++ b/drivers/gpu/drm/drm_dma.c | |||
@@ -120,11 +120,6 @@ void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf) | |||
120 | buf->pending = 0; | 120 | buf->pending = 0; |
121 | buf->file_priv = NULL; | 121 | buf->file_priv = NULL; |
122 | buf->used = 0; | 122 | buf->used = 0; |
123 | |||
124 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) | ||
125 | && waitqueue_active(&buf->dma_wait)) { | ||
126 | wake_up_interruptible(&buf->dma_wait); | ||
127 | } | ||
128 | } | 123 | } |
129 | 124 | ||
130 | /** | 125 | /** |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8a9d0792e4ec..9238de4009fa 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -182,7 +182,6 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
182 | int drm_lastclose(struct drm_device * dev) | 182 | int drm_lastclose(struct drm_device * dev) |
183 | { | 183 | { |
184 | struct drm_vma_entry *vma, *vma_temp; | 184 | struct drm_vma_entry *vma, *vma_temp; |
185 | int i; | ||
186 | 185 | ||
187 | DRM_DEBUG("\n"); | 186 | DRM_DEBUG("\n"); |
188 | 187 | ||
@@ -228,16 +227,6 @@ int drm_lastclose(struct drm_device * dev) | |||
228 | kfree(vma); | 227 | kfree(vma); |
229 | } | 228 | } |
230 | 229 | ||
231 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { | ||
232 | for (i = 0; i < dev->queue_count; i++) { | ||
233 | kfree(dev->queuelist[i]); | ||
234 | dev->queuelist[i] = NULL; | ||
235 | } | ||
236 | kfree(dev->queuelist); | ||
237 | dev->queuelist = NULL; | ||
238 | } | ||
239 | dev->queue_count = 0; | ||
240 | |||
241 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && | 230 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && |
242 | !drm_core_check_feature(dev, DRIVER_MODESET)) | 231 | !drm_core_check_feature(dev, DRIVER_MODESET)) |
243 | drm_dma_takedown(dev); | 232 | drm_dma_takedown(dev); |
@@ -486,7 +475,7 @@ long drm_ioctl(struct file *filp, | |||
486 | kfree(kdata); | 475 | kfree(kdata); |
487 | atomic_dec(&dev->ioctl_count); | 476 | atomic_dec(&dev->ioctl_count); |
488 | if (retcode) | 477 | if (retcode) |
489 | DRM_DEBUG("ret = %x\n", retcode); | 478 | DRM_DEBUG("ret = %d\n", retcode); |
490 | return retcode; | 479 | return retcode; |
491 | } | 480 | } |
492 | 481 | ||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5683b7fdd746..f546d1e8af82 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -228,7 +228,7 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) | |||
228 | int i, ret; | 228 | int i, ret; |
229 | for (i = 0; i < fb_helper->crtc_count; i++) { | 229 | for (i = 0; i < fb_helper->crtc_count; i++) { |
230 | struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; | 230 | struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; |
231 | ret = drm_crtc_helper_set_config(mode_set); | 231 | ret = mode_set->crtc->funcs->set_config(mode_set); |
232 | if (ret) | 232 | if (ret) |
233 | error = true; | 233 | error = true; |
234 | } | 234 | } |
@@ -1353,7 +1353,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) | |||
1353 | struct drm_device *dev = fb_helper->dev; | 1353 | struct drm_device *dev = fb_helper->dev; |
1354 | int count = 0; | 1354 | int count = 0; |
1355 | u32 max_width, max_height, bpp_sel; | 1355 | u32 max_width, max_height, bpp_sel; |
1356 | bool bound = false, crtcs_bound = false; | 1356 | int bound = 0, crtcs_bound = 0; |
1357 | struct drm_crtc *crtc; | 1357 | struct drm_crtc *crtc; |
1358 | 1358 | ||
1359 | if (!fb_helper->fb) | 1359 | if (!fb_helper->fb) |
@@ -1362,12 +1362,12 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) | |||
1362 | mutex_lock(&dev->mode_config.mutex); | 1362 | mutex_lock(&dev->mode_config.mutex); |
1363 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 1363 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
1364 | if (crtc->fb) | 1364 | if (crtc->fb) |
1365 | crtcs_bound = true; | 1365 | crtcs_bound++; |
1366 | if (crtc->fb == fb_helper->fb) | 1366 | if (crtc->fb == fb_helper->fb) |
1367 | bound = true; | 1367 | bound++; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | if (!bound && crtcs_bound) { | 1370 | if (bound < crtcs_bound) { |
1371 | fb_helper->delayed_hotplug = true; | 1371 | fb_helper->delayed_hotplug = true; |
1372 | mutex_unlock(&dev->mode_config.mutex); | 1372 | mutex_unlock(&dev->mode_config.mutex); |
1373 | return 0; | 1373 | return 0; |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 123de28f94ef..5062eec673f1 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -75,10 +75,6 @@ static int drm_setup(struct drm_device * dev) | |||
75 | 75 | ||
76 | dev->sigdata.lock = NULL; | 76 | dev->sigdata.lock = NULL; |
77 | 77 | ||
78 | dev->queue_count = 0; | ||
79 | dev->queue_reserved = 0; | ||
80 | dev->queue_slots = 0; | ||
81 | dev->queuelist = NULL; | ||
82 | dev->context_flag = 0; | 78 | dev->context_flag = 0; |
83 | dev->interrupt_flag = 0; | 79 | dev->interrupt_flag = 0; |
84 | dev->dma_flag = 0; | 80 | dev->dma_flag = 0; |
@@ -144,12 +140,12 @@ int drm_open(struct inode *inode, struct file *filp) | |||
144 | } | 140 | } |
145 | if (!retcode) { | 141 | if (!retcode) { |
146 | mutex_lock(&dev->struct_mutex); | 142 | mutex_lock(&dev->struct_mutex); |
147 | if (minor->type == DRM_MINOR_LEGACY) { | 143 | if (dev->dev_mapping == NULL) |
148 | if (dev->dev_mapping == NULL) | 144 | dev->dev_mapping = &inode->i_data; |
149 | dev->dev_mapping = inode->i_mapping; | 145 | /* ihold ensures nobody can remove inode with our i_data */ |
150 | else if (dev->dev_mapping != inode->i_mapping) | 146 | ihold(container_of(dev->dev_mapping, struct inode, i_data)); |
151 | retcode = -ENODEV; | 147 | inode->i_mapping = dev->dev_mapping; |
152 | } | 148 | filp->f_mapping = dev->dev_mapping; |
153 | mutex_unlock(&dev->struct_mutex); | 149 | mutex_unlock(&dev->struct_mutex); |
154 | } | 150 | } |
155 | 151 | ||
@@ -370,72 +366,16 @@ int drm_fasync(int fd, struct file *filp, int on) | |||
370 | } | 366 | } |
371 | EXPORT_SYMBOL(drm_fasync); | 367 | EXPORT_SYMBOL(drm_fasync); |
372 | 368 | ||
373 | /* | ||
374 | * Reclaim locked buffers; note that this may be a bad idea if the current | ||
375 | * context doesn't have the hw lock... | ||
376 | */ | ||
377 | static void drm_reclaim_locked_buffers(struct drm_device *dev, struct file *f) | ||
378 | { | ||
379 | struct drm_file *file_priv = f->private_data; | ||
380 | |||
381 | if (drm_i_have_hw_lock(dev, file_priv)) { | ||
382 | dev->driver->reclaim_buffers_locked(dev, file_priv); | ||
383 | } else { | ||
384 | unsigned long _end = jiffies + 3 * DRM_HZ; | ||
385 | int locked = 0; | ||
386 | |||
387 | drm_idlelock_take(&file_priv->master->lock); | ||
388 | |||
389 | /* | ||
390 | * Wait for a while. | ||
391 | */ | ||
392 | do { | ||
393 | spin_lock_bh(&file_priv->master->lock.spinlock); | ||
394 | locked = file_priv->master->lock.idle_has_lock; | ||
395 | spin_unlock_bh(&file_priv->master->lock.spinlock); | ||
396 | if (locked) | ||
397 | break; | ||
398 | schedule(); | ||
399 | } while (!time_after_eq(jiffies, _end)); | ||
400 | |||
401 | if (!locked) { | ||
402 | DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" | ||
403 | "\tdriver to use reclaim_buffers_idlelocked() instead.\n" | ||
404 | "\tI will go on reclaiming the buffers anyway.\n"); | ||
405 | } | ||
406 | |||
407 | dev->driver->reclaim_buffers_locked(dev, file_priv); | ||
408 | drm_idlelock_release(&file_priv->master->lock); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | static void drm_master_release(struct drm_device *dev, struct file *filp) | 369 | static void drm_master_release(struct drm_device *dev, struct file *filp) |
413 | { | 370 | { |
414 | struct drm_file *file_priv = filp->private_data; | 371 | struct drm_file *file_priv = filp->private_data; |
415 | 372 | ||
416 | if (dev->driver->reclaim_buffers_locked && | ||
417 | file_priv->master->lock.hw_lock) | ||
418 | drm_reclaim_locked_buffers(dev, filp); | ||
419 | |||
420 | if (dev->driver->reclaim_buffers_idlelocked && | ||
421 | file_priv->master->lock.hw_lock) { | ||
422 | drm_idlelock_take(&file_priv->master->lock); | ||
423 | dev->driver->reclaim_buffers_idlelocked(dev, file_priv); | ||
424 | drm_idlelock_release(&file_priv->master->lock); | ||
425 | } | ||
426 | |||
427 | |||
428 | if (drm_i_have_hw_lock(dev, file_priv)) { | 373 | if (drm_i_have_hw_lock(dev, file_priv)) { |
429 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | 374 | DRM_DEBUG("File %p released, freeing lock for context %d\n", |
430 | filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); | 375 | filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); |
431 | drm_lock_free(&file_priv->master->lock, | 376 | drm_lock_free(&file_priv->master->lock, |
432 | _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); | 377 | _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); |
433 | } | 378 | } |
434 | |||
435 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && | ||
436 | !dev->driver->reclaim_buffers_locked) { | ||
437 | dev->driver->reclaim_buffers(dev, file_priv); | ||
438 | } | ||
439 | } | 379 | } |
440 | 380 | ||
441 | static void drm_events_release(struct drm_file *file_priv) | 381 | static void drm_events_release(struct drm_file *file_priv) |
@@ -505,6 +445,9 @@ int drm_release(struct inode *inode, struct file *filp) | |||
505 | if (file_priv->minor->master) | 445 | if (file_priv->minor->master) |
506 | drm_master_release(dev, filp); | 446 | drm_master_release(dev, filp); |
507 | 447 | ||
448 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) | ||
449 | drm_core_reclaim_buffers(dev, file_priv); | ||
450 | |||
508 | drm_events_release(file_priv); | 451 | drm_events_release(file_priv); |
509 | 452 | ||
510 | if (dev->driver->driver_features & DRIVER_MODESET) | 453 | if (dev->driver->driver_features & DRIVER_MODESET) |
@@ -566,6 +509,9 @@ int drm_release(struct inode *inode, struct file *filp) | |||
566 | } | 509 | } |
567 | } | 510 | } |
568 | 511 | ||
512 | BUG_ON(dev->dev_mapping == NULL); | ||
513 | iput(container_of(dev->dev_mapping, struct inode, i_data)); | ||
514 | |||
569 | /* drop the reference held my the file priv */ | 515 | /* drop the reference held my the file priv */ |
570 | drm_master_put(&file_priv->master); | 516 | drm_master_put(&file_priv->master); |
571 | file_priv->is_master = 0; | 517 | file_priv->is_master = 0; |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index d58e69da1fb5..fbe0842038b5 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -354,7 +354,7 @@ drm_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
354 | 354 | ||
355 | /* Get a DRM GEM mmap offset allocated... */ | 355 | /* Get a DRM GEM mmap offset allocated... */ |
356 | list->file_offset_node = drm_mm_search_free(&mm->offset_manager, | 356 | list->file_offset_node = drm_mm_search_free(&mm->offset_manager, |
357 | obj->size / PAGE_SIZE, 0, 0); | 357 | obj->size / PAGE_SIZE, 0, false); |
358 | 358 | ||
359 | if (!list->file_offset_node) { | 359 | if (!list->file_offset_node) { |
360 | DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); | 360 | DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index ab1162da70f8..8928edbb94c7 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -110,42 +110,6 @@ int drm_vm_info(struct seq_file *m, void *data) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /** | 112 | /** |
113 | * Called when "/proc/dri/.../queues" is read. | ||
114 | */ | ||
115 | int drm_queues_info(struct seq_file *m, void *data) | ||
116 | { | ||
117 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
118 | struct drm_device *dev = node->minor->dev; | ||
119 | int i; | ||
120 | struct drm_queue *q; | ||
121 | |||
122 | mutex_lock(&dev->struct_mutex); | ||
123 | seq_printf(m, " ctx/flags use fin" | ||
124 | " blk/rw/rwf wait flushed queued" | ||
125 | " locks\n\n"); | ||
126 | for (i = 0; i < dev->queue_count; i++) { | ||
127 | q = dev->queuelist[i]; | ||
128 | atomic_inc(&q->use_count); | ||
129 | seq_printf(m, "%5d/0x%03x %5d %5d" | ||
130 | " %5d/%c%c/%c%c%c %5Zd\n", | ||
131 | i, | ||
132 | q->flags, | ||
133 | atomic_read(&q->use_count), | ||
134 | atomic_read(&q->finalization), | ||
135 | atomic_read(&q->block_count), | ||
136 | atomic_read(&q->block_read) ? 'r' : '-', | ||
137 | atomic_read(&q->block_write) ? 'w' : '-', | ||
138 | waitqueue_active(&q->read_queue) ? 'r' : '-', | ||
139 | waitqueue_active(&q->write_queue) ? 'w' : '-', | ||
140 | waitqueue_active(&q->flush_queue) ? 'f' : '-', | ||
141 | DRM_BUFCOUNT(&q->waitlist)); | ||
142 | atomic_dec(&q->use_count); | ||
143 | } | ||
144 | mutex_unlock(&dev->struct_mutex); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * Called when "/proc/dri/.../bufs" is read. | 113 | * Called when "/proc/dri/.../bufs" is read. |
150 | */ | 114 | */ |
151 | int drm_bufs_info(struct seq_file *m, void *data) | 115 | int drm_bufs_info(struct seq_file *m, void *data) |
@@ -235,7 +199,7 @@ int drm_clients_info(struct seq_file *m, void *data) | |||
235 | } | 199 | } |
236 | 200 | ||
237 | 201 | ||
238 | int drm_gem_one_name_info(int id, void *ptr, void *data) | 202 | static int drm_gem_one_name_info(int id, void *ptr, void *data) |
239 | { | 203 | { |
240 | struct drm_gem_object *obj = ptr; | 204 | struct drm_gem_object *obj = ptr; |
241 | struct seq_file *m = data; | 205 | struct seq_file *m = data; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index c798eeae0a03..03f16f352fe2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -974,7 +974,6 @@ EXPORT_SYMBOL(drm_vblank_off); | |||
974 | * drm_vblank_pre_modeset - account for vblanks across mode sets | 974 | * drm_vblank_pre_modeset - account for vblanks across mode sets |
975 | * @dev: DRM device | 975 | * @dev: DRM device |
976 | * @crtc: CRTC in question | 976 | * @crtc: CRTC in question |
977 | * @post: post or pre mode set? | ||
978 | * | 977 | * |
979 | * Account for vblank events across mode setting events, which will likely | 978 | * Account for vblank events across mode setting events, which will likely |
980 | * reset the hardware frame counter. | 979 | * reset the hardware frame counter. |
@@ -1037,6 +1036,10 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, | |||
1037 | if (!dev->num_crtcs) | 1036 | if (!dev->num_crtcs) |
1038 | return 0; | 1037 | return 0; |
1039 | 1038 | ||
1039 | /* KMS drivers handle this internally */ | ||
1040 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
1041 | return 0; | ||
1042 | |||
1040 | crtc = modeset->crtc; | 1043 | crtc = modeset->crtc; |
1041 | if (crtc >= dev->num_crtcs) | 1044 | if (crtc >= dev->num_crtcs) |
1042 | return -EINVAL; | 1045 | return -EINVAL; |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 521152041691..32039553e172 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -70,10 +70,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
70 | lock->context, task_pid_nr(current), | 70 | lock->context, task_pid_nr(current), |
71 | master->lock.hw_lock->lock, lock->flags); | 71 | master->lock.hw_lock->lock, lock->flags); |
72 | 72 | ||
73 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)) | ||
74 | if (lock->context < 0) | ||
75 | return -EINVAL; | ||
76 | |||
77 | add_wait_queue(&master->lock.lock_queue, &entry); | 73 | add_wait_queue(&master->lock.lock_queue, &entry); |
78 | spin_lock_bh(&master->lock.spinlock); | 74 | spin_lock_bh(&master->lock.spinlock); |
79 | master->lock.user_waiters++; | 75 | master->lock.user_waiters++; |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 961fb54f4266..9bb82f7f0061 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -118,45 +118,53 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) | |||
118 | 118 | ||
119 | static void drm_mm_insert_helper(struct drm_mm_node *hole_node, | 119 | static void drm_mm_insert_helper(struct drm_mm_node *hole_node, |
120 | struct drm_mm_node *node, | 120 | struct drm_mm_node *node, |
121 | unsigned long size, unsigned alignment) | 121 | unsigned long size, unsigned alignment, |
122 | unsigned long color) | ||
122 | { | 123 | { |
123 | struct drm_mm *mm = hole_node->mm; | 124 | struct drm_mm *mm = hole_node->mm; |
124 | unsigned long tmp = 0, wasted = 0; | ||
125 | unsigned long hole_start = drm_mm_hole_node_start(hole_node); | 125 | unsigned long hole_start = drm_mm_hole_node_start(hole_node); |
126 | unsigned long hole_end = drm_mm_hole_node_end(hole_node); | 126 | unsigned long hole_end = drm_mm_hole_node_end(hole_node); |
127 | unsigned long adj_start = hole_start; | ||
128 | unsigned long adj_end = hole_end; | ||
127 | 129 | ||
128 | BUG_ON(!hole_node->hole_follows || node->allocated); | 130 | BUG_ON(!hole_node->hole_follows || node->allocated); |
129 | 131 | ||
130 | if (alignment) | 132 | if (mm->color_adjust) |
131 | tmp = hole_start % alignment; | 133 | mm->color_adjust(hole_node, color, &adj_start, &adj_end); |
132 | 134 | ||
133 | if (!tmp) { | 135 | if (alignment) { |
136 | unsigned tmp = adj_start % alignment; | ||
137 | if (tmp) | ||
138 | adj_start += alignment - tmp; | ||
139 | } | ||
140 | |||
141 | if (adj_start == hole_start) { | ||
134 | hole_node->hole_follows = 0; | 142 | hole_node->hole_follows = 0; |
135 | list_del_init(&hole_node->hole_stack); | 143 | list_del(&hole_node->hole_stack); |
136 | } else | 144 | } |
137 | wasted = alignment - tmp; | ||
138 | 145 | ||
139 | node->start = hole_start + wasted; | 146 | node->start = adj_start; |
140 | node->size = size; | 147 | node->size = size; |
141 | node->mm = mm; | 148 | node->mm = mm; |
149 | node->color = color; | ||
142 | node->allocated = 1; | 150 | node->allocated = 1; |
143 | 151 | ||
144 | INIT_LIST_HEAD(&node->hole_stack); | 152 | INIT_LIST_HEAD(&node->hole_stack); |
145 | list_add(&node->node_list, &hole_node->node_list); | 153 | list_add(&node->node_list, &hole_node->node_list); |
146 | 154 | ||
147 | BUG_ON(node->start + node->size > hole_end); | 155 | BUG_ON(node->start + node->size > adj_end); |
148 | 156 | ||
157 | node->hole_follows = 0; | ||
149 | if (node->start + node->size < hole_end) { | 158 | if (node->start + node->size < hole_end) { |
150 | list_add(&node->hole_stack, &mm->hole_stack); | 159 | list_add(&node->hole_stack, &mm->hole_stack); |
151 | node->hole_follows = 1; | 160 | node->hole_follows = 1; |
152 | } else { | ||
153 | node->hole_follows = 0; | ||
154 | } | 161 | } |
155 | } | 162 | } |
156 | 163 | ||
157 | struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, | 164 | struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, |
158 | unsigned long size, | 165 | unsigned long size, |
159 | unsigned alignment, | 166 | unsigned alignment, |
167 | unsigned long color, | ||
160 | int atomic) | 168 | int atomic) |
161 | { | 169 | { |
162 | struct drm_mm_node *node; | 170 | struct drm_mm_node *node; |
@@ -165,7 +173,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, | |||
165 | if (unlikely(node == NULL)) | 173 | if (unlikely(node == NULL)) |
166 | return NULL; | 174 | return NULL; |
167 | 175 | ||
168 | drm_mm_insert_helper(hole_node, node, size, alignment); | 176 | drm_mm_insert_helper(hole_node, node, size, alignment, color); |
169 | 177 | ||
170 | return node; | 178 | return node; |
171 | } | 179 | } |
@@ -181,11 +189,11 @@ int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, | |||
181 | { | 189 | { |
182 | struct drm_mm_node *hole_node; | 190 | struct drm_mm_node *hole_node; |
183 | 191 | ||
184 | hole_node = drm_mm_search_free(mm, size, alignment, 0); | 192 | hole_node = drm_mm_search_free(mm, size, alignment, false); |
185 | if (!hole_node) | 193 | if (!hole_node) |
186 | return -ENOSPC; | 194 | return -ENOSPC; |
187 | 195 | ||
188 | drm_mm_insert_helper(hole_node, node, size, alignment); | 196 | drm_mm_insert_helper(hole_node, node, size, alignment, 0); |
189 | 197 | ||
190 | return 0; | 198 | return 0; |
191 | } | 199 | } |
@@ -194,50 +202,57 @@ EXPORT_SYMBOL(drm_mm_insert_node); | |||
194 | static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, | 202 | static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, |
195 | struct drm_mm_node *node, | 203 | struct drm_mm_node *node, |
196 | unsigned long size, unsigned alignment, | 204 | unsigned long size, unsigned alignment, |
205 | unsigned long color, | ||
197 | unsigned long start, unsigned long end) | 206 | unsigned long start, unsigned long end) |
198 | { | 207 | { |
199 | struct drm_mm *mm = hole_node->mm; | 208 | struct drm_mm *mm = hole_node->mm; |
200 | unsigned long tmp = 0, wasted = 0; | ||
201 | unsigned long hole_start = drm_mm_hole_node_start(hole_node); | 209 | unsigned long hole_start = drm_mm_hole_node_start(hole_node); |
202 | unsigned long hole_end = drm_mm_hole_node_end(hole_node); | 210 | unsigned long hole_end = drm_mm_hole_node_end(hole_node); |
211 | unsigned long adj_start = hole_start; | ||
212 | unsigned long adj_end = hole_end; | ||
203 | 213 | ||
204 | BUG_ON(!hole_node->hole_follows || node->allocated); | 214 | BUG_ON(!hole_node->hole_follows || node->allocated); |
205 | 215 | ||
206 | if (hole_start < start) | 216 | if (mm->color_adjust) |
207 | wasted += start - hole_start; | 217 | mm->color_adjust(hole_node, color, &adj_start, &adj_end); |
208 | if (alignment) | ||
209 | tmp = (hole_start + wasted) % alignment; | ||
210 | 218 | ||
211 | if (tmp) | 219 | if (adj_start < start) |
212 | wasted += alignment - tmp; | 220 | adj_start = start; |
221 | |||
222 | if (alignment) { | ||
223 | unsigned tmp = adj_start % alignment; | ||
224 | if (tmp) | ||
225 | adj_start += alignment - tmp; | ||
226 | } | ||
213 | 227 | ||
214 | if (!wasted) { | 228 | if (adj_start == hole_start) { |
215 | hole_node->hole_follows = 0; | 229 | hole_node->hole_follows = 0; |
216 | list_del_init(&hole_node->hole_stack); | 230 | list_del(&hole_node->hole_stack); |
217 | } | 231 | } |
218 | 232 | ||
219 | node->start = hole_start + wasted; | 233 | node->start = adj_start; |
220 | node->size = size; | 234 | node->size = size; |
221 | node->mm = mm; | 235 | node->mm = mm; |
236 | node->color = color; | ||
222 | node->allocated = 1; | 237 | node->allocated = 1; |
223 | 238 | ||
224 | INIT_LIST_HEAD(&node->hole_stack); | 239 | INIT_LIST_HEAD(&node->hole_stack); |
225 | list_add(&node->node_list, &hole_node->node_list); | 240 | list_add(&node->node_list, &hole_node->node_list); |
226 | 241 | ||
227 | BUG_ON(node->start + node->size > hole_end); | 242 | BUG_ON(node->start + node->size > adj_end); |
228 | BUG_ON(node->start + node->size > end); | 243 | BUG_ON(node->start + node->size > end); |
229 | 244 | ||
245 | node->hole_follows = 0; | ||
230 | if (node->start + node->size < hole_end) { | 246 | if (node->start + node->size < hole_end) { |
231 | list_add(&node->hole_stack, &mm->hole_stack); | 247 | list_add(&node->hole_stack, &mm->hole_stack); |
232 | node->hole_follows = 1; | 248 | node->hole_follows = 1; |
233 | } else { | ||
234 | node->hole_follows = 0; | ||
235 | } | 249 | } |
236 | } | 250 | } |
237 | 251 | ||
238 | struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node, | 252 | struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node, |
239 | unsigned long size, | 253 | unsigned long size, |
240 | unsigned alignment, | 254 | unsigned alignment, |
255 | unsigned long color, | ||
241 | unsigned long start, | 256 | unsigned long start, |
242 | unsigned long end, | 257 | unsigned long end, |
243 | int atomic) | 258 | int atomic) |
@@ -248,7 +263,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node | |||
248 | if (unlikely(node == NULL)) | 263 | if (unlikely(node == NULL)) |
249 | return NULL; | 264 | return NULL; |
250 | 265 | ||
251 | drm_mm_insert_helper_range(hole_node, node, size, alignment, | 266 | drm_mm_insert_helper_range(hole_node, node, size, alignment, color, |
252 | start, end); | 267 | start, end); |
253 | 268 | ||
254 | return node; | 269 | return node; |
@@ -267,11 +282,11 @@ int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, | |||
267 | struct drm_mm_node *hole_node; | 282 | struct drm_mm_node *hole_node; |
268 | 283 | ||
269 | hole_node = drm_mm_search_free_in_range(mm, size, alignment, | 284 | hole_node = drm_mm_search_free_in_range(mm, size, alignment, |
270 | start, end, 0); | 285 | start, end, false); |
271 | if (!hole_node) | 286 | if (!hole_node) |
272 | return -ENOSPC; | 287 | return -ENOSPC; |
273 | 288 | ||
274 | drm_mm_insert_helper_range(hole_node, node, size, alignment, | 289 | drm_mm_insert_helper_range(hole_node, node, size, alignment, 0, |
275 | start, end); | 290 | start, end); |
276 | 291 | ||
277 | return 0; | 292 | return 0; |
@@ -336,27 +351,23 @@ EXPORT_SYMBOL(drm_mm_put_block); | |||
336 | static int check_free_hole(unsigned long start, unsigned long end, | 351 | static int check_free_hole(unsigned long start, unsigned long end, |
337 | unsigned long size, unsigned alignment) | 352 | unsigned long size, unsigned alignment) |
338 | { | 353 | { |
339 | unsigned wasted = 0; | ||
340 | |||
341 | if (end - start < size) | 354 | if (end - start < size) |
342 | return 0; | 355 | return 0; |
343 | 356 | ||
344 | if (alignment) { | 357 | if (alignment) { |
345 | unsigned tmp = start % alignment; | 358 | unsigned tmp = start % alignment; |
346 | if (tmp) | 359 | if (tmp) |
347 | wasted = alignment - tmp; | 360 | start += alignment - tmp; |
348 | } | ||
349 | |||
350 | if (end >= start + size + wasted) { | ||
351 | return 1; | ||
352 | } | 361 | } |
353 | 362 | ||
354 | return 0; | 363 | return end >= start + size; |
355 | } | 364 | } |
356 | 365 | ||
357 | struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | 366 | struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, |
358 | unsigned long size, | 367 | unsigned long size, |
359 | unsigned alignment, int best_match) | 368 | unsigned alignment, |
369 | unsigned long color, | ||
370 | bool best_match) | ||
360 | { | 371 | { |
361 | struct drm_mm_node *entry; | 372 | struct drm_mm_node *entry; |
362 | struct drm_mm_node *best; | 373 | struct drm_mm_node *best; |
@@ -368,10 +379,17 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
368 | best_size = ~0UL; | 379 | best_size = ~0UL; |
369 | 380 | ||
370 | list_for_each_entry(entry, &mm->hole_stack, hole_stack) { | 381 | list_for_each_entry(entry, &mm->hole_stack, hole_stack) { |
382 | unsigned long adj_start = drm_mm_hole_node_start(entry); | ||
383 | unsigned long adj_end = drm_mm_hole_node_end(entry); | ||
384 | |||
385 | if (mm->color_adjust) { | ||
386 | mm->color_adjust(entry, color, &adj_start, &adj_end); | ||
387 | if (adj_end <= adj_start) | ||
388 | continue; | ||
389 | } | ||
390 | |||
371 | BUG_ON(!entry->hole_follows); | 391 | BUG_ON(!entry->hole_follows); |
372 | if (!check_free_hole(drm_mm_hole_node_start(entry), | 392 | if (!check_free_hole(adj_start, adj_end, size, alignment)) |
373 | drm_mm_hole_node_end(entry), | ||
374 | size, alignment)) | ||
375 | continue; | 393 | continue; |
376 | 394 | ||
377 | if (!best_match) | 395 | if (!best_match) |
@@ -385,14 +403,15 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
385 | 403 | ||
386 | return best; | 404 | return best; |
387 | } | 405 | } |
388 | EXPORT_SYMBOL(drm_mm_search_free); | 406 | EXPORT_SYMBOL(drm_mm_search_free_generic); |
389 | 407 | ||
390 | struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | 408 | struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm, |
391 | unsigned long size, | 409 | unsigned long size, |
392 | unsigned alignment, | 410 | unsigned alignment, |
393 | unsigned long start, | 411 | unsigned long color, |
394 | unsigned long end, | 412 | unsigned long start, |
395 | int best_match) | 413 | unsigned long end, |
414 | bool best_match) | ||
396 | { | 415 | { |
397 | struct drm_mm_node *entry; | 416 | struct drm_mm_node *entry; |
398 | struct drm_mm_node *best; | 417 | struct drm_mm_node *best; |
@@ -410,6 +429,13 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
410 | end : drm_mm_hole_node_end(entry); | 429 | end : drm_mm_hole_node_end(entry); |
411 | 430 | ||
412 | BUG_ON(!entry->hole_follows); | 431 | BUG_ON(!entry->hole_follows); |
432 | |||
433 | if (mm->color_adjust) { | ||
434 | mm->color_adjust(entry, color, &adj_start, &adj_end); | ||
435 | if (adj_end <= adj_start) | ||
436 | continue; | ||
437 | } | ||
438 | |||
413 | if (!check_free_hole(adj_start, adj_end, size, alignment)) | 439 | if (!check_free_hole(adj_start, adj_end, size, alignment)) |
414 | continue; | 440 | continue; |
415 | 441 | ||
@@ -424,7 +450,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
424 | 450 | ||
425 | return best; | 451 | return best; |
426 | } | 452 | } |
427 | EXPORT_SYMBOL(drm_mm_search_free_in_range); | 453 | EXPORT_SYMBOL(drm_mm_search_free_in_range_generic); |
428 | 454 | ||
429 | /** | 455 | /** |
430 | * Moves an allocation. To be used with embedded struct drm_mm_node. | 456 | * Moves an allocation. To be used with embedded struct drm_mm_node. |
@@ -437,6 +463,7 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) | |||
437 | new->mm = old->mm; | 463 | new->mm = old->mm; |
438 | new->start = old->start; | 464 | new->start = old->start; |
439 | new->size = old->size; | 465 | new->size = old->size; |
466 | new->color = old->color; | ||
440 | 467 | ||
441 | old->allocated = 0; | 468 | old->allocated = 0; |
442 | new->allocated = 1; | 469 | new->allocated = 1; |
@@ -452,9 +479,12 @@ EXPORT_SYMBOL(drm_mm_replace_node); | |||
452 | * Warning: As long as the scan list is non-empty, no other operations than | 479 | * Warning: As long as the scan list is non-empty, no other operations than |
453 | * adding/removing nodes to/from the scan list are allowed. | 480 | * adding/removing nodes to/from the scan list are allowed. |
454 | */ | 481 | */ |
455 | void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, | 482 | void drm_mm_init_scan(struct drm_mm *mm, |
456 | unsigned alignment) | 483 | unsigned long size, |
484 | unsigned alignment, | ||
485 | unsigned long color) | ||
457 | { | 486 | { |
487 | mm->scan_color = color; | ||
458 | mm->scan_alignment = alignment; | 488 | mm->scan_alignment = alignment; |
459 | mm->scan_size = size; | 489 | mm->scan_size = size; |
460 | mm->scanned_blocks = 0; | 490 | mm->scanned_blocks = 0; |
@@ -474,11 +504,14 @@ EXPORT_SYMBOL(drm_mm_init_scan); | |||
474 | * Warning: As long as the scan list is non-empty, no other operations than | 504 | * Warning: As long as the scan list is non-empty, no other operations than |
475 | * adding/removing nodes to/from the scan list are allowed. | 505 | * adding/removing nodes to/from the scan list are allowed. |
476 | */ | 506 | */ |
477 | void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, | 507 | void drm_mm_init_scan_with_range(struct drm_mm *mm, |
508 | unsigned long size, | ||
478 | unsigned alignment, | 509 | unsigned alignment, |
510 | unsigned long color, | ||
479 | unsigned long start, | 511 | unsigned long start, |
480 | unsigned long end) | 512 | unsigned long end) |
481 | { | 513 | { |
514 | mm->scan_color = color; | ||
482 | mm->scan_alignment = alignment; | 515 | mm->scan_alignment = alignment; |
483 | mm->scan_size = size; | 516 | mm->scan_size = size; |
484 | mm->scanned_blocks = 0; | 517 | mm->scanned_blocks = 0; |
@@ -522,17 +555,21 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
522 | 555 | ||
523 | hole_start = drm_mm_hole_node_start(prev_node); | 556 | hole_start = drm_mm_hole_node_start(prev_node); |
524 | hole_end = drm_mm_hole_node_end(prev_node); | 557 | hole_end = drm_mm_hole_node_end(prev_node); |
558 | |||
559 | adj_start = hole_start; | ||
560 | adj_end = hole_end; | ||
561 | |||
562 | if (mm->color_adjust) | ||
563 | mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end); | ||
564 | |||
525 | if (mm->scan_check_range) { | 565 | if (mm->scan_check_range) { |
526 | adj_start = hole_start < mm->scan_start ? | 566 | if (adj_start < mm->scan_start) |
527 | mm->scan_start : hole_start; | 567 | adj_start = mm->scan_start; |
528 | adj_end = hole_end > mm->scan_end ? | 568 | if (adj_end > mm->scan_end) |
529 | mm->scan_end : hole_end; | 569 | adj_end = mm->scan_end; |
530 | } else { | ||
531 | adj_start = hole_start; | ||
532 | adj_end = hole_end; | ||
533 | } | 570 | } |
534 | 571 | ||
535 | if (check_free_hole(adj_start , adj_end, | 572 | if (check_free_hole(adj_start, adj_end, |
536 | mm->scan_size, mm->scan_alignment)) { | 573 | mm->scan_size, mm->scan_alignment)) { |
537 | mm->scan_hit_start = hole_start; | 574 | mm->scan_hit_start = hole_start; |
538 | mm->scan_hit_size = hole_end; | 575 | mm->scan_hit_size = hole_end; |
@@ -616,6 +653,8 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) | |||
616 | mm->head_node.size = start - mm->head_node.start; | 653 | mm->head_node.size = start - mm->head_node.start; |
617 | list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); | 654 | list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); |
618 | 655 | ||
656 | mm->color_adjust = NULL; | ||
657 | |||
619 | return 0; | 658 | return 0; |
620 | } | 659 | } |
621 | EXPORT_SYMBOL(drm_mm_init); | 660 | EXPORT_SYMBOL(drm_mm_init); |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 13f3d936472f..5320364582ce 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -465,3 +465,52 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) | |||
465 | DRM_INFO("Module unloaded\n"); | 465 | DRM_INFO("Module unloaded\n"); |
466 | } | 466 | } |
467 | EXPORT_SYMBOL(drm_pci_exit); | 467 | EXPORT_SYMBOL(drm_pci_exit); |
468 | |||
469 | int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask) | ||
470 | { | ||
471 | struct pci_dev *root; | ||
472 | int pos; | ||
473 | u32 lnkcap, lnkcap2; | ||
474 | |||
475 | *mask = 0; | ||
476 | if (!dev->pdev) | ||
477 | return -EINVAL; | ||
478 | |||
479 | if (!pci_is_pcie(dev->pdev)) | ||
480 | return -EINVAL; | ||
481 | |||
482 | root = dev->pdev->bus->self; | ||
483 | |||
484 | pos = pci_pcie_cap(root); | ||
485 | if (!pos) | ||
486 | return -EINVAL; | ||
487 | |||
488 | /* we've been informed via and serverworks don't make the cut */ | ||
489 | if (root->vendor == PCI_VENDOR_ID_VIA || | ||
490 | root->vendor == PCI_VENDOR_ID_SERVERWORKS) | ||
491 | return -EINVAL; | ||
492 | |||
493 | pci_read_config_dword(root, pos + PCI_EXP_LNKCAP, &lnkcap); | ||
494 | pci_read_config_dword(root, pos + PCI_EXP_LNKCAP2, &lnkcap2); | ||
495 | |||
496 | lnkcap &= PCI_EXP_LNKCAP_SLS; | ||
497 | lnkcap2 &= 0xfe; | ||
498 | |||
499 | if (lnkcap2) { /* PCIE GEN 3.0 */ | ||
500 | if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB) | ||
501 | *mask |= DRM_PCIE_SPEED_25; | ||
502 | if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB) | ||
503 | *mask |= DRM_PCIE_SPEED_50; | ||
504 | if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB) | ||
505 | *mask |= DRM_PCIE_SPEED_80; | ||
506 | } else { | ||
507 | if (lnkcap & 1) | ||
508 | *mask |= DRM_PCIE_SPEED_25; | ||
509 | if (lnkcap & 2) | ||
510 | *mask |= DRM_PCIE_SPEED_50; | ||
511 | } | ||
512 | |||
513 | DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", root->vendor, root->device, lnkcap, lnkcap2); | ||
514 | return 0; | ||
515 | } | ||
516 | EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask); | ||
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index fff87221f9e9..371c695322d9 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -53,7 +53,6 @@ static struct drm_info_list drm_proc_list[] = { | |||
53 | {"name", drm_name_info, 0}, | 53 | {"name", drm_name_info, 0}, |
54 | {"vm", drm_vm_info, 0}, | 54 | {"vm", drm_vm_info, 0}, |
55 | {"clients", drm_clients_info, 0}, | 55 | {"clients", drm_clients_info, 0}, |
56 | {"queues", drm_queues_info, 0}, | ||
57 | {"bufs", drm_bufs_info, 0}, | 56 | {"bufs", drm_bufs_info, 0}, |
58 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, | 57 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, |
59 | #if DRM_DEBUG_CODE | 58 | #if DRM_DEBUG_CODE |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 45cf1dd3eb9c..45ac8d6c92b7 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -134,6 +134,7 @@ void drm_sysfs_destroy(void) | |||
134 | return; | 134 | return; |
135 | class_remove_file(drm_class, &class_attr_version.attr); | 135 | class_remove_file(drm_class, &class_attr_version.attr); |
136 | class_destroy(drm_class); | 136 | class_destroy(drm_class); |
137 | drm_class = NULL; | ||
137 | } | 138 | } |
138 | 139 | ||
139 | /** | 140 | /** |
@@ -554,6 +555,9 @@ void drm_sysfs_device_remove(struct drm_minor *minor) | |||
554 | 555 | ||
555 | int drm_class_device_register(struct device *dev) | 556 | int drm_class_device_register(struct device *dev) |
556 | { | 557 | { |
558 | if (!drm_class || IS_ERR(drm_class)) | ||
559 | return -ENOENT; | ||
560 | |||
557 | dev->class = drm_class; | 561 | dev->class = drm_class; |
558 | return device_register(dev); | 562 | return device_register(dev); |
559 | } | 563 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 4afb625128d7..32a34c85899b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -237,7 +237,7 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc) | |||
237 | 237 | ||
238 | static bool | 238 | static bool |
239 | exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc, | 239 | exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc, |
240 | struct drm_display_mode *mode, | 240 | const struct drm_display_mode *mode, |
241 | struct drm_display_mode *adjusted_mode) | 241 | struct drm_display_mode *adjusted_mode) |
242 | { | 242 | { |
243 | DRM_DEBUG_KMS("%s\n", __FILE__); | 243 | DRM_DEBUG_KMS("%s\n", __FILE__); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index c82c90c443e7..277653d5fda0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -174,7 +174,7 @@ struct exynos_drm_manager_ops { | |||
174 | void (*apply)(struct device *subdrv_dev); | 174 | void (*apply)(struct device *subdrv_dev); |
175 | void (*mode_fixup)(struct device *subdrv_dev, | 175 | void (*mode_fixup)(struct device *subdrv_dev, |
176 | struct drm_connector *connector, | 176 | struct drm_connector *connector, |
177 | struct drm_display_mode *mode, | 177 | const struct drm_display_mode *mode, |
178 | struct drm_display_mode *adjusted_mode); | 178 | struct drm_display_mode *adjusted_mode); |
179 | void (*mode_set)(struct device *subdrv_dev, void *mode); | 179 | void (*mode_set)(struct device *subdrv_dev, void *mode); |
180 | void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width, | 180 | void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 23d5ad379f86..4a13a747f5d4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -108,7 +108,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
108 | 108 | ||
109 | static bool | 109 | static bool |
110 | exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, | 110 | exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, |
111 | struct drm_display_mode *mode, | 111 | const struct drm_display_mode *mode, |
112 | struct drm_display_mode *adjusted_mode) | 112 | struct drm_display_mode *adjusted_mode) |
113 | { | 113 | { |
114 | struct drm_device *dev = encoder->dev; | 114 | struct drm_device *dev = encoder->dev; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 5d9d2c2f8f3f..8ffcdf8b9e22 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -142,7 +142,7 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev) | |||
142 | 142 | ||
143 | static void drm_hdmi_mode_fixup(struct device *subdrv_dev, | 143 | static void drm_hdmi_mode_fixup(struct device *subdrv_dev, |
144 | struct drm_connector *connector, | 144 | struct drm_connector *connector, |
145 | struct drm_display_mode *mode, | 145 | const struct drm_display_mode *mode, |
146 | struct drm_display_mode *adjusted_mode) | 146 | struct drm_display_mode *adjusted_mode) |
147 | { | 147 | { |
148 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); | 148 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index bd8126996e52..a91c42088e42 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h | |||
@@ -51,7 +51,7 @@ struct exynos_hdmi_ops { | |||
51 | 51 | ||
52 | /* manager */ | 52 | /* manager */ |
53 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, | 53 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, |
54 | struct drm_display_mode *mode, | 54 | const struct drm_display_mode *mode, |
55 | struct drm_display_mode *adjusted_mode); | 55 | struct drm_display_mode *adjusted_mode); |
56 | void (*mode_set)(void *ctx, void *mode); | 56 | void (*mode_set)(void *ctx, void *mode); |
57 | void (*get_max_resol)(void *ctx, unsigned int *width, | 57 | void (*get_max_resol)(void *ctx, unsigned int *width, |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a137e9e39a33..066bde3f19c4 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -1940,7 +1940,7 @@ static void hdmi_conf_apply(struct hdmi_context *hdata) | |||
1940 | } | 1940 | } |
1941 | 1941 | ||
1942 | static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | 1942 | static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, |
1943 | struct drm_display_mode *mode, | 1943 | const struct drm_display_mode *mode, |
1944 | struct drm_display_mode *adjusted_mode) | 1944 | struct drm_display_mode *adjusted_mode) |
1945 | { | 1945 | { |
1946 | struct drm_display_mode *m; | 1946 | struct drm_display_mode *m; |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c index 187422018601..8c175345d85c 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c | |||
@@ -82,7 +82,7 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector, | |||
82 | } | 82 | } |
83 | 83 | ||
84 | static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder, | 84 | static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder, |
85 | struct drm_display_mode *mode, | 85 | const struct drm_display_mode *mode, |
86 | struct drm_display_mode *adjusted_mode) | 86 | struct drm_display_mode *adjusted_mode) |
87 | { | 87 | { |
88 | return true; | 88 | return true; |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index c3e9a0f701df..a68509ba22a8 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c | |||
@@ -913,7 +913,7 @@ static void cdv_intel_crtc_commit(struct drm_crtc *crtc) | |||
913 | } | 913 | } |
914 | 914 | ||
915 | static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc, | 915 | static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc, |
916 | struct drm_display_mode *mode, | 916 | const struct drm_display_mode *mode, |
917 | struct drm_display_mode *adjusted_mode) | 917 | struct drm_display_mode *adjusted_mode) |
918 | { | 918 | { |
919 | return true; | 919 | return true; |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 88b59d4a7b7f..a86f87b9ddde 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c | |||
@@ -90,7 +90,7 @@ static void cdv_hdmi_mode_set(struct drm_encoder *encoder, | |||
90 | } | 90 | } |
91 | 91 | ||
92 | static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder, | 92 | static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder, |
93 | struct drm_display_mode *mode, | 93 | const struct drm_display_mode *mode, |
94 | struct drm_display_mode *adjusted_mode) | 94 | struct drm_display_mode *adjusted_mode) |
95 | { | 95 | { |
96 | return true; | 96 | return true; |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index ff5b58eb878c..c7f9468b74ba 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c | |||
@@ -270,7 +270,7 @@ static int cdv_intel_lvds_mode_valid(struct drm_connector *connector, | |||
270 | } | 270 | } |
271 | 271 | ||
272 | static bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder, | 272 | static bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder, |
273 | struct drm_display_mode *mode, | 273 | const struct drm_display_mode *mode, |
274 | struct drm_display_mode *adjusted_mode) | 274 | struct drm_display_mode *adjusted_mode) |
275 | { | 275 | { |
276 | struct drm_device *dev = encoder->dev; | 276 | struct drm_device *dev = encoder->dev; |
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index 973d7f6d66b7..8d7caf0f363e 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c | |||
@@ -427,7 +427,7 @@ parse_device_mapping(struct drm_psb_private *dev_priv, | |||
427 | * | 427 | * |
428 | * Returns 0 on success, nonzero on failure. | 428 | * Returns 0 on success, nonzero on failure. |
429 | */ | 429 | */ |
430 | bool psb_intel_init_bios(struct drm_device *dev) | 430 | int psb_intel_init_bios(struct drm_device *dev) |
431 | { | 431 | { |
432 | struct drm_psb_private *dev_priv = dev->dev_private; | 432 | struct drm_psb_private *dev_priv = dev->dev_private; |
433 | struct pci_dev *pdev = dev->pdev; | 433 | struct pci_dev *pdev = dev->pdev; |
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h index 0a738663eb5a..2e95523b84b1 100644 --- a/drivers/gpu/drm/gma500/intel_bios.h +++ b/drivers/gpu/drm/gma500/intel_bios.h | |||
@@ -431,7 +431,7 @@ struct bdb_driver_features { | |||
431 | u8 custom_vbt_version; | 431 | u8 custom_vbt_version; |
432 | } __attribute__((packed)); | 432 | } __attribute__((packed)); |
433 | 433 | ||
434 | extern bool psb_intel_init_bios(struct drm_device *dev); | 434 | extern int psb_intel_init_bios(struct drm_device *dev); |
435 | extern void psb_intel_destroy_bios(struct drm_device *dev); | 435 | extern void psb_intel_destroy_bios(struct drm_device *dev); |
436 | 436 | ||
437 | /* | 437 | /* |
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c index b34ff097b979..d4813e03f5ee 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c | |||
@@ -684,7 +684,7 @@ void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) | |||
684 | } | 684 | } |
685 | 685 | ||
686 | bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, | 686 | bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, |
687 | struct drm_display_mode *mode, | 687 | const struct drm_display_mode *mode, |
688 | struct drm_display_mode *adjusted_mode) | 688 | struct drm_display_mode *adjusted_mode) |
689 | { | 689 | { |
690 | struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); | 690 | struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); |
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h index 6f762478b959..2b40663e1696 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h +++ b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h | |||
@@ -65,7 +65,7 @@ extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, | |||
65 | /* MDFLD DPI helper functions */ | 65 | /* MDFLD DPI helper functions */ |
66 | extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode); | 66 | extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode); |
67 | extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, | 67 | extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, |
68 | struct drm_display_mode *mode, | 68 | const struct drm_display_mode *mode, |
69 | struct drm_display_mode *adjusted_mode); | 69 | struct drm_display_mode *adjusted_mode); |
70 | extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder); | 70 | extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder); |
71 | extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder); | 71 | extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 3f3cd619c79f..dec6a9aea3c6 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c | |||
@@ -117,7 +117,7 @@ static void psb_intel_crtc_commit(struct drm_crtc *crtc) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, | 119 | static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, |
120 | struct drm_display_mode *mode, | 120 | const struct drm_display_mode *mode, |
121 | struct drm_display_mode *adjusted_mode) | 121 | struct drm_display_mode *adjusted_mode) |
122 | { | 122 | { |
123 | return true; | 123 | return true; |
diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index f821c835ca90..cdafd2acc72f 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c | |||
@@ -487,7 +487,7 @@ oaktrail_crtc_mode_set_exit: | |||
487 | } | 487 | } |
488 | 488 | ||
489 | static bool oaktrail_crtc_mode_fixup(struct drm_crtc *crtc, | 489 | static bool oaktrail_crtc_mode_fixup(struct drm_crtc *crtc, |
490 | struct drm_display_mode *mode, | 490 | const struct drm_display_mode *mode, |
491 | struct drm_display_mode *adjusted_mode) | 491 | struct drm_display_mode *adjusted_mode) |
492 | { | 492 | { |
493 | return true; | 493 | return true; |
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index c10899c953b9..2eb3dc4e9c9b 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c | |||
@@ -191,7 +191,7 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, | |||
191 | } | 191 | } |
192 | 192 | ||
193 | static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder, | 193 | static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder, |
194 | struct drm_display_mode *mode, | 194 | const struct drm_display_mode *mode, |
195 | struct drm_display_mode *adjusted_mode) | 195 | struct drm_display_mode *adjusted_mode) |
196 | { | 196 | { |
197 | return true; | 197 | return true; |
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index a8858a907f47..0c4737438530 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c | |||
@@ -633,7 +633,6 @@ static struct drm_driver driver = { | |||
633 | .open = psb_driver_open, | 633 | .open = psb_driver_open, |
634 | .preclose = psb_driver_preclose, | 634 | .preclose = psb_driver_preclose, |
635 | .postclose = psb_driver_close, | 635 | .postclose = psb_driver_close, |
636 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
637 | 636 | ||
638 | .gem_init_object = psb_gem_init_object, | 637 | .gem_init_object = psb_gem_init_object, |
639 | .gem_free_object = psb_gem_free_object, | 638 | .gem_free_object = psb_gem_free_object, |
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 36c3c99612f6..30dc22a7156c 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c | |||
@@ -543,7 +543,7 @@ void psb_intel_encoder_destroy(struct drm_encoder *encoder) | |||
543 | } | 543 | } |
544 | 544 | ||
545 | static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, | 545 | static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, |
546 | struct drm_display_mode *mode, | 546 | const struct drm_display_mode *mode, |
547 | struct drm_display_mode *adjusted_mode) | 547 | struct drm_display_mode *adjusted_mode) |
548 | { | 548 | { |
549 | return true; | 549 | return true; |
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index 2515f83248cb..ebe1a28f60e1 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h | |||
@@ -268,7 +268,7 @@ extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device | |||
268 | *mode_cmd, | 268 | *mode_cmd, |
269 | void *mm_private); | 269 | void *mm_private); |
270 | extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, | 270 | extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, |
271 | struct drm_display_mode *mode, | 271 | const struct drm_display_mode *mode, |
272 | struct drm_display_mode *adjusted_mode); | 272 | struct drm_display_mode *adjusted_mode); |
273 | extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, | 273 | extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, |
274 | struct drm_display_mode *mode); | 274 | struct drm_display_mode *mode); |
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index c83f5b5d1057..37adc9edf974 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c | |||
@@ -375,7 +375,7 @@ int psb_intel_lvds_mode_valid(struct drm_connector *connector, | |||
375 | } | 375 | } |
376 | 376 | ||
377 | bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, | 377 | bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, |
378 | struct drm_display_mode *mode, | 378 | const struct drm_display_mode *mode, |
379 | struct drm_display_mode *adjusted_mode) | 379 | struct drm_display_mode *adjusted_mode) |
380 | { | 380 | { |
381 | struct drm_device *dev = encoder->dev; | 381 | struct drm_device *dev = encoder->dev; |
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index d39b15be7649..0466c7b985f8 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c | |||
@@ -901,7 +901,7 @@ static bool psb_intel_sdvo_set_tv_format(struct psb_intel_sdvo *psb_intel_sdvo) | |||
901 | 901 | ||
902 | static bool | 902 | static bool |
903 | psb_intel_sdvo_set_output_timings_from_mode(struct psb_intel_sdvo *psb_intel_sdvo, | 903 | psb_intel_sdvo_set_output_timings_from_mode(struct psb_intel_sdvo *psb_intel_sdvo, |
904 | struct drm_display_mode *mode) | 904 | const struct drm_display_mode *mode) |
905 | { | 905 | { |
906 | struct psb_intel_sdvo_dtd output_dtd; | 906 | struct psb_intel_sdvo_dtd output_dtd; |
907 | 907 | ||
@@ -918,7 +918,7 @@ psb_intel_sdvo_set_output_timings_from_mode(struct psb_intel_sdvo *psb_intel_sdv | |||
918 | 918 | ||
919 | static bool | 919 | static bool |
920 | psb_intel_sdvo_set_input_timings_for_mode(struct psb_intel_sdvo *psb_intel_sdvo, | 920 | psb_intel_sdvo_set_input_timings_for_mode(struct psb_intel_sdvo *psb_intel_sdvo, |
921 | struct drm_display_mode *mode, | 921 | const struct drm_display_mode *mode, |
922 | struct drm_display_mode *adjusted_mode) | 922 | struct drm_display_mode *adjusted_mode) |
923 | { | 923 | { |
924 | /* Reset the input timing to the screen. Assume always input 0. */ | 924 | /* Reset the input timing to the screen. Assume always input 0. */ |
@@ -942,7 +942,7 @@ psb_intel_sdvo_set_input_timings_for_mode(struct psb_intel_sdvo *psb_intel_sdvo, | |||
942 | } | 942 | } |
943 | 943 | ||
944 | static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 944 | static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
945 | struct drm_display_mode *mode, | 945 | const struct drm_display_mode *mode, |
946 | struct drm_display_mode *adjusted_mode) | 946 | struct drm_display_mode *adjusted_mode) |
947 | { | 947 | { |
948 | struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); | 948 | struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); |
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index d3f2e8785010..36d952280c50 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c | |||
@@ -88,7 +88,7 @@ static void ch7006_encoder_restore(struct drm_encoder *encoder) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | static bool ch7006_encoder_mode_fixup(struct drm_encoder *encoder, | 90 | static bool ch7006_encoder_mode_fixup(struct drm_encoder *encoder, |
91 | struct drm_display_mode *mode, | 91 | const struct drm_display_mode *mode, |
92 | struct drm_display_mode *adjusted_mode) | 92 | struct drm_display_mode *adjusted_mode) |
93 | { | 93 | { |
94 | struct ch7006_priv *priv = to_ch7006_priv(encoder); | 94 | struct ch7006_priv *priv = to_ch7006_priv(encoder); |
diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c index c860f24a5afc..9b83574141a6 100644 --- a/drivers/gpu/drm/i2c/ch7006_mode.c +++ b/drivers/gpu/drm/i2c/ch7006_mode.c | |||
@@ -172,7 +172,7 @@ struct ch7006_mode ch7006_modes[] = { | |||
172 | }; | 172 | }; |
173 | 173 | ||
174 | struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, | 174 | struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, |
175 | struct drm_display_mode *drm_mode) | 175 | const struct drm_display_mode *drm_mode) |
176 | { | 176 | { |
177 | struct ch7006_priv *priv = to_ch7006_priv(encoder); | 177 | struct ch7006_priv *priv = to_ch7006_priv(encoder); |
178 | struct ch7006_mode *mode; | 178 | struct ch7006_mode *mode; |
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h index 17667b7d57e7..09599f4c0c9a 100644 --- a/drivers/gpu/drm/i2c/ch7006_priv.h +++ b/drivers/gpu/drm/i2c/ch7006_priv.h | |||
@@ -111,7 +111,7 @@ extern struct ch7006_tv_norm_info ch7006_tv_norms[]; | |||
111 | extern struct ch7006_mode ch7006_modes[]; | 111 | extern struct ch7006_mode ch7006_modes[]; |
112 | 112 | ||
113 | struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, | 113 | struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, |
114 | struct drm_display_mode *drm_mode); | 114 | const struct drm_display_mode *drm_mode); |
115 | 115 | ||
116 | void ch7006_setup_levels(struct drm_encoder *encoder); | 116 | void ch7006_setup_levels(struct drm_encoder *encoder); |
117 | void ch7006_setup_subcarrier(struct drm_encoder *encoder); | 117 | void ch7006_setup_subcarrier(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c index b7d45ab4ba69..30b8ae5e5c4a 100644 --- a/drivers/gpu/drm/i2c/sil164_drv.c +++ b/drivers/gpu/drm/i2c/sil164_drv.c | |||
@@ -254,7 +254,7 @@ sil164_encoder_restore(struct drm_encoder *encoder) | |||
254 | 254 | ||
255 | static bool | 255 | static bool |
256 | sil164_encoder_mode_fixup(struct drm_encoder *encoder, | 256 | sil164_encoder_mode_fixup(struct drm_encoder *encoder, |
257 | struct drm_display_mode *mode, | 257 | const struct drm_display_mode *mode, |
258 | struct drm_display_mode *adjusted_mode) | 258 | struct drm_display_mode *adjusted_mode) |
259 | { | 259 | { |
260 | return true; | 260 | return true; |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index fa9439159ebd..57d892eaaa6e 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -881,7 +881,7 @@ static int i810_flush_queue(struct drm_device *dev) | |||
881 | } | 881 | } |
882 | 882 | ||
883 | /* Must be called with the lock held */ | 883 | /* Must be called with the lock held */ |
884 | static void i810_reclaim_buffers(struct drm_device *dev, | 884 | void i810_driver_reclaim_buffers(struct drm_device *dev, |
885 | struct drm_file *file_priv) | 885 | struct drm_file *file_priv) |
886 | { | 886 | { |
887 | struct drm_device_dma *dma = dev->dma; | 887 | struct drm_device_dma *dma = dev->dma; |
@@ -1220,12 +1220,17 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
1220 | if (dev_priv->page_flipping) | 1220 | if (dev_priv->page_flipping) |
1221 | i810_do_cleanup_pageflip(dev); | 1221 | i810_do_cleanup_pageflip(dev); |
1222 | } | 1222 | } |
1223 | } | ||
1224 | 1223 | ||
1225 | void i810_driver_reclaim_buffers_locked(struct drm_device *dev, | 1224 | if (file_priv->master && file_priv->master->lock.hw_lock) { |
1226 | struct drm_file *file_priv) | 1225 | drm_idlelock_take(&file_priv->master->lock); |
1227 | { | 1226 | i810_driver_reclaim_buffers(dev, file_priv); |
1228 | i810_reclaim_buffers(dev, file_priv); | 1227 | drm_idlelock_release(&file_priv->master->lock); |
1228 | } else { | ||
1229 | /* master disappeared, clean up stuff anyway and hope nothing | ||
1230 | * goes wrong */ | ||
1231 | i810_driver_reclaim_buffers(dev, file_priv); | ||
1232 | } | ||
1233 | |||
1229 | } | 1234 | } |
1230 | 1235 | ||
1231 | int i810_driver_dma_quiescent(struct drm_device *dev) | 1236 | int i810_driver_dma_quiescent(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index ec12f7dc717a..f9924ad04d09 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -57,13 +57,12 @@ static const struct file_operations i810_driver_fops = { | |||
57 | static struct drm_driver driver = { | 57 | static struct drm_driver driver = { |
58 | .driver_features = | 58 | .driver_features = |
59 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | | 59 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | |
60 | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, | 60 | DRIVER_HAVE_DMA, |
61 | .dev_priv_size = sizeof(drm_i810_buf_priv_t), | 61 | .dev_priv_size = sizeof(drm_i810_buf_priv_t), |
62 | .load = i810_driver_load, | 62 | .load = i810_driver_load, |
63 | .lastclose = i810_driver_lastclose, | 63 | .lastclose = i810_driver_lastclose, |
64 | .preclose = i810_driver_preclose, | 64 | .preclose = i810_driver_preclose, |
65 | .device_is_agp = i810_driver_device_is_agp, | 65 | .device_is_agp = i810_driver_device_is_agp, |
66 | .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, | ||
67 | .dma_quiescent = i810_driver_dma_quiescent, | 66 | .dma_quiescent = i810_driver_dma_quiescent, |
68 | .ioctls = i810_ioctls, | 67 | .ioctls = i810_ioctls, |
69 | .fops = &i810_driver_fops, | 68 | .fops = &i810_driver_fops, |
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h index c9339f481795..6e0acad9e0f5 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h | |||
@@ -116,14 +116,12 @@ typedef struct drm_i810_private { | |||
116 | 116 | ||
117 | /* i810_dma.c */ | 117 | /* i810_dma.c */ |
118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); | 118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); |
119 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, | 119 | void i810_driver_reclaim_buffers(struct drm_device *dev, |
120 | struct drm_file *file_priv); | 120 | struct drm_file *file_priv); |
121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); | 121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); |
122 | extern void i810_driver_lastclose(struct drm_device *dev); | 122 | extern void i810_driver_lastclose(struct drm_device *dev); |
123 | extern void i810_driver_preclose(struct drm_device *dev, | 123 | extern void i810_driver_preclose(struct drm_device *dev, |
124 | struct drm_file *file_priv); | 124 | struct drm_file *file_priv); |
125 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, | ||
126 | struct drm_file *file_priv); | ||
127 | extern int i810_driver_device_is_agp(struct drm_device *dev); | 125 | extern int i810_driver_device_is_agp(struct drm_device *dev); |
128 | 126 | ||
129 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 127 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 2e9268da58d8..b0bacdba6d7e 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -7,6 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ | |||
7 | i915_debugfs.o \ | 7 | i915_debugfs.o \ |
8 | i915_suspend.o \ | 8 | i915_suspend.o \ |
9 | i915_gem.o \ | 9 | i915_gem.o \ |
10 | i915_gem_context.o \ | ||
10 | i915_gem_debug.o \ | 11 | i915_gem_debug.o \ |
11 | i915_gem_evict.o \ | 12 | i915_gem_evict.o \ |
12 | i915_gem_execbuffer.o \ | 13 | i915_gem_execbuffer.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 8c2ad014c47f..58914691a77b 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -86,7 +86,7 @@ struct intel_dvo_dev_ops { | |||
86 | * buses with clock limitations. | 86 | * buses with clock limitations. |
87 | */ | 87 | */ |
88 | bool (*mode_fixup)(struct intel_dvo_device *dvo, | 88 | bool (*mode_fixup)(struct intel_dvo_device *dvo, |
89 | struct drm_display_mode *mode, | 89 | const struct drm_display_mode *mode, |
90 | struct drm_display_mode *adjusted_mode); | 90 | struct drm_display_mode *adjusted_mode); |
91 | 91 | ||
92 | /* | 92 | /* |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5363e9c66c27..359f6e8b9b00 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -676,6 +676,7 @@ static void i915_ring_error_state(struct seq_file *m, | |||
676 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); | 676 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); |
677 | seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); | 677 | seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); |
678 | if (INTEL_INFO(dev)->gen >= 6) { | 678 | if (INTEL_INFO(dev)->gen >= 6) { |
679 | seq_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); | ||
679 | seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); | 680 | seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); |
680 | seq_printf(m, " SYNC_0: 0x%08x\n", | 681 | seq_printf(m, " SYNC_0: 0x%08x\n", |
681 | error->semaphore_mboxes[ring][0]); | 682 | error->semaphore_mboxes[ring][0]); |
@@ -713,6 +714,7 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
713 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | 714 | seq_printf(m, "EIR: 0x%08x\n", error->eir); |
714 | seq_printf(m, "IER: 0x%08x\n", error->ier); | 715 | seq_printf(m, "IER: 0x%08x\n", error->ier); |
715 | seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); | 716 | seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
717 | seq_printf(m, "CCID: 0x%08x\n", error->ccid); | ||
716 | 718 | ||
717 | for (i = 0; i < dev_priv->num_fence_regs; i++) | 719 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
718 | seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); | 720 | seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); |
@@ -1765,6 +1767,64 @@ static const struct file_operations i915_max_freq_fops = { | |||
1765 | }; | 1767 | }; |
1766 | 1768 | ||
1767 | static ssize_t | 1769 | static ssize_t |
1770 | i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max, | ||
1771 | loff_t *ppos) | ||
1772 | { | ||
1773 | struct drm_device *dev = filp->private_data; | ||
1774 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1775 | char buf[80]; | ||
1776 | int len; | ||
1777 | |||
1778 | len = snprintf(buf, sizeof(buf), | ||
1779 | "min freq: %d\n", dev_priv->min_delay * 50); | ||
1780 | |||
1781 | if (len > sizeof(buf)) | ||
1782 | len = sizeof(buf); | ||
1783 | |||
1784 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); | ||
1785 | } | ||
1786 | |||
1787 | static ssize_t | ||
1788 | i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt, | ||
1789 | loff_t *ppos) | ||
1790 | { | ||
1791 | struct drm_device *dev = filp->private_data; | ||
1792 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1793 | char buf[20]; | ||
1794 | int val = 1; | ||
1795 | |||
1796 | if (cnt > 0) { | ||
1797 | if (cnt > sizeof(buf) - 1) | ||
1798 | return -EINVAL; | ||
1799 | |||
1800 | if (copy_from_user(buf, ubuf, cnt)) | ||
1801 | return -EFAULT; | ||
1802 | buf[cnt] = 0; | ||
1803 | |||
1804 | val = simple_strtoul(buf, NULL, 0); | ||
1805 | } | ||
1806 | |||
1807 | DRM_DEBUG_DRIVER("Manually setting min freq to %d\n", val); | ||
1808 | |||
1809 | /* | ||
1810 | * Turbo will still be enabled, but won't go below the set value. | ||
1811 | */ | ||
1812 | dev_priv->min_delay = val / 50; | ||
1813 | |||
1814 | gen6_set_rps(dev, val / 50); | ||
1815 | |||
1816 | return cnt; | ||
1817 | } | ||
1818 | |||
1819 | static const struct file_operations i915_min_freq_fops = { | ||
1820 | .owner = THIS_MODULE, | ||
1821 | .open = simple_open, | ||
1822 | .read = i915_min_freq_read, | ||
1823 | .write = i915_min_freq_write, | ||
1824 | .llseek = default_llseek, | ||
1825 | }; | ||
1826 | |||
1827 | static ssize_t | ||
1768 | i915_cache_sharing_read(struct file *filp, | 1828 | i915_cache_sharing_read(struct file *filp, |
1769 | char __user *ubuf, | 1829 | char __user *ubuf, |
1770 | size_t max, | 1830 | size_t max, |
@@ -1997,6 +2057,12 @@ int i915_debugfs_init(struct drm_minor *minor) | |||
1997 | return ret; | 2057 | return ret; |
1998 | 2058 | ||
1999 | ret = i915_debugfs_create(minor->debugfs_root, minor, | 2059 | ret = i915_debugfs_create(minor->debugfs_root, minor, |
2060 | "i915_min_freq", | ||
2061 | &i915_min_freq_fops); | ||
2062 | if (ret) | ||
2063 | return ret; | ||
2064 | |||
2065 | ret = i915_debugfs_create(minor->debugfs_root, minor, | ||
2000 | "i915_cache_sharing", | 2066 | "i915_cache_sharing", |
2001 | &i915_cache_sharing_fops); | 2067 | &i915_cache_sharing_fops); |
2002 | if (ret) | 2068 | if (ret) |
@@ -2028,6 +2094,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) | |||
2028 | 1, minor); | 2094 | 1, minor); |
2029 | drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, | 2095 | drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, |
2030 | 1, minor); | 2096 | 1, minor); |
2097 | drm_debugfs_remove_files((struct drm_info_list *) &i915_min_freq_fops, | ||
2098 | 1, minor); | ||
2031 | drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, | 2099 | drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, |
2032 | 1, minor); | 2100 | 1, minor); |
2033 | drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops, | 2101 | drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 36822b924eb1..9cf7dfe022b9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1006,6 +1006,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
1006 | case I915_PARAM_HAS_ALIASING_PPGTT: | 1006 | case I915_PARAM_HAS_ALIASING_PPGTT: |
1007 | value = dev_priv->mm.aliasing_ppgtt ? 1 : 0; | 1007 | value = dev_priv->mm.aliasing_ppgtt ? 1 : 0; |
1008 | break; | 1008 | break; |
1009 | case I915_PARAM_HAS_WAIT_TIMEOUT: | ||
1010 | value = 1; | ||
1011 | break; | ||
1009 | default: | 1012 | default: |
1010 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 1013 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
1011 | param->param); | 1014 | param->param); |
@@ -1082,8 +1085,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
1082 | 1085 | ||
1083 | ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); | 1086 | ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); |
1084 | 1087 | ||
1085 | dev_priv->dri1.gfx_hws_cpu_addr = ioremap_wc(dev->agp->base + hws->addr, | 1088 | dev_priv->dri1.gfx_hws_cpu_addr = |
1086 | 4096); | 1089 | ioremap_wc(dev_priv->mm.gtt_base_addr + hws->addr, 4096); |
1087 | if (dev_priv->dri1.gfx_hws_cpu_addr == NULL) { | 1090 | if (dev_priv->dri1.gfx_hws_cpu_addr == NULL) { |
1088 | i915_dma_cleanup(dev); | 1091 | i915_dma_cleanup(dev); |
1089 | ring->status_page.gfx_addr = 0; | 1092 | ring->status_page.gfx_addr = 0; |
@@ -1411,7 +1414,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) | |||
1411 | if (!ap) | 1414 | if (!ap) |
1412 | return; | 1415 | return; |
1413 | 1416 | ||
1414 | ap->ranges[0].base = dev_priv->dev->agp->base; | 1417 | ap->ranges[0].base = dev_priv->mm.gtt->gma_bus_addr; |
1415 | ap->ranges[0].size = | 1418 | ap->ranges[0].size = |
1416 | dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | 1419 | dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
1417 | primary = | 1420 | primary = |
@@ -1467,11 +1470,18 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1467 | goto free_priv; | 1470 | goto free_priv; |
1468 | } | 1471 | } |
1469 | 1472 | ||
1473 | ret = intel_gmch_probe(dev_priv->bridge_dev, dev->pdev, NULL); | ||
1474 | if (!ret) { | ||
1475 | DRM_ERROR("failed to set up gmch\n"); | ||
1476 | ret = -EIO; | ||
1477 | goto put_bridge; | ||
1478 | } | ||
1479 | |||
1470 | dev_priv->mm.gtt = intel_gtt_get(); | 1480 | dev_priv->mm.gtt = intel_gtt_get(); |
1471 | if (!dev_priv->mm.gtt) { | 1481 | if (!dev_priv->mm.gtt) { |
1472 | DRM_ERROR("Failed to initialize GTT\n"); | 1482 | DRM_ERROR("Failed to initialize GTT\n"); |
1473 | ret = -ENODEV; | 1483 | ret = -ENODEV; |
1474 | goto put_bridge; | 1484 | goto put_gmch; |
1475 | } | 1485 | } |
1476 | 1486 | ||
1477 | i915_kick_out_firmware_fb(dev_priv); | 1487 | i915_kick_out_firmware_fb(dev_priv); |
@@ -1498,19 +1508,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1498 | if (!dev_priv->regs) { | 1508 | if (!dev_priv->regs) { |
1499 | DRM_ERROR("failed to map registers\n"); | 1509 | DRM_ERROR("failed to map registers\n"); |
1500 | ret = -EIO; | 1510 | ret = -EIO; |
1501 | goto put_bridge; | 1511 | goto put_gmch; |
1502 | } | 1512 | } |
1503 | 1513 | ||
1504 | aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | 1514 | aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
1515 | dev_priv->mm.gtt_base_addr = dev_priv->mm.gtt->gma_bus_addr; | ||
1505 | 1516 | ||
1506 | dev_priv->mm.gtt_mapping = | 1517 | dev_priv->mm.gtt_mapping = |
1507 | io_mapping_create_wc(dev->agp->base, aperture_size); | 1518 | io_mapping_create_wc(dev_priv->mm.gtt_base_addr, |
1519 | aperture_size); | ||
1508 | if (dev_priv->mm.gtt_mapping == NULL) { | 1520 | if (dev_priv->mm.gtt_mapping == NULL) { |
1509 | ret = -EIO; | 1521 | ret = -EIO; |
1510 | goto out_rmmap; | 1522 | goto out_rmmap; |
1511 | } | 1523 | } |
1512 | 1524 | ||
1513 | i915_mtrr_setup(dev_priv, dev->agp->base, aperture_size); | 1525 | i915_mtrr_setup(dev_priv, dev_priv->mm.gtt_base_addr, |
1526 | aperture_size); | ||
1514 | 1527 | ||
1515 | /* The i915 workqueue is primarily used for batched retirement of | 1528 | /* The i915 workqueue is primarily used for batched retirement of |
1516 | * requests (and thus managing bo) once the task has been completed | 1529 | * requests (and thus managing bo) once the task has been completed |
@@ -1534,7 +1547,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1534 | goto out_mtrrfree; | 1547 | goto out_mtrrfree; |
1535 | } | 1548 | } |
1536 | 1549 | ||
1550 | /* This must be called before any calls to HAS_PCH_* */ | ||
1551 | intel_detect_pch(dev); | ||
1552 | |||
1537 | intel_irq_init(dev); | 1553 | intel_irq_init(dev); |
1554 | intel_gt_init(dev); | ||
1538 | 1555 | ||
1539 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1556 | /* Try to make sure MCHBAR is enabled before poking at it */ |
1540 | intel_setup_mchbar(dev); | 1557 | intel_setup_mchbar(dev); |
@@ -1567,7 +1584,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1567 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 1584 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
1568 | pci_enable_msi(dev->pdev); | 1585 | pci_enable_msi(dev->pdev); |
1569 | 1586 | ||
1570 | spin_lock_init(&dev_priv->gt_lock); | ||
1571 | spin_lock_init(&dev_priv->irq_lock); | 1587 | spin_lock_init(&dev_priv->irq_lock); |
1572 | spin_lock_init(&dev_priv->error_lock); | 1588 | spin_lock_init(&dev_priv->error_lock); |
1573 | spin_lock_init(&dev_priv->rps_lock); | 1589 | spin_lock_init(&dev_priv->rps_lock); |
@@ -1586,8 +1602,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1586 | /* Start out suspended */ | 1602 | /* Start out suspended */ |
1587 | dev_priv->mm.suspended = 1; | 1603 | dev_priv->mm.suspended = 1; |
1588 | 1604 | ||
1589 | intel_detect_pch(dev); | ||
1590 | |||
1591 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1605 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1592 | ret = i915_load_modeset_init(dev); | 1606 | ret = i915_load_modeset_init(dev); |
1593 | if (ret < 0) { | 1607 | if (ret < 0) { |
@@ -1622,13 +1636,16 @@ out_gem_unload: | |||
1622 | destroy_workqueue(dev_priv->wq); | 1636 | destroy_workqueue(dev_priv->wq); |
1623 | out_mtrrfree: | 1637 | out_mtrrfree: |
1624 | if (dev_priv->mm.gtt_mtrr >= 0) { | 1638 | if (dev_priv->mm.gtt_mtrr >= 0) { |
1625 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, | 1639 | mtrr_del(dev_priv->mm.gtt_mtrr, |
1626 | dev->agp->agp_info.aper_size * 1024 * 1024); | 1640 | dev_priv->mm.gtt_base_addr, |
1641 | aperture_size); | ||
1627 | dev_priv->mm.gtt_mtrr = -1; | 1642 | dev_priv->mm.gtt_mtrr = -1; |
1628 | } | 1643 | } |
1629 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1644 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1630 | out_rmmap: | 1645 | out_rmmap: |
1631 | pci_iounmap(dev->pdev, dev_priv->regs); | 1646 | pci_iounmap(dev->pdev, dev_priv->regs); |
1647 | put_gmch: | ||
1648 | intel_gmch_remove(); | ||
1632 | put_bridge: | 1649 | put_bridge: |
1633 | pci_dev_put(dev_priv->bridge_dev); | 1650 | pci_dev_put(dev_priv->bridge_dev); |
1634 | free_priv: | 1651 | free_priv: |
@@ -1660,8 +1677,9 @@ int i915_driver_unload(struct drm_device *dev) | |||
1660 | 1677 | ||
1661 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1678 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1662 | if (dev_priv->mm.gtt_mtrr >= 0) { | 1679 | if (dev_priv->mm.gtt_mtrr >= 0) { |
1663 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, | 1680 | mtrr_del(dev_priv->mm.gtt_mtrr, |
1664 | dev->agp->agp_info.aper_size * 1024 * 1024); | 1681 | dev_priv->mm.gtt_base_addr, |
1682 | dev_priv->mm.gtt->gtt_mappable_entries * PAGE_SIZE); | ||
1665 | dev_priv->mm.gtt_mtrr = -1; | 1683 | dev_priv->mm.gtt_mtrr = -1; |
1666 | } | 1684 | } |
1667 | 1685 | ||
@@ -1702,6 +1720,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
1702 | mutex_lock(&dev->struct_mutex); | 1720 | mutex_lock(&dev->struct_mutex); |
1703 | i915_gem_free_all_phys_object(dev); | 1721 | i915_gem_free_all_phys_object(dev); |
1704 | i915_gem_cleanup_ringbuffer(dev); | 1722 | i915_gem_cleanup_ringbuffer(dev); |
1723 | i915_gem_context_fini(dev); | ||
1705 | mutex_unlock(&dev->struct_mutex); | 1724 | mutex_unlock(&dev->struct_mutex); |
1706 | i915_gem_cleanup_aliasing_ppgtt(dev); | 1725 | i915_gem_cleanup_aliasing_ppgtt(dev); |
1707 | i915_gem_cleanup_stolen(dev); | 1726 | i915_gem_cleanup_stolen(dev); |
@@ -1741,6 +1760,8 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file) | |||
1741 | spin_lock_init(&file_priv->mm.lock); | 1760 | spin_lock_init(&file_priv->mm.lock); |
1742 | INIT_LIST_HEAD(&file_priv->mm.request_list); | 1761 | INIT_LIST_HEAD(&file_priv->mm.request_list); |
1743 | 1762 | ||
1763 | idr_init(&file_priv->context_idr); | ||
1764 | |||
1744 | return 0; | 1765 | return 0; |
1745 | } | 1766 | } |
1746 | 1767 | ||
@@ -1760,7 +1781,13 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
1760 | { | 1781 | { |
1761 | drm_i915_private_t *dev_priv = dev->dev_private; | 1782 | drm_i915_private_t *dev_priv = dev->dev_private; |
1762 | 1783 | ||
1763 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { | 1784 | /* On gen6+ we refuse to init without kms enabled, but then the drm core |
1785 | * goes right around and calls lastclose. Check for this and don't clean | ||
1786 | * up anything. */ | ||
1787 | if (!dev_priv) | ||
1788 | return; | ||
1789 | |||
1790 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
1764 | intel_fb_restore_mode(dev); | 1791 | intel_fb_restore_mode(dev); |
1765 | vga_switcheroo_process_delayed_switch(); | 1792 | vga_switcheroo_process_delayed_switch(); |
1766 | return; | 1793 | return; |
@@ -1773,6 +1800,7 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
1773 | 1800 | ||
1774 | void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | 1801 | void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) |
1775 | { | 1802 | { |
1803 | i915_gem_context_close(dev, file_priv); | ||
1776 | i915_gem_release(dev, file_priv); | 1804 | i915_gem_release(dev, file_priv); |
1777 | } | 1805 | } |
1778 | 1806 | ||
@@ -1826,6 +1854,9 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
1826 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 1854 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
1827 | DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 1855 | DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
1828 | DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 1856 | DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
1857 | DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_UNLOCKED), | ||
1858 | DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_UNLOCKED), | ||
1859 | DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_UNLOCKED), | ||
1829 | }; | 1860 | }; |
1830 | 1861 | ||
1831 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 1862 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9fe9ebe52a7a..ed22612bc847 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "drm.h" | 32 | #include "drm.h" |
33 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
34 | #include "i915_drv.h" | 34 | #include "i915_drv.h" |
35 | #include "i915_trace.h" | ||
35 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
36 | 37 | ||
37 | #include <linux/console.h> | 38 | #include <linux/console.h> |
@@ -215,7 +216,6 @@ static const struct intel_device_info intel_ironlake_d_info = { | |||
215 | .gen = 5, | 216 | .gen = 5, |
216 | .need_gfx_hws = 1, .has_hotplug = 1, | 217 | .need_gfx_hws = 1, .has_hotplug = 1, |
217 | .has_bsd_ring = 1, | 218 | .has_bsd_ring = 1, |
218 | .has_pch_split = 1, | ||
219 | }; | 219 | }; |
220 | 220 | ||
221 | static const struct intel_device_info intel_ironlake_m_info = { | 221 | static const struct intel_device_info intel_ironlake_m_info = { |
@@ -223,7 +223,6 @@ static const struct intel_device_info intel_ironlake_m_info = { | |||
223 | .need_gfx_hws = 1, .has_hotplug = 1, | 223 | .need_gfx_hws = 1, .has_hotplug = 1, |
224 | .has_fbc = 1, | 224 | .has_fbc = 1, |
225 | .has_bsd_ring = 1, | 225 | .has_bsd_ring = 1, |
226 | .has_pch_split = 1, | ||
227 | }; | 226 | }; |
228 | 227 | ||
229 | static const struct intel_device_info intel_sandybridge_d_info = { | 228 | static const struct intel_device_info intel_sandybridge_d_info = { |
@@ -232,7 +231,6 @@ static const struct intel_device_info intel_sandybridge_d_info = { | |||
232 | .has_bsd_ring = 1, | 231 | .has_bsd_ring = 1, |
233 | .has_blt_ring = 1, | 232 | .has_blt_ring = 1, |
234 | .has_llc = 1, | 233 | .has_llc = 1, |
235 | .has_pch_split = 1, | ||
236 | .has_force_wake = 1, | 234 | .has_force_wake = 1, |
237 | }; | 235 | }; |
238 | 236 | ||
@@ -243,7 +241,6 @@ static const struct intel_device_info intel_sandybridge_m_info = { | |||
243 | .has_bsd_ring = 1, | 241 | .has_bsd_ring = 1, |
244 | .has_blt_ring = 1, | 242 | .has_blt_ring = 1, |
245 | .has_llc = 1, | 243 | .has_llc = 1, |
246 | .has_pch_split = 1, | ||
247 | .has_force_wake = 1, | 244 | .has_force_wake = 1, |
248 | }; | 245 | }; |
249 | 246 | ||
@@ -253,7 +250,6 @@ static const struct intel_device_info intel_ivybridge_d_info = { | |||
253 | .has_bsd_ring = 1, | 250 | .has_bsd_ring = 1, |
254 | .has_blt_ring = 1, | 251 | .has_blt_ring = 1, |
255 | .has_llc = 1, | 252 | .has_llc = 1, |
256 | .has_pch_split = 1, | ||
257 | .has_force_wake = 1, | 253 | .has_force_wake = 1, |
258 | }; | 254 | }; |
259 | 255 | ||
@@ -264,7 +260,6 @@ static const struct intel_device_info intel_ivybridge_m_info = { | |||
264 | .has_bsd_ring = 1, | 260 | .has_bsd_ring = 1, |
265 | .has_blt_ring = 1, | 261 | .has_blt_ring = 1, |
266 | .has_llc = 1, | 262 | .has_llc = 1, |
267 | .has_pch_split = 1, | ||
268 | .has_force_wake = 1, | 263 | .has_force_wake = 1, |
269 | }; | 264 | }; |
270 | 265 | ||
@@ -292,7 +287,6 @@ static const struct intel_device_info intel_haswell_d_info = { | |||
292 | .has_bsd_ring = 1, | 287 | .has_bsd_ring = 1, |
293 | .has_blt_ring = 1, | 288 | .has_blt_ring = 1, |
294 | .has_llc = 1, | 289 | .has_llc = 1, |
295 | .has_pch_split = 1, | ||
296 | .has_force_wake = 1, | 290 | .has_force_wake = 1, |
297 | }; | 291 | }; |
298 | 292 | ||
@@ -302,7 +296,6 @@ static const struct intel_device_info intel_haswell_m_info = { | |||
302 | .has_bsd_ring = 1, | 296 | .has_bsd_ring = 1, |
303 | .has_blt_ring = 1, | 297 | .has_blt_ring = 1, |
304 | .has_llc = 1, | 298 | .has_llc = 1, |
305 | .has_pch_split = 1, | ||
306 | .has_force_wake = 1, | 299 | .has_force_wake = 1, |
307 | }; | 300 | }; |
308 | 301 | ||
@@ -358,6 +351,9 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
358 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ | 351 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ |
359 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ | 352 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ |
360 | INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ | 353 | INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ |
354 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), | ||
355 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), | ||
356 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), | ||
361 | {0, 0, 0} | 357 | {0, 0, 0} |
362 | }; | 358 | }; |
363 | 359 | ||
@@ -429,135 +425,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) | |||
429 | return 1; | 425 | return 1; |
430 | } | 426 | } |
431 | 427 | ||
432 | void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | ||
433 | { | ||
434 | int count; | ||
435 | |||
436 | count = 0; | ||
437 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) | ||
438 | udelay(10); | ||
439 | |||
440 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | ||
441 | POSTING_READ(FORCEWAKE); | ||
442 | |||
443 | count = 0; | ||
444 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) | ||
445 | udelay(10); | ||
446 | } | ||
447 | |||
448 | void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | ||
449 | { | ||
450 | int count; | ||
451 | |||
452 | count = 0; | ||
453 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1)) | ||
454 | udelay(10); | ||
455 | |||
456 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); | ||
457 | POSTING_READ(FORCEWAKE_MT); | ||
458 | |||
459 | count = 0; | ||
460 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0) | ||
461 | udelay(10); | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Generally this is called implicitly by the register read function. However, | ||
466 | * if some sequence requires the GT to not power down then this function should | ||
467 | * be called at the beginning of the sequence followed by a call to | ||
468 | * gen6_gt_force_wake_put() at the end of the sequence. | ||
469 | */ | ||
470 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | ||
471 | { | ||
472 | unsigned long irqflags; | ||
473 | |||
474 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); | ||
475 | if (dev_priv->forcewake_count++ == 0) | ||
476 | dev_priv->display.force_wake_get(dev_priv); | ||
477 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
478 | } | ||
479 | |||
480 | static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | ||
481 | { | ||
482 | u32 gtfifodbg; | ||
483 | gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); | ||
484 | if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, | ||
485 | "MMIO read or write has been dropped %x\n", gtfifodbg)) | ||
486 | I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); | ||
487 | } | ||
488 | |||
489 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | ||
490 | { | ||
491 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | ||
492 | /* The below doubles as a POSTING_READ */ | ||
493 | gen6_gt_check_fifodbg(dev_priv); | ||
494 | } | ||
495 | |||
496 | void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | ||
497 | { | ||
498 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); | ||
499 | /* The below doubles as a POSTING_READ */ | ||
500 | gen6_gt_check_fifodbg(dev_priv); | ||
501 | } | ||
502 | |||
503 | /* | ||
504 | * see gen6_gt_force_wake_get() | ||
505 | */ | ||
506 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | ||
507 | { | ||
508 | unsigned long irqflags; | ||
509 | |||
510 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); | ||
511 | if (--dev_priv->forcewake_count == 0) | ||
512 | dev_priv->display.force_wake_put(dev_priv); | ||
513 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
514 | } | ||
515 | |||
516 | int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | ||
517 | { | ||
518 | int ret = 0; | ||
519 | |||
520 | if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { | ||
521 | int loop = 500; | ||
522 | u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | ||
523 | while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { | ||
524 | udelay(10); | ||
525 | fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | ||
526 | } | ||
527 | if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) | ||
528 | ++ret; | ||
529 | dev_priv->gt_fifo_count = fifo; | ||
530 | } | ||
531 | dev_priv->gt_fifo_count--; | ||
532 | |||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | void vlv_force_wake_get(struct drm_i915_private *dev_priv) | ||
537 | { | ||
538 | int count; | ||
539 | |||
540 | count = 0; | ||
541 | |||
542 | /* Already awake? */ | ||
543 | if ((I915_READ(0x130094) & 0xa1) == 0xa1) | ||
544 | return; | ||
545 | |||
546 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff); | ||
547 | POSTING_READ(FORCEWAKE_VLV); | ||
548 | |||
549 | count = 0; | ||
550 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0) | ||
551 | udelay(10); | ||
552 | } | ||
553 | |||
554 | void vlv_force_wake_put(struct drm_i915_private *dev_priv) | ||
555 | { | ||
556 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000); | ||
557 | /* FIXME: confirm VLV behavior with Punit folks */ | ||
558 | POSTING_READ(FORCEWAKE_VLV); | ||
559 | } | ||
560 | |||
561 | static int i915_drm_freeze(struct drm_device *dev) | 428 | static int i915_drm_freeze(struct drm_device *dev) |
562 | { | 429 | { |
563 | struct drm_i915_private *dev_priv = dev->dev_private; | 430 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -637,7 +504,7 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
637 | 504 | ||
638 | /* KMS EnterVT equivalent */ | 505 | /* KMS EnterVT equivalent */ |
639 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 506 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
640 | if (HAS_PCH_SPLIT(dev)) | 507 | if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) |
641 | ironlake_init_pch_refclk(dev); | 508 | ironlake_init_pch_refclk(dev); |
642 | 509 | ||
643 | mutex_lock(&dev->struct_mutex); | 510 | mutex_lock(&dev->struct_mutex); |
@@ -794,9 +661,9 @@ static int gen6_do_reset(struct drm_device *dev) | |||
794 | 661 | ||
795 | /* If reset with a user forcewake, try to restore, otherwise turn it off */ | 662 | /* If reset with a user forcewake, try to restore, otherwise turn it off */ |
796 | if (dev_priv->forcewake_count) | 663 | if (dev_priv->forcewake_count) |
797 | dev_priv->display.force_wake_get(dev_priv); | 664 | dev_priv->gt.force_wake_get(dev_priv); |
798 | else | 665 | else |
799 | dev_priv->display.force_wake_put(dev_priv); | 666 | dev_priv->gt.force_wake_put(dev_priv); |
800 | 667 | ||
801 | /* Restore fifo count */ | 668 | /* Restore fifo count */ |
802 | dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | 669 | dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); |
@@ -805,7 +672,7 @@ static int gen6_do_reset(struct drm_device *dev) | |||
805 | return ret; | 672 | return ret; |
806 | } | 673 | } |
807 | 674 | ||
808 | static int intel_gpu_reset(struct drm_device *dev) | 675 | int intel_gpu_reset(struct drm_device *dev) |
809 | { | 676 | { |
810 | struct drm_i915_private *dev_priv = dev->dev_private; | 677 | struct drm_i915_private *dev_priv = dev->dev_private; |
811 | int ret = -ENODEV; | 678 | int ret = -ENODEV; |
@@ -863,10 +730,7 @@ int i915_reset(struct drm_device *dev) | |||
863 | if (!i915_try_reset) | 730 | if (!i915_try_reset) |
864 | return 0; | 731 | return 0; |
865 | 732 | ||
866 | if (!mutex_trylock(&dev->struct_mutex)) | 733 | mutex_lock(&dev->struct_mutex); |
867 | return -EBUSY; | ||
868 | |||
869 | dev_priv->stop_rings = 0; | ||
870 | 734 | ||
871 | i915_gem_reset(dev); | 735 | i915_gem_reset(dev); |
872 | 736 | ||
@@ -909,12 +773,16 @@ int i915_reset(struct drm_device *dev) | |||
909 | for_each_ring(ring, dev_priv, i) | 773 | for_each_ring(ring, dev_priv, i) |
910 | ring->init(ring); | 774 | ring->init(ring); |
911 | 775 | ||
776 | i915_gem_context_init(dev); | ||
912 | i915_gem_init_ppgtt(dev); | 777 | i915_gem_init_ppgtt(dev); |
913 | 778 | ||
914 | mutex_unlock(&dev->struct_mutex); | 779 | /* |
780 | * It would make sense to re-init all the other hw state, at | ||
781 | * least the rps/rc6/emon init done within modeset_init_hw. For | ||
782 | * some unknown reason, this blows up my ilk, so don't. | ||
783 | */ | ||
915 | 784 | ||
916 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 785 | mutex_unlock(&dev->struct_mutex); |
917 | intel_modeset_init_hw(dev); | ||
918 | 786 | ||
919 | drm_irq_uninstall(dev); | 787 | drm_irq_uninstall(dev); |
920 | drm_irq_install(dev); | 788 | drm_irq_install(dev); |
@@ -925,10 +793,12 @@ int i915_reset(struct drm_device *dev) | |||
925 | return 0; | 793 | return 0; |
926 | } | 794 | } |
927 | 795 | ||
928 | |||
929 | static int __devinit | 796 | static int __devinit |
930 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 797 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
931 | { | 798 | { |
799 | struct intel_device_info *intel_info = | ||
800 | (struct intel_device_info *) ent->driver_data; | ||
801 | |||
932 | /* Only bind to function 0 of the device. Early generations | 802 | /* Only bind to function 0 of the device. Early generations |
933 | * used function 1 as a placeholder for multi-head. This causes | 803 | * used function 1 as a placeholder for multi-head. This causes |
934 | * us confusion instead, especially on the systems where both | 804 | * us confusion instead, especially on the systems where both |
@@ -937,6 +807,18 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
937 | if (PCI_FUNC(pdev->devfn)) | 807 | if (PCI_FUNC(pdev->devfn)) |
938 | return -ENODEV; | 808 | return -ENODEV; |
939 | 809 | ||
810 | /* We've managed to ship a kms-enabled ddx that shipped with an XvMC | ||
811 | * implementation for gen3 (and only gen3) that used legacy drm maps | ||
812 | * (gasp!) to share buffers between X and the client. Hence we need to | ||
813 | * keep around the fake agp stuff for gen3, even when kms is enabled. */ | ||
814 | if (intel_info->gen != 3) { | ||
815 | driver.driver_features &= | ||
816 | ~(DRIVER_USE_AGP | DRIVER_REQUIRE_AGP); | ||
817 | } else if (!intel_agp_enabled) { | ||
818 | DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); | ||
819 | return -ENODEV; | ||
820 | } | ||
821 | |||
940 | return drm_get_pci_dev(pdev, ent, &driver); | 822 | return drm_get_pci_dev(pdev, ent, &driver); |
941 | } | 823 | } |
942 | 824 | ||
@@ -1058,7 +940,6 @@ static struct drm_driver driver = { | |||
1058 | .resume = i915_resume, | 940 | .resume = i915_resume, |
1059 | 941 | ||
1060 | .device_is_agp = i915_driver_device_is_agp, | 942 | .device_is_agp = i915_driver_device_is_agp, |
1061 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
1062 | .master_create = i915_master_create, | 943 | .master_create = i915_master_create, |
1063 | .master_destroy = i915_master_destroy, | 944 | .master_destroy = i915_master_destroy, |
1064 | #if defined(CONFIG_DEBUG_FS) | 945 | #if defined(CONFIG_DEBUG_FS) |
@@ -1097,11 +978,6 @@ static struct pci_driver i915_pci_driver = { | |||
1097 | 978 | ||
1098 | static int __init i915_init(void) | 979 | static int __init i915_init(void) |
1099 | { | 980 | { |
1100 | if (!intel_agp_enabled) { | ||
1101 | DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); | ||
1102 | return -ENODEV; | ||
1103 | } | ||
1104 | |||
1105 | driver.num_ioctls = i915_max_ioctl; | 981 | driver.num_ioctls = i915_max_ioctl; |
1106 | 982 | ||
1107 | /* | 983 | /* |
@@ -1149,6 +1025,84 @@ MODULE_LICENSE("GPL and additional rights"); | |||
1149 | ((reg) < 0x40000) && \ | 1025 | ((reg) < 0x40000) && \ |
1150 | ((reg) != FORCEWAKE)) | 1026 | ((reg) != FORCEWAKE)) |
1151 | 1027 | ||
1028 | static bool IS_DISPLAYREG(u32 reg) | ||
1029 | { | ||
1030 | /* | ||
1031 | * This should make it easier to transition modules over to the | ||
1032 | * new register block scheme, since we can do it incrementally. | ||
1033 | */ | ||
1034 | if (reg >= 0x180000) | ||
1035 | return false; | ||
1036 | |||
1037 | if (reg >= RENDER_RING_BASE && | ||
1038 | reg < RENDER_RING_BASE + 0xff) | ||
1039 | return false; | ||
1040 | if (reg >= GEN6_BSD_RING_BASE && | ||
1041 | reg < GEN6_BSD_RING_BASE + 0xff) | ||
1042 | return false; | ||
1043 | if (reg >= BLT_RING_BASE && | ||
1044 | reg < BLT_RING_BASE + 0xff) | ||
1045 | return false; | ||
1046 | |||
1047 | if (reg == PGTBL_ER) | ||
1048 | return false; | ||
1049 | |||
1050 | if (reg >= IPEIR_I965 && | ||
1051 | reg < HWSTAM) | ||
1052 | return false; | ||
1053 | |||
1054 | if (reg == MI_MODE) | ||
1055 | return false; | ||
1056 | |||
1057 | if (reg == GFX_MODE_GEN7) | ||
1058 | return false; | ||
1059 | |||
1060 | if (reg == RENDER_HWS_PGA_GEN7 || | ||
1061 | reg == BSD_HWS_PGA_GEN7 || | ||
1062 | reg == BLT_HWS_PGA_GEN7) | ||
1063 | return false; | ||
1064 | |||
1065 | if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL || | ||
1066 | reg == GEN6_BSD_RNCID) | ||
1067 | return false; | ||
1068 | |||
1069 | if (reg == GEN6_BLITTER_ECOSKPD) | ||
1070 | return false; | ||
1071 | |||
1072 | if (reg >= 0x4000c && | ||
1073 | reg <= 0x4002c) | ||
1074 | return false; | ||
1075 | |||
1076 | if (reg >= 0x4f000 && | ||
1077 | reg <= 0x4f08f) | ||
1078 | return false; | ||
1079 | |||
1080 | if (reg >= 0x4f100 && | ||
1081 | reg <= 0x4f11f) | ||
1082 | return false; | ||
1083 | |||
1084 | if (reg >= VLV_MASTER_IER && | ||
1085 | reg <= GEN6_PMIER) | ||
1086 | return false; | ||
1087 | |||
1088 | if (reg >= FENCE_REG_SANDYBRIDGE_0 && | ||
1089 | reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8))) | ||
1090 | return false; | ||
1091 | |||
1092 | if (reg >= VLV_IIR_RW && | ||
1093 | reg <= VLV_ISR) | ||
1094 | return false; | ||
1095 | |||
1096 | if (reg == FORCEWAKE_VLV || | ||
1097 | reg == FORCEWAKE_ACK_VLV) | ||
1098 | return false; | ||
1099 | |||
1100 | if (reg == GEN6_GDRST) | ||
1101 | return false; | ||
1102 | |||
1103 | return true; | ||
1104 | } | ||
1105 | |||
1152 | #define __i915_read(x, y) \ | 1106 | #define __i915_read(x, y) \ |
1153 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 1107 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
1154 | u##x val = 0; \ | 1108 | u##x val = 0; \ |
@@ -1156,11 +1110,13 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | |||
1156 | unsigned long irqflags; \ | 1110 | unsigned long irqflags; \ |
1157 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ | 1111 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ |
1158 | if (dev_priv->forcewake_count == 0) \ | 1112 | if (dev_priv->forcewake_count == 0) \ |
1159 | dev_priv->display.force_wake_get(dev_priv); \ | 1113 | dev_priv->gt.force_wake_get(dev_priv); \ |
1160 | val = read##y(dev_priv->regs + reg); \ | 1114 | val = read##y(dev_priv->regs + reg); \ |
1161 | if (dev_priv->forcewake_count == 0) \ | 1115 | if (dev_priv->forcewake_count == 0) \ |
1162 | dev_priv->display.force_wake_put(dev_priv); \ | 1116 | dev_priv->gt.force_wake_put(dev_priv); \ |
1163 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ | 1117 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ |
1118 | } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ | ||
1119 | val = read##y(dev_priv->regs + reg + 0x180000); \ | ||
1164 | } else { \ | 1120 | } else { \ |
1165 | val = read##y(dev_priv->regs + reg); \ | 1121 | val = read##y(dev_priv->regs + reg); \ |
1166 | } \ | 1122 | } \ |
@@ -1181,7 +1137,11 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ | |||
1181 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 1137 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
1182 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ | 1138 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
1183 | } \ | 1139 | } \ |
1184 | write##y(val, dev_priv->regs + reg); \ | 1140 | if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ |
1141 | write##y(val, dev_priv->regs + reg + 0x180000); \ | ||
1142 | } else { \ | ||
1143 | write##y(val, dev_priv->regs + reg); \ | ||
1144 | } \ | ||
1185 | if (unlikely(__fifo_ret)) { \ | 1145 | if (unlikely(__fifo_ret)) { \ |
1186 | gen6_gt_check_fifodbg(dev_priv); \ | 1146 | gen6_gt_check_fifodbg(dev_priv); \ |
1187 | } \ | 1147 | } \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b0b676abde0d..627fe35781b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -79,6 +79,10 @@ enum port { | |||
79 | 79 | ||
80 | #define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++) | 80 | #define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++) |
81 | 81 | ||
82 | #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ | ||
83 | list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ | ||
84 | if ((intel_encoder)->base.crtc == (__crtc)) | ||
85 | |||
82 | struct intel_pch_pll { | 86 | struct intel_pch_pll { |
83 | int refcount; /* count of number of CRTCs sharing this PLL */ | 87 | int refcount; /* count of number of CRTCs sharing this PLL */ |
84 | int active; /* count of number of active CRTCs (i.e. DPMS on) */ | 88 | int active; /* count of number of active CRTCs (i.e. DPMS on) */ |
@@ -176,6 +180,7 @@ struct drm_i915_error_state { | |||
176 | u32 eir; | 180 | u32 eir; |
177 | u32 pgtbl_er; | 181 | u32 pgtbl_er; |
178 | u32 ier; | 182 | u32 ier; |
183 | u32 ccid; | ||
179 | bool waiting[I915_NUM_RINGS]; | 184 | bool waiting[I915_NUM_RINGS]; |
180 | u32 pipestat[I915_MAX_PIPES]; | 185 | u32 pipestat[I915_MAX_PIPES]; |
181 | u32 tail[I915_NUM_RINGS]; | 186 | u32 tail[I915_NUM_RINGS]; |
@@ -185,6 +190,7 @@ struct drm_i915_error_state { | |||
185 | u32 instdone[I915_NUM_RINGS]; | 190 | u32 instdone[I915_NUM_RINGS]; |
186 | u32 acthd[I915_NUM_RINGS]; | 191 | u32 acthd[I915_NUM_RINGS]; |
187 | u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; | 192 | u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; |
193 | u32 rc_psmi[I915_NUM_RINGS]; /* sleep state */ | ||
188 | /* our own tracking of ring head and tail */ | 194 | /* our own tracking of ring head and tail */ |
189 | u32 cpu_ring_head[I915_NUM_RINGS]; | 195 | u32 cpu_ring_head[I915_NUM_RINGS]; |
190 | u32 cpu_ring_tail[I915_NUM_RINGS]; | 196 | u32 cpu_ring_tail[I915_NUM_RINGS]; |
@@ -261,8 +267,6 @@ struct drm_i915_display_funcs { | |||
261 | struct drm_i915_gem_object *obj); | 267 | struct drm_i915_gem_object *obj); |
262 | int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 268 | int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
263 | int x, int y); | 269 | int x, int y); |
264 | void (*force_wake_get)(struct drm_i915_private *dev_priv); | ||
265 | void (*force_wake_put)(struct drm_i915_private *dev_priv); | ||
266 | /* clock updates for mode set */ | 270 | /* clock updates for mode set */ |
267 | /* cursor updates */ | 271 | /* cursor updates */ |
268 | /* render clock increase/decrease */ | 272 | /* render clock increase/decrease */ |
@@ -270,6 +274,11 @@ struct drm_i915_display_funcs { | |||
270 | /* pll clock increase/decrease */ | 274 | /* pll clock increase/decrease */ |
271 | }; | 275 | }; |
272 | 276 | ||
277 | struct drm_i915_gt_funcs { | ||
278 | void (*force_wake_get)(struct drm_i915_private *dev_priv); | ||
279 | void (*force_wake_put)(struct drm_i915_private *dev_priv); | ||
280 | }; | ||
281 | |||
273 | struct intel_device_info { | 282 | struct intel_device_info { |
274 | u8 gen; | 283 | u8 gen; |
275 | u8 is_mobile:1; | 284 | u8 is_mobile:1; |
@@ -284,7 +293,6 @@ struct intel_device_info { | |||
284 | u8 is_crestline:1; | 293 | u8 is_crestline:1; |
285 | u8 is_ivybridge:1; | 294 | u8 is_ivybridge:1; |
286 | u8 is_valleyview:1; | 295 | u8 is_valleyview:1; |
287 | u8 has_pch_split:1; | ||
288 | u8 has_force_wake:1; | 296 | u8 has_force_wake:1; |
289 | u8 is_haswell:1; | 297 | u8 is_haswell:1; |
290 | u8 has_fbc:1; | 298 | u8 has_fbc:1; |
@@ -309,6 +317,17 @@ struct i915_hw_ppgtt { | |||
309 | dma_addr_t scratch_page_dma_addr; | 317 | dma_addr_t scratch_page_dma_addr; |
310 | }; | 318 | }; |
311 | 319 | ||
320 | |||
321 | /* This must match up with the value previously used for execbuf2.rsvd1. */ | ||
322 | #define DEFAULT_CONTEXT_ID 0 | ||
323 | struct i915_hw_context { | ||
324 | int id; | ||
325 | bool is_initialized; | ||
326 | struct drm_i915_file_private *file_priv; | ||
327 | struct intel_ring_buffer *ring; | ||
328 | struct drm_i915_gem_object *obj; | ||
329 | }; | ||
330 | |||
312 | enum no_fbc_reason { | 331 | enum no_fbc_reason { |
313 | FBC_NO_OUTPUT, /* no outputs enabled to compress */ | 332 | FBC_NO_OUTPUT, /* no outputs enabled to compress */ |
314 | FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ | 333 | FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ |
@@ -321,6 +340,7 @@ enum no_fbc_reason { | |||
321 | }; | 340 | }; |
322 | 341 | ||
323 | enum intel_pch { | 342 | enum intel_pch { |
343 | PCH_NONE = 0, /* No PCH present */ | ||
324 | PCH_IBX, /* Ibexpeak PCH */ | 344 | PCH_IBX, /* Ibexpeak PCH */ |
325 | PCH_CPT, /* Cougarpoint PCH */ | 345 | PCH_CPT, /* Cougarpoint PCH */ |
326 | PCH_LPT, /* Lynxpoint PCH */ | 346 | PCH_LPT, /* Lynxpoint PCH */ |
@@ -350,6 +370,8 @@ typedef struct drm_i915_private { | |||
350 | int relative_constants_mode; | 370 | int relative_constants_mode; |
351 | 371 | ||
352 | void __iomem *regs; | 372 | void __iomem *regs; |
373 | |||
374 | struct drm_i915_gt_funcs gt; | ||
353 | /** gt_fifo_count and the subsequent register write are synchronized | 375 | /** gt_fifo_count and the subsequent register write are synchronized |
354 | * with dev->struct_mutex. */ | 376 | * with dev->struct_mutex. */ |
355 | unsigned gt_fifo_count; | 377 | unsigned gt_fifo_count; |
@@ -652,11 +674,14 @@ typedef struct drm_i915_private { | |||
652 | unsigned long gtt_end; | 674 | unsigned long gtt_end; |
653 | 675 | ||
654 | struct io_mapping *gtt_mapping; | 676 | struct io_mapping *gtt_mapping; |
677 | phys_addr_t gtt_base_addr; | ||
655 | int gtt_mtrr; | 678 | int gtt_mtrr; |
656 | 679 | ||
657 | /** PPGTT used for aliasing the PPGTT with the GTT */ | 680 | /** PPGTT used for aliasing the PPGTT with the GTT */ |
658 | struct i915_hw_ppgtt *aliasing_ppgtt; | 681 | struct i915_hw_ppgtt *aliasing_ppgtt; |
659 | 682 | ||
683 | u32 *l3_remap_info; | ||
684 | |||
660 | struct shrinker inactive_shrinker; | 685 | struct shrinker inactive_shrinker; |
661 | 686 | ||
662 | /** | 687 | /** |
@@ -817,6 +842,10 @@ typedef struct drm_i915_private { | |||
817 | 842 | ||
818 | struct drm_property *broadcast_rgb_property; | 843 | struct drm_property *broadcast_rgb_property; |
819 | struct drm_property *force_audio_property; | 844 | struct drm_property *force_audio_property; |
845 | |||
846 | struct work_struct parity_error_work; | ||
847 | bool hw_contexts_disabled; | ||
848 | uint32_t hw_context_size; | ||
820 | } drm_i915_private_t; | 849 | } drm_i915_private_t; |
821 | 850 | ||
822 | /* Iterate over initialised rings */ | 851 | /* Iterate over initialised rings */ |
@@ -1026,6 +1055,7 @@ struct drm_i915_file_private { | |||
1026 | struct spinlock lock; | 1055 | struct spinlock lock; |
1027 | struct list_head request_list; | 1056 | struct list_head request_list; |
1028 | } mm; | 1057 | } mm; |
1058 | struct idr context_idr; | ||
1029 | }; | 1059 | }; |
1030 | 1060 | ||
1031 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) | 1061 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) |
@@ -1071,7 +1101,8 @@ struct drm_i915_file_private { | |||
1071 | #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) | 1101 | #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) |
1072 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 1102 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
1073 | 1103 | ||
1074 | #define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6) | 1104 | #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) |
1105 | #define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev)) | ||
1075 | 1106 | ||
1076 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) | 1107 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) |
1077 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) | 1108 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) |
@@ -1094,13 +1125,13 @@ struct drm_i915_file_private { | |||
1094 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) | 1125 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) |
1095 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) | 1126 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) |
1096 | 1127 | ||
1097 | #define HAS_PCH_SPLIT(dev) (INTEL_INFO(dev)->has_pch_split) | ||
1098 | #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) | 1128 | #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) |
1099 | 1129 | ||
1100 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) | 1130 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) |
1101 | #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) | 1131 | #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) |
1102 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | 1132 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) |
1103 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) | 1133 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) |
1134 | #define HAS_PCH_SPLIT(dev) (INTEL_PCH_TYPE(dev) != PCH_NONE) | ||
1104 | 1135 | ||
1105 | #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake) | 1136 | #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake) |
1106 | 1137 | ||
@@ -1166,6 +1197,7 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | |||
1166 | extern int i915_emit_box(struct drm_device *dev, | 1197 | extern int i915_emit_box(struct drm_device *dev, |
1167 | struct drm_clip_rect *box, | 1198 | struct drm_clip_rect *box, |
1168 | int DR1, int DR4); | 1199 | int DR1, int DR4); |
1200 | extern int intel_gpu_reset(struct drm_device *dev); | ||
1169 | extern int i915_reset(struct drm_device *dev); | 1201 | extern int i915_reset(struct drm_device *dev); |
1170 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); | 1202 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); |
1171 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); | 1203 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); |
@@ -1178,6 +1210,7 @@ void i915_hangcheck_elapsed(unsigned long data); | |||
1178 | void i915_handle_error(struct drm_device *dev, bool wedged); | 1210 | void i915_handle_error(struct drm_device *dev, bool wedged); |
1179 | 1211 | ||
1180 | extern void intel_irq_init(struct drm_device *dev); | 1212 | extern void intel_irq_init(struct drm_device *dev); |
1213 | extern void intel_gt_init(struct drm_device *dev); | ||
1181 | 1214 | ||
1182 | void i915_error_state_free(struct kref *error_ref); | 1215 | void i915_error_state_free(struct kref *error_ref); |
1183 | 1216 | ||
@@ -1237,6 +1270,8 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
1237 | struct drm_file *file_priv); | 1270 | struct drm_file *file_priv); |
1238 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 1271 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
1239 | struct drm_file *file_priv); | 1272 | struct drm_file *file_priv); |
1273 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, | ||
1274 | struct drm_file *file_priv); | ||
1240 | void i915_gem_load(struct drm_device *dev); | 1275 | void i915_gem_load(struct drm_device *dev); |
1241 | int i915_gem_init_object(struct drm_gem_object *obj); | 1276 | int i915_gem_init_object(struct drm_gem_object *obj); |
1242 | int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring, | 1277 | int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring, |
@@ -1306,6 +1341,8 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) | |||
1306 | 1341 | ||
1307 | void i915_gem_retire_requests(struct drm_device *dev); | 1342 | void i915_gem_retire_requests(struct drm_device *dev); |
1308 | void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); | 1343 | void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); |
1344 | int __must_check i915_gem_check_wedge(struct drm_i915_private *dev_priv, | ||
1345 | bool interruptible); | ||
1309 | 1346 | ||
1310 | void i915_gem_reset(struct drm_device *dev); | 1347 | void i915_gem_reset(struct drm_device *dev); |
1311 | void i915_gem_clflush_object(struct drm_i915_gem_object *obj); | 1348 | void i915_gem_clflush_object(struct drm_i915_gem_object *obj); |
@@ -1315,6 +1352,7 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, | |||
1315 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); | 1352 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); |
1316 | int __must_check i915_gem_init(struct drm_device *dev); | 1353 | int __must_check i915_gem_init(struct drm_device *dev); |
1317 | int __must_check i915_gem_init_hw(struct drm_device *dev); | 1354 | int __must_check i915_gem_init_hw(struct drm_device *dev); |
1355 | void i915_gem_l3_remap(struct drm_device *dev); | ||
1318 | void i915_gem_init_swizzling(struct drm_device *dev); | 1356 | void i915_gem_init_swizzling(struct drm_device *dev); |
1319 | void i915_gem_init_ppgtt(struct drm_device *dev); | 1357 | void i915_gem_init_ppgtt(struct drm_device *dev); |
1320 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 1358 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
@@ -1323,8 +1361,8 @@ int __must_check i915_gem_idle(struct drm_device *dev); | |||
1323 | int __must_check i915_add_request(struct intel_ring_buffer *ring, | 1361 | int __must_check i915_add_request(struct intel_ring_buffer *ring, |
1324 | struct drm_file *file, | 1362 | struct drm_file *file, |
1325 | struct drm_i915_gem_request *request); | 1363 | struct drm_i915_gem_request *request); |
1326 | int __must_check i915_wait_request(struct intel_ring_buffer *ring, | 1364 | int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, |
1327 | uint32_t seqno); | 1365 | uint32_t seqno); |
1328 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1366 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
1329 | int __must_check | 1367 | int __must_check |
1330 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, | 1368 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, |
@@ -1358,6 +1396,16 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, | |||
1358 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | 1396 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, |
1359 | struct drm_gem_object *gem_obj, int flags); | 1397 | struct drm_gem_object *gem_obj, int flags); |
1360 | 1398 | ||
1399 | /* i915_gem_context.c */ | ||
1400 | void i915_gem_context_init(struct drm_device *dev); | ||
1401 | void i915_gem_context_fini(struct drm_device *dev); | ||
1402 | void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); | ||
1403 | int i915_switch_context(struct intel_ring_buffer *ring, | ||
1404 | struct drm_file *file, int to_id); | ||
1405 | int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, | ||
1406 | struct drm_file *file); | ||
1407 | int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, | ||
1408 | struct drm_file *file); | ||
1361 | 1409 | ||
1362 | /* i915_gem_gtt.c */ | 1410 | /* i915_gem_gtt.c */ |
1363 | int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); | 1411 | int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); |
@@ -1475,20 +1523,12 @@ extern bool intel_fbc_enabled(struct drm_device *dev); | |||
1475 | extern void intel_disable_fbc(struct drm_device *dev); | 1523 | extern void intel_disable_fbc(struct drm_device *dev); |
1476 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | 1524 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); |
1477 | extern void ironlake_init_pch_refclk(struct drm_device *dev); | 1525 | extern void ironlake_init_pch_refclk(struct drm_device *dev); |
1478 | extern void ironlake_enable_rc6(struct drm_device *dev); | ||
1479 | extern void gen6_set_rps(struct drm_device *dev, u8 val); | 1526 | extern void gen6_set_rps(struct drm_device *dev, u8 val); |
1480 | extern void intel_detect_pch(struct drm_device *dev); | 1527 | extern void intel_detect_pch(struct drm_device *dev); |
1481 | extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); | 1528 | extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); |
1482 | extern int intel_enable_rc6(const struct drm_device *dev); | 1529 | extern int intel_enable_rc6(const struct drm_device *dev); |
1483 | 1530 | ||
1484 | extern bool i915_semaphore_is_enabled(struct drm_device *dev); | 1531 | extern bool i915_semaphore_is_enabled(struct drm_device *dev); |
1485 | extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); | ||
1486 | extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); | ||
1487 | extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); | ||
1488 | extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); | ||
1489 | |||
1490 | extern void vlv_force_wake_get(struct drm_i915_private *dev_priv); | ||
1491 | extern void vlv_force_wake_put(struct drm_i915_private *dev_priv); | ||
1492 | 1532 | ||
1493 | /* overlay */ | 1533 | /* overlay */ |
1494 | #ifdef CONFIG_DEBUG_FS | 1534 | #ifdef CONFIG_DEBUG_FS |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 288d7b8f49ae..5c4657a54f97 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -96,9 +96,18 @@ i915_gem_wait_for_error(struct drm_device *dev) | |||
96 | if (!atomic_read(&dev_priv->mm.wedged)) | 96 | if (!atomic_read(&dev_priv->mm.wedged)) |
97 | return 0; | 97 | return 0; |
98 | 98 | ||
99 | ret = wait_for_completion_interruptible(x); | 99 | /* |
100 | if (ret) | 100 | * Only wait 10 seconds for the gpu reset to complete to avoid hanging |
101 | * userspace. If it takes that long something really bad is going on and | ||
102 | * we should simply try to bail out and fail as gracefully as possible. | ||
103 | */ | ||
104 | ret = wait_for_completion_interruptible_timeout(x, 10*HZ); | ||
105 | if (ret == 0) { | ||
106 | DRM_ERROR("Timed out waiting for the gpu reset to complete\n"); | ||
107 | return -EIO; | ||
108 | } else if (ret < 0) { | ||
101 | return ret; | 109 | return ret; |
110 | } | ||
102 | 111 | ||
103 | if (atomic_read(&dev_priv->mm.wedged)) { | 112 | if (atomic_read(&dev_priv->mm.wedged)) { |
104 | /* GPU is hung, bump the completion count to account for | 113 | /* GPU is hung, bump the completion count to account for |
@@ -1122,7 +1131,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1122 | 1131 | ||
1123 | obj->fault_mappable = true; | 1132 | obj->fault_mappable = true; |
1124 | 1133 | ||
1125 | pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) + | 1134 | pfn = ((dev_priv->mm.gtt_base_addr + obj->gtt_offset) >> PAGE_SHIFT) + |
1126 | page_offset; | 1135 | page_offset; |
1127 | 1136 | ||
1128 | /* Finally, remap it using the new GTT offset */ | 1137 | /* Finally, remap it using the new GTT offset */ |
@@ -1132,6 +1141,11 @@ unlock: | |||
1132 | out: | 1141 | out: |
1133 | switch (ret) { | 1142 | switch (ret) { |
1134 | case -EIO: | 1143 | case -EIO: |
1144 | /* If this -EIO is due to a gpu hang, give the reset code a | ||
1145 | * chance to clean up the mess. Otherwise return the proper | ||
1146 | * SIGBUS. */ | ||
1147 | if (!atomic_read(&dev_priv->mm.wedged)) | ||
1148 | return VM_FAULT_SIGBUS; | ||
1135 | case -EAGAIN: | 1149 | case -EAGAIN: |
1136 | /* Give the error handler a chance to run and move the | 1150 | /* Give the error handler a chance to run and move the |
1137 | * objects off the GPU active list. Next time we service the | 1151 | * objects off the GPU active list. Next time we service the |
@@ -1568,6 +1582,21 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1568 | int was_empty; | 1582 | int was_empty; |
1569 | int ret; | 1583 | int ret; |
1570 | 1584 | ||
1585 | /* | ||
1586 | * Emit any outstanding flushes - execbuf can fail to emit the flush | ||
1587 | * after having emitted the batchbuffer command. Hence we need to fix | ||
1588 | * things up similar to emitting the lazy request. The difference here | ||
1589 | * is that the flush _must_ happen before the next request, no matter | ||
1590 | * what. | ||
1591 | */ | ||
1592 | if (ring->gpu_caches_dirty) { | ||
1593 | ret = i915_gem_flush_ring(ring, 0, I915_GEM_GPU_DOMAINS); | ||
1594 | if (ret) | ||
1595 | return ret; | ||
1596 | |||
1597 | ring->gpu_caches_dirty = false; | ||
1598 | } | ||
1599 | |||
1571 | BUG_ON(request == NULL); | 1600 | BUG_ON(request == NULL); |
1572 | seqno = i915_gem_next_request_seqno(ring); | 1601 | seqno = i915_gem_next_request_seqno(ring); |
1573 | 1602 | ||
@@ -1613,6 +1642,9 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1613 | queue_delayed_work(dev_priv->wq, | 1642 | queue_delayed_work(dev_priv->wq, |
1614 | &dev_priv->mm.retire_work, HZ); | 1643 | &dev_priv->mm.retire_work, HZ); |
1615 | } | 1644 | } |
1645 | |||
1646 | WARN_ON(!list_empty(&ring->gpu_write_list)); | ||
1647 | |||
1616 | return 0; | 1648 | return 0; |
1617 | } | 1649 | } |
1618 | 1650 | ||
@@ -1827,14 +1859,11 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1827 | */ | 1859 | */ |
1828 | idle = true; | 1860 | idle = true; |
1829 | for_each_ring(ring, dev_priv, i) { | 1861 | for_each_ring(ring, dev_priv, i) { |
1830 | if (!list_empty(&ring->gpu_write_list)) { | 1862 | if (ring->gpu_caches_dirty) { |
1831 | struct drm_i915_gem_request *request; | 1863 | struct drm_i915_gem_request *request; |
1832 | int ret; | ||
1833 | 1864 | ||
1834 | ret = i915_gem_flush_ring(ring, | ||
1835 | 0, I915_GEM_GPU_DOMAINS); | ||
1836 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 1865 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
1837 | if (ret || request == NULL || | 1866 | if (request == NULL || |
1838 | i915_add_request(ring, NULL, request)) | 1867 | i915_add_request(ring, NULL, request)) |
1839 | kfree(request); | 1868 | kfree(request); |
1840 | } | 1869 | } |
@@ -1848,11 +1877,10 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1848 | mutex_unlock(&dev->struct_mutex); | 1877 | mutex_unlock(&dev->struct_mutex); |
1849 | } | 1878 | } |
1850 | 1879 | ||
1851 | static int | 1880 | int |
1852 | i915_gem_check_wedge(struct drm_i915_private *dev_priv) | 1881 | i915_gem_check_wedge(struct drm_i915_private *dev_priv, |
1882 | bool interruptible) | ||
1853 | { | 1883 | { |
1854 | BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | ||
1855 | |||
1856 | if (atomic_read(&dev_priv->mm.wedged)) { | 1884 | if (atomic_read(&dev_priv->mm.wedged)) { |
1857 | struct completion *x = &dev_priv->error_completion; | 1885 | struct completion *x = &dev_priv->error_completion; |
1858 | bool recovery_complete; | 1886 | bool recovery_complete; |
@@ -1863,7 +1891,16 @@ i915_gem_check_wedge(struct drm_i915_private *dev_priv) | |||
1863 | recovery_complete = x->done > 0; | 1891 | recovery_complete = x->done > 0; |
1864 | spin_unlock_irqrestore(&x->wait.lock, flags); | 1892 | spin_unlock_irqrestore(&x->wait.lock, flags); |
1865 | 1893 | ||
1866 | return recovery_complete ? -EIO : -EAGAIN; | 1894 | /* Non-interruptible callers can't handle -EAGAIN, hence return |
1895 | * -EIO unconditionally for these. */ | ||
1896 | if (!interruptible) | ||
1897 | return -EIO; | ||
1898 | |||
1899 | /* Recovery complete, but still wedged means reset failure. */ | ||
1900 | if (recovery_complete) | ||
1901 | return -EIO; | ||
1902 | |||
1903 | return -EAGAIN; | ||
1867 | } | 1904 | } |
1868 | 1905 | ||
1869 | return 0; | 1906 | return 0; |
@@ -1899,34 +1936,85 @@ i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) | |||
1899 | return ret; | 1936 | return ret; |
1900 | } | 1937 | } |
1901 | 1938 | ||
1939 | /** | ||
1940 | * __wait_seqno - wait until execution of seqno has finished | ||
1941 | * @ring: the ring expected to report seqno | ||
1942 | * @seqno: duh! | ||
1943 | * @interruptible: do an interruptible wait (normally yes) | ||
1944 | * @timeout: in - how long to wait (NULL forever); out - how much time remaining | ||
1945 | * | ||
1946 | * Returns 0 if the seqno was found within the alloted time. Else returns the | ||
1947 | * errno with remaining time filled in timeout argument. | ||
1948 | */ | ||
1902 | static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | 1949 | static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, |
1903 | bool interruptible) | 1950 | bool interruptible, struct timespec *timeout) |
1904 | { | 1951 | { |
1905 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1952 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1906 | int ret = 0; | 1953 | struct timespec before, now, wait_time={1,0}; |
1954 | unsigned long timeout_jiffies; | ||
1955 | long end; | ||
1956 | bool wait_forever = true; | ||
1957 | int ret; | ||
1907 | 1958 | ||
1908 | if (i915_seqno_passed(ring->get_seqno(ring), seqno)) | 1959 | if (i915_seqno_passed(ring->get_seqno(ring), seqno)) |
1909 | return 0; | 1960 | return 0; |
1910 | 1961 | ||
1911 | trace_i915_gem_request_wait_begin(ring, seqno); | 1962 | trace_i915_gem_request_wait_begin(ring, seqno); |
1963 | |||
1964 | if (timeout != NULL) { | ||
1965 | wait_time = *timeout; | ||
1966 | wait_forever = false; | ||
1967 | } | ||
1968 | |||
1969 | timeout_jiffies = timespec_to_jiffies(&wait_time); | ||
1970 | |||
1912 | if (WARN_ON(!ring->irq_get(ring))) | 1971 | if (WARN_ON(!ring->irq_get(ring))) |
1913 | return -ENODEV; | 1972 | return -ENODEV; |
1914 | 1973 | ||
1974 | /* Record current time in case interrupted by signal, or wedged * */ | ||
1975 | getrawmonotonic(&before); | ||
1976 | |||
1915 | #define EXIT_COND \ | 1977 | #define EXIT_COND \ |
1916 | (i915_seqno_passed(ring->get_seqno(ring), seqno) || \ | 1978 | (i915_seqno_passed(ring->get_seqno(ring), seqno) || \ |
1917 | atomic_read(&dev_priv->mm.wedged)) | 1979 | atomic_read(&dev_priv->mm.wedged)) |
1980 | do { | ||
1981 | if (interruptible) | ||
1982 | end = wait_event_interruptible_timeout(ring->irq_queue, | ||
1983 | EXIT_COND, | ||
1984 | timeout_jiffies); | ||
1985 | else | ||
1986 | end = wait_event_timeout(ring->irq_queue, EXIT_COND, | ||
1987 | timeout_jiffies); | ||
1918 | 1988 | ||
1919 | if (interruptible) | 1989 | ret = i915_gem_check_wedge(dev_priv, interruptible); |
1920 | ret = wait_event_interruptible(ring->irq_queue, | 1990 | if (ret) |
1921 | EXIT_COND); | 1991 | end = ret; |
1922 | else | 1992 | } while (end == 0 && wait_forever); |
1923 | wait_event(ring->irq_queue, EXIT_COND); | 1993 | |
1994 | getrawmonotonic(&now); | ||
1924 | 1995 | ||
1925 | ring->irq_put(ring); | 1996 | ring->irq_put(ring); |
1926 | trace_i915_gem_request_wait_end(ring, seqno); | 1997 | trace_i915_gem_request_wait_end(ring, seqno); |
1927 | #undef EXIT_COND | 1998 | #undef EXIT_COND |
1928 | 1999 | ||
1929 | return ret; | 2000 | if (timeout) { |
2001 | struct timespec sleep_time = timespec_sub(now, before); | ||
2002 | *timeout = timespec_sub(*timeout, sleep_time); | ||
2003 | } | ||
2004 | |||
2005 | switch (end) { | ||
2006 | case -EIO: | ||
2007 | case -EAGAIN: /* Wedged */ | ||
2008 | case -ERESTARTSYS: /* Signal */ | ||
2009 | return (int)end; | ||
2010 | case 0: /* Timeout */ | ||
2011 | if (timeout) | ||
2012 | set_normalized_timespec(timeout, 0, 0); | ||
2013 | return -ETIME; | ||
2014 | default: /* Completed */ | ||
2015 | WARN_ON(end < 0); /* We're not aware of other errors */ | ||
2016 | return 0; | ||
2017 | } | ||
1930 | } | 2018 | } |
1931 | 2019 | ||
1932 | /** | 2020 | /** |
@@ -1934,15 +2022,14 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | |||
1934 | * request and object lists appropriately for that event. | 2022 | * request and object lists appropriately for that event. |
1935 | */ | 2023 | */ |
1936 | int | 2024 | int |
1937 | i915_wait_request(struct intel_ring_buffer *ring, | 2025 | i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) |
1938 | uint32_t seqno) | ||
1939 | { | 2026 | { |
1940 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 2027 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1941 | int ret = 0; | 2028 | int ret = 0; |
1942 | 2029 | ||
1943 | BUG_ON(seqno == 0); | 2030 | BUG_ON(seqno == 0); |
1944 | 2031 | ||
1945 | ret = i915_gem_check_wedge(dev_priv); | 2032 | ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); |
1946 | if (ret) | 2033 | if (ret) |
1947 | return ret; | 2034 | return ret; |
1948 | 2035 | ||
@@ -1950,9 +2037,7 @@ i915_wait_request(struct intel_ring_buffer *ring, | |||
1950 | if (ret) | 2037 | if (ret) |
1951 | return ret; | 2038 | return ret; |
1952 | 2039 | ||
1953 | ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); | 2040 | ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible, NULL); |
1954 | if (atomic_read(&dev_priv->mm.wedged)) | ||
1955 | ret = -EAGAIN; | ||
1956 | 2041 | ||
1957 | return ret; | 2042 | return ret; |
1958 | } | 2043 | } |
@@ -1975,7 +2060,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | |||
1975 | * it. | 2060 | * it. |
1976 | */ | 2061 | */ |
1977 | if (obj->active) { | 2062 | if (obj->active) { |
1978 | ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); | 2063 | ret = i915_wait_seqno(obj->ring, obj->last_rendering_seqno); |
1979 | if (ret) | 2064 | if (ret) |
1980 | return ret; | 2065 | return ret; |
1981 | i915_gem_retire_requests_ring(obj->ring); | 2066 | i915_gem_retire_requests_ring(obj->ring); |
@@ -1985,6 +2070,115 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | |||
1985 | } | 2070 | } |
1986 | 2071 | ||
1987 | /** | 2072 | /** |
2073 | * Ensures that an object will eventually get non-busy by flushing any required | ||
2074 | * write domains, emitting any outstanding lazy request and retiring and | ||
2075 | * completed requests. | ||
2076 | */ | ||
2077 | static int | ||
2078 | i915_gem_object_flush_active(struct drm_i915_gem_object *obj) | ||
2079 | { | ||
2080 | int ret; | ||
2081 | |||
2082 | if (obj->active) { | ||
2083 | ret = i915_gem_object_flush_gpu_write_domain(obj); | ||
2084 | if (ret) | ||
2085 | return ret; | ||
2086 | |||
2087 | ret = i915_gem_check_olr(obj->ring, | ||
2088 | obj->last_rendering_seqno); | ||
2089 | if (ret) | ||
2090 | return ret; | ||
2091 | i915_gem_retire_requests_ring(obj->ring); | ||
2092 | } | ||
2093 | |||
2094 | return 0; | ||
2095 | } | ||
2096 | |||
2097 | /** | ||
2098 | * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT | ||
2099 | * @DRM_IOCTL_ARGS: standard ioctl arguments | ||
2100 | * | ||
2101 | * Returns 0 if successful, else an error is returned with the remaining time in | ||
2102 | * the timeout parameter. | ||
2103 | * -ETIME: object is still busy after timeout | ||
2104 | * -ERESTARTSYS: signal interrupted the wait | ||
2105 | * -ENONENT: object doesn't exist | ||
2106 | * Also possible, but rare: | ||
2107 | * -EAGAIN: GPU wedged | ||
2108 | * -ENOMEM: damn | ||
2109 | * -ENODEV: Internal IRQ fail | ||
2110 | * -E?: The add request failed | ||
2111 | * | ||
2112 | * The wait ioctl with a timeout of 0 reimplements the busy ioctl. With any | ||
2113 | * non-zero timeout parameter the wait ioctl will wait for the given number of | ||
2114 | * nanoseconds on an object becoming unbusy. Since the wait itself does so | ||
2115 | * without holding struct_mutex the object may become re-busied before this | ||
2116 | * function completes. A similar but shorter * race condition exists in the busy | ||
2117 | * ioctl | ||
2118 | */ | ||
2119 | int | ||
2120 | i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | ||
2121 | { | ||
2122 | struct drm_i915_gem_wait *args = data; | ||
2123 | struct drm_i915_gem_object *obj; | ||
2124 | struct intel_ring_buffer *ring = NULL; | ||
2125 | struct timespec timeout_stack, *timeout = NULL; | ||
2126 | u32 seqno = 0; | ||
2127 | int ret = 0; | ||
2128 | |||
2129 | if (args->timeout_ns >= 0) { | ||
2130 | timeout_stack = ns_to_timespec(args->timeout_ns); | ||
2131 | timeout = &timeout_stack; | ||
2132 | } | ||
2133 | |||
2134 | ret = i915_mutex_lock_interruptible(dev); | ||
2135 | if (ret) | ||
2136 | return ret; | ||
2137 | |||
2138 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle)); | ||
2139 | if (&obj->base == NULL) { | ||
2140 | mutex_unlock(&dev->struct_mutex); | ||
2141 | return -ENOENT; | ||
2142 | } | ||
2143 | |||
2144 | /* Need to make sure the object gets inactive eventually. */ | ||
2145 | ret = i915_gem_object_flush_active(obj); | ||
2146 | if (ret) | ||
2147 | goto out; | ||
2148 | |||
2149 | if (obj->active) { | ||
2150 | seqno = obj->last_rendering_seqno; | ||
2151 | ring = obj->ring; | ||
2152 | } | ||
2153 | |||
2154 | if (seqno == 0) | ||
2155 | goto out; | ||
2156 | |||
2157 | /* Do this after OLR check to make sure we make forward progress polling | ||
2158 | * on this IOCTL with a 0 timeout (like busy ioctl) | ||
2159 | */ | ||
2160 | if (!args->timeout_ns) { | ||
2161 | ret = -ETIME; | ||
2162 | goto out; | ||
2163 | } | ||
2164 | |||
2165 | drm_gem_object_unreference(&obj->base); | ||
2166 | mutex_unlock(&dev->struct_mutex); | ||
2167 | |||
2168 | ret = __wait_seqno(ring, seqno, true, timeout); | ||
2169 | if (timeout) { | ||
2170 | WARN_ON(!timespec_valid(timeout)); | ||
2171 | args->timeout_ns = timespec_to_ns(timeout); | ||
2172 | } | ||
2173 | return ret; | ||
2174 | |||
2175 | out: | ||
2176 | drm_gem_object_unreference(&obj->base); | ||
2177 | mutex_unlock(&dev->struct_mutex); | ||
2178 | return ret; | ||
2179 | } | ||
2180 | |||
2181 | /** | ||
1988 | * i915_gem_object_sync - sync an object to a ring. | 2182 | * i915_gem_object_sync - sync an object to a ring. |
1989 | * | 2183 | * |
1990 | * @obj: object which may be in use on another ring. | 2184 | * @obj: object which may be in use on another ring. |
@@ -2160,7 +2354,7 @@ static int i915_ring_idle(struct intel_ring_buffer *ring) | |||
2160 | return ret; | 2354 | return ret; |
2161 | } | 2355 | } |
2162 | 2356 | ||
2163 | return i915_wait_request(ring, i915_gem_next_request_seqno(ring)); | 2357 | return i915_wait_seqno(ring, i915_gem_next_request_seqno(ring)); |
2164 | } | 2358 | } |
2165 | 2359 | ||
2166 | int i915_gpu_idle(struct drm_device *dev) | 2360 | int i915_gpu_idle(struct drm_device *dev) |
@@ -2178,6 +2372,10 @@ int i915_gpu_idle(struct drm_device *dev) | |||
2178 | /* Is the device fubar? */ | 2372 | /* Is the device fubar? */ |
2179 | if (WARN_ON(!list_empty(&ring->gpu_write_list))) | 2373 | if (WARN_ON(!list_empty(&ring->gpu_write_list))) |
2180 | return -EBUSY; | 2374 | return -EBUSY; |
2375 | |||
2376 | ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); | ||
2377 | if (ret) | ||
2378 | return ret; | ||
2181 | } | 2379 | } |
2182 | 2380 | ||
2183 | return 0; | 2381 | return 0; |
@@ -2364,7 +2562,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) | |||
2364 | } | 2562 | } |
2365 | 2563 | ||
2366 | if (obj->last_fenced_seqno) { | 2564 | if (obj->last_fenced_seqno) { |
2367 | ret = i915_wait_request(obj->ring, obj->last_fenced_seqno); | 2565 | ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno); |
2368 | if (ret) | 2566 | if (ret) |
2369 | return ret; | 2567 | return ret; |
2370 | 2568 | ||
@@ -2551,8 +2749,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2551 | if (map_and_fenceable) | 2749 | if (map_and_fenceable) |
2552 | free_space = | 2750 | free_space = |
2553 | drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, | 2751 | drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, |
2554 | size, alignment, 0, | 2752 | size, alignment, |
2555 | dev_priv->mm.gtt_mappable_end, | 2753 | 0, dev_priv->mm.gtt_mappable_end, |
2556 | 0); | 2754 | 0); |
2557 | else | 2755 | else |
2558 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, | 2756 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, |
@@ -2563,7 +2761,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2563 | obj->gtt_space = | 2761 | obj->gtt_space = |
2564 | drm_mm_get_block_range_generic(free_space, | 2762 | drm_mm_get_block_range_generic(free_space, |
2565 | size, alignment, 0, | 2763 | size, alignment, 0, |
2566 | dev_priv->mm.gtt_mappable_end, | 2764 | 0, dev_priv->mm.gtt_mappable_end, |
2567 | 0); | 2765 | 0); |
2568 | else | 2766 | else |
2569 | obj->gtt_space = | 2767 | obj->gtt_space = |
@@ -3030,7 +3228,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
3030 | if (seqno == 0) | 3228 | if (seqno == 0) |
3031 | return 0; | 3229 | return 0; |
3032 | 3230 | ||
3033 | ret = __wait_seqno(ring, seqno, true); | 3231 | ret = __wait_seqno(ring, seqno, true, NULL); |
3034 | if (ret == 0) | 3232 | if (ret == 0) |
3035 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); | 3233 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); |
3036 | 3234 | ||
@@ -3199,30 +3397,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
3199 | * become non-busy without any further actions, therefore emit any | 3397 | * become non-busy without any further actions, therefore emit any |
3200 | * necessary flushes here. | 3398 | * necessary flushes here. |
3201 | */ | 3399 | */ |
3202 | args->busy = obj->active; | 3400 | ret = i915_gem_object_flush_active(obj); |
3203 | if (args->busy) { | ||
3204 | /* Unconditionally flush objects, even when the gpu still uses this | ||
3205 | * object. Userspace calling this function indicates that it wants to | ||
3206 | * use this buffer rather sooner than later, so issuing the required | ||
3207 | * flush earlier is beneficial. | ||
3208 | */ | ||
3209 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { | ||
3210 | ret = i915_gem_flush_ring(obj->ring, | ||
3211 | 0, obj->base.write_domain); | ||
3212 | } else { | ||
3213 | ret = i915_gem_check_olr(obj->ring, | ||
3214 | obj->last_rendering_seqno); | ||
3215 | } | ||
3216 | 3401 | ||
3217 | /* Update the active list for the hardware's current position. | 3402 | args->busy = obj->active; |
3218 | * Otherwise this only updates on a delayed timer or when irqs | ||
3219 | * are actually unmasked, and our working set ends up being | ||
3220 | * larger than required. | ||
3221 | */ | ||
3222 | i915_gem_retire_requests_ring(obj->ring); | ||
3223 | |||
3224 | args->busy = obj->active; | ||
3225 | } | ||
3226 | 3403 | ||
3227 | drm_gem_object_unreference(&obj->base); | 3404 | drm_gem_object_unreference(&obj->base); |
3228 | unlock: | 3405 | unlock: |
@@ -3435,6 +3612,38 @@ i915_gem_idle(struct drm_device *dev) | |||
3435 | return 0; | 3612 | return 0; |
3436 | } | 3613 | } |
3437 | 3614 | ||
3615 | void i915_gem_l3_remap(struct drm_device *dev) | ||
3616 | { | ||
3617 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3618 | u32 misccpctl; | ||
3619 | int i; | ||
3620 | |||
3621 | if (!IS_IVYBRIDGE(dev)) | ||
3622 | return; | ||
3623 | |||
3624 | if (!dev_priv->mm.l3_remap_info) | ||
3625 | return; | ||
3626 | |||
3627 | misccpctl = I915_READ(GEN7_MISCCPCTL); | ||
3628 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); | ||
3629 | POSTING_READ(GEN7_MISCCPCTL); | ||
3630 | |||
3631 | for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) { | ||
3632 | u32 remap = I915_READ(GEN7_L3LOG_BASE + i); | ||
3633 | if (remap && remap != dev_priv->mm.l3_remap_info[i/4]) | ||
3634 | DRM_DEBUG("0x%x was already programmed to %x\n", | ||
3635 | GEN7_L3LOG_BASE + i, remap); | ||
3636 | if (remap && !dev_priv->mm.l3_remap_info[i/4]) | ||
3637 | DRM_DEBUG_DRIVER("Clearing remapped register\n"); | ||
3638 | I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->mm.l3_remap_info[i/4]); | ||
3639 | } | ||
3640 | |||
3641 | /* Make sure all the writes land before disabling dop clock gating */ | ||
3642 | POSTING_READ(GEN7_L3LOG_BASE); | ||
3643 | |||
3644 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | ||
3645 | } | ||
3646 | |||
3438 | void i915_gem_init_swizzling(struct drm_device *dev) | 3647 | void i915_gem_init_swizzling(struct drm_device *dev) |
3439 | { | 3648 | { |
3440 | drm_i915_private_t *dev_priv = dev->dev_private; | 3649 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -3518,12 +3727,33 @@ void i915_gem_init_ppgtt(struct drm_device *dev) | |||
3518 | } | 3727 | } |
3519 | } | 3728 | } |
3520 | 3729 | ||
3730 | static bool | ||
3731 | intel_enable_blt(struct drm_device *dev) | ||
3732 | { | ||
3733 | if (!HAS_BLT(dev)) | ||
3734 | return false; | ||
3735 | |||
3736 | /* The blitter was dysfunctional on early prototypes */ | ||
3737 | if (IS_GEN6(dev) && dev->pdev->revision < 8) { | ||
3738 | DRM_INFO("BLT not supported on this pre-production hardware;" | ||
3739 | " graphics performance will be degraded.\n"); | ||
3740 | return false; | ||
3741 | } | ||
3742 | |||
3743 | return true; | ||
3744 | } | ||
3745 | |||
3521 | int | 3746 | int |
3522 | i915_gem_init_hw(struct drm_device *dev) | 3747 | i915_gem_init_hw(struct drm_device *dev) |
3523 | { | 3748 | { |
3524 | drm_i915_private_t *dev_priv = dev->dev_private; | 3749 | drm_i915_private_t *dev_priv = dev->dev_private; |
3525 | int ret; | 3750 | int ret; |
3526 | 3751 | ||
3752 | if (!intel_enable_gtt()) | ||
3753 | return -EIO; | ||
3754 | |||
3755 | i915_gem_l3_remap(dev); | ||
3756 | |||
3527 | i915_gem_init_swizzling(dev); | 3757 | i915_gem_init_swizzling(dev); |
3528 | 3758 | ||
3529 | ret = intel_init_render_ring_buffer(dev); | 3759 | ret = intel_init_render_ring_buffer(dev); |
@@ -3536,7 +3766,7 @@ i915_gem_init_hw(struct drm_device *dev) | |||
3536 | goto cleanup_render_ring; | 3766 | goto cleanup_render_ring; |
3537 | } | 3767 | } |
3538 | 3768 | ||
3539 | if (HAS_BLT(dev)) { | 3769 | if (intel_enable_blt(dev)) { |
3540 | ret = intel_init_blt_ring_buffer(dev); | 3770 | ret = intel_init_blt_ring_buffer(dev); |
3541 | if (ret) | 3771 | if (ret) |
3542 | goto cleanup_bsd_ring; | 3772 | goto cleanup_bsd_ring; |
@@ -3544,6 +3774,11 @@ i915_gem_init_hw(struct drm_device *dev) | |||
3544 | 3774 | ||
3545 | dev_priv->next_seqno = 1; | 3775 | dev_priv->next_seqno = 1; |
3546 | 3776 | ||
3777 | /* | ||
3778 | * XXX: There was some w/a described somewhere suggesting loading | ||
3779 | * contexts before PPGTT. | ||
3780 | */ | ||
3781 | i915_gem_context_init(dev); | ||
3547 | i915_gem_init_ppgtt(dev); | 3782 | i915_gem_init_ppgtt(dev); |
3548 | 3783 | ||
3549 | return 0; | 3784 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c new file mode 100644 index 000000000000..da8b01fb1bf8 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -0,0 +1,536 @@ | |||
1 | /* | ||
2 | * Copyright © 2011-2012 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Ben Widawsky <ben@bwidawsk.net> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * This file implements HW context support. On gen5+ a HW context consists of an | ||
30 | * opaque GPU object which is referenced at times of context saves and restores. | ||
31 | * With RC6 enabled, the context is also referenced as the GPU enters and exists | ||
32 | * from RC6 (GPU has it's own internal power context, except on gen5). Though | ||
33 | * something like a context does exist for the media ring, the code only | ||
34 | * supports contexts for the render ring. | ||
35 | * | ||
36 | * In software, there is a distinction between contexts created by the user, | ||
37 | * and the default HW context. The default HW context is used by GPU clients | ||
38 | * that do not request setup of their own hardware context. The default | ||
39 | * context's state is never restored to help prevent programming errors. This | ||
40 | * would happen if a client ran and piggy-backed off another clients GPU state. | ||
41 | * The default context only exists to give the GPU some offset to load as the | ||
42 | * current to invoke a save of the context we actually care about. In fact, the | ||
43 | * code could likely be constructed, albeit in a more complicated fashion, to | ||
44 | * never use the default context, though that limits the driver's ability to | ||
45 | * swap out, and/or destroy other contexts. | ||
46 | * | ||
47 | * All other contexts are created as a request by the GPU client. These contexts | ||
48 | * store GPU state, and thus allow GPU clients to not re-emit state (and | ||
49 | * potentially query certain state) at any time. The kernel driver makes | ||
50 | * certain that the appropriate commands are inserted. | ||
51 | * | ||
52 | * The context life cycle is semi-complicated in that context BOs may live | ||
53 | * longer than the context itself because of the way the hardware, and object | ||
54 | * tracking works. Below is a very crude representation of the state machine | ||
55 | * describing the context life. | ||
56 | * refcount pincount active | ||
57 | * S0: initial state 0 0 0 | ||
58 | * S1: context created 1 0 0 | ||
59 | * S2: context is currently running 2 1 X | ||
60 | * S3: GPU referenced, but not current 2 0 1 | ||
61 | * S4: context is current, but destroyed 1 1 0 | ||
62 | * S5: like S3, but destroyed 1 0 1 | ||
63 | * | ||
64 | * The most common (but not all) transitions: | ||
65 | * S0->S1: client creates a context | ||
66 | * S1->S2: client submits execbuf with context | ||
67 | * S2->S3: other clients submits execbuf with context | ||
68 | * S3->S1: context object was retired | ||
69 | * S3->S2: clients submits another execbuf | ||
70 | * S2->S4: context destroy called with current context | ||
71 | * S3->S5->S0: destroy path | ||
72 | * S4->S5->S0: destroy path on current context | ||
73 | * | ||
74 | * There are two confusing terms used above: | ||
75 | * The "current context" means the context which is currently running on the | ||
76 | * GPU. The GPU has loaded it's state already and has stored away the gtt | ||
77 | * offset of the BO. The GPU is not actively referencing the data at this | ||
78 | * offset, but it will on the next context switch. The only way to avoid this | ||
79 | * is to do a GPU reset. | ||
80 | * | ||
81 | * An "active context' is one which was previously the "current context" and is | ||
82 | * on the active list waiting for the next context switch to occur. Until this | ||
83 | * happens, the object must remain at the same gtt offset. It is therefore | ||
84 | * possible to destroy a context, but it is still active. | ||
85 | * | ||
86 | */ | ||
87 | |||
88 | #include "drmP.h" | ||
89 | #include "i915_drm.h" | ||
90 | #include "i915_drv.h" | ||
91 | |||
92 | /* This is a HW constraint. The value below is the largest known requirement | ||
93 | * I've seen in a spec to date, and that was a workaround for a non-shipping | ||
94 | * part. It should be safe to decrease this, but it's more future proof as is. | ||
95 | */ | ||
96 | #define CONTEXT_ALIGN (64<<10) | ||
97 | |||
98 | static struct i915_hw_context * | ||
99 | i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); | ||
100 | static int do_switch(struct drm_i915_gem_object *from_obj, | ||
101 | struct i915_hw_context *to, u32 seqno); | ||
102 | |||
103 | static int get_context_size(struct drm_device *dev) | ||
104 | { | ||
105 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
106 | int ret; | ||
107 | u32 reg; | ||
108 | |||
109 | switch (INTEL_INFO(dev)->gen) { | ||
110 | case 6: | ||
111 | reg = I915_READ(CXT_SIZE); | ||
112 | ret = GEN6_CXT_TOTAL_SIZE(reg) * 64; | ||
113 | break; | ||
114 | case 7: | ||
115 | reg = I915_READ(GEN7_CXT_SIZE); | ||
116 | ret = GEN7_CXT_TOTAL_SIZE(reg) * 64; | ||
117 | break; | ||
118 | default: | ||
119 | BUG(); | ||
120 | } | ||
121 | |||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | static void do_destroy(struct i915_hw_context *ctx) | ||
126 | { | ||
127 | struct drm_device *dev = ctx->obj->base.dev; | ||
128 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
129 | |||
130 | if (ctx->file_priv) | ||
131 | idr_remove(&ctx->file_priv->context_idr, ctx->id); | ||
132 | else | ||
133 | BUG_ON(ctx != dev_priv->ring[RCS].default_context); | ||
134 | |||
135 | drm_gem_object_unreference(&ctx->obj->base); | ||
136 | kfree(ctx); | ||
137 | } | ||
138 | |||
139 | static struct i915_hw_context * | ||
140 | create_hw_context(struct drm_device *dev, | ||
141 | struct drm_i915_file_private *file_priv) | ||
142 | { | ||
143 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
144 | struct i915_hw_context *ctx; | ||
145 | int ret, id; | ||
146 | |||
147 | ctx = kzalloc(sizeof(struct drm_i915_file_private), GFP_KERNEL); | ||
148 | if (ctx == NULL) | ||
149 | return ERR_PTR(-ENOMEM); | ||
150 | |||
151 | ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); | ||
152 | if (ctx->obj == NULL) { | ||
153 | kfree(ctx); | ||
154 | DRM_DEBUG_DRIVER("Context object allocated failed\n"); | ||
155 | return ERR_PTR(-ENOMEM); | ||
156 | } | ||
157 | |||
158 | /* The ring associated with the context object is handled by the normal | ||
159 | * object tracking code. We give an initial ring value simple to pass an | ||
160 | * assertion in the context switch code. | ||
161 | */ | ||
162 | ctx->ring = &dev_priv->ring[RCS]; | ||
163 | |||
164 | /* Default context will never have a file_priv */ | ||
165 | if (file_priv == NULL) | ||
166 | return ctx; | ||
167 | |||
168 | ctx->file_priv = file_priv; | ||
169 | |||
170 | again: | ||
171 | if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) { | ||
172 | ret = -ENOMEM; | ||
173 | DRM_DEBUG_DRIVER("idr allocation failed\n"); | ||
174 | goto err_out; | ||
175 | } | ||
176 | |||
177 | ret = idr_get_new_above(&file_priv->context_idr, ctx, | ||
178 | DEFAULT_CONTEXT_ID + 1, &id); | ||
179 | if (ret == 0) | ||
180 | ctx->id = id; | ||
181 | |||
182 | if (ret == -EAGAIN) | ||
183 | goto again; | ||
184 | else if (ret) | ||
185 | goto err_out; | ||
186 | |||
187 | return ctx; | ||
188 | |||
189 | err_out: | ||
190 | do_destroy(ctx); | ||
191 | return ERR_PTR(ret); | ||
192 | } | ||
193 | |||
194 | static inline bool is_default_context(struct i915_hw_context *ctx) | ||
195 | { | ||
196 | return (ctx == ctx->ring->default_context); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * The default context needs to exist per ring that uses contexts. It stores the | ||
201 | * context state of the GPU for applications that don't utilize HW contexts, as | ||
202 | * well as an idle case. | ||
203 | */ | ||
204 | static int create_default_context(struct drm_i915_private *dev_priv) | ||
205 | { | ||
206 | struct i915_hw_context *ctx; | ||
207 | int ret; | ||
208 | |||
209 | BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | ||
210 | |||
211 | ctx = create_hw_context(dev_priv->dev, NULL); | ||
212 | if (IS_ERR(ctx)) | ||
213 | return PTR_ERR(ctx); | ||
214 | |||
215 | /* We may need to do things with the shrinker which require us to | ||
216 | * immediately switch back to the default context. This can cause a | ||
217 | * problem as pinning the default context also requires GTT space which | ||
218 | * may not be available. To avoid this we always pin the | ||
219 | * default context. | ||
220 | */ | ||
221 | dev_priv->ring[RCS].default_context = ctx; | ||
222 | ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false); | ||
223 | if (ret) { | ||
224 | do_destroy(ctx); | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | ret = do_switch(NULL, ctx, 0); | ||
229 | if (ret) { | ||
230 | i915_gem_object_unpin(ctx->obj); | ||
231 | do_destroy(ctx); | ||
232 | } else { | ||
233 | DRM_DEBUG_DRIVER("Default HW context loaded\n"); | ||
234 | } | ||
235 | |||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | void i915_gem_context_init(struct drm_device *dev) | ||
240 | { | ||
241 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
242 | uint32_t ctx_size; | ||
243 | |||
244 | if (!HAS_HW_CONTEXTS(dev)) { | ||
245 | dev_priv->hw_contexts_disabled = true; | ||
246 | return; | ||
247 | } | ||
248 | |||
249 | /* If called from reset, or thaw... we've been here already */ | ||
250 | if (dev_priv->hw_contexts_disabled || | ||
251 | dev_priv->ring[RCS].default_context) | ||
252 | return; | ||
253 | |||
254 | ctx_size = get_context_size(dev); | ||
255 | dev_priv->hw_context_size = get_context_size(dev); | ||
256 | dev_priv->hw_context_size = round_up(dev_priv->hw_context_size, 4096); | ||
257 | |||
258 | if (ctx_size <= 0 || ctx_size > (1<<20)) { | ||
259 | dev_priv->hw_contexts_disabled = true; | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | if (create_default_context(dev_priv)) { | ||
264 | dev_priv->hw_contexts_disabled = true; | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | DRM_DEBUG_DRIVER("HW context support initialized\n"); | ||
269 | } | ||
270 | |||
271 | void i915_gem_context_fini(struct drm_device *dev) | ||
272 | { | ||
273 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
274 | |||
275 | if (dev_priv->hw_contexts_disabled) | ||
276 | return; | ||
277 | |||
278 | /* The only known way to stop the gpu from accessing the hw context is | ||
279 | * to reset it. Do this as the very last operation to avoid confusing | ||
280 | * other code, leading to spurious errors. */ | ||
281 | intel_gpu_reset(dev); | ||
282 | |||
283 | i915_gem_object_unpin(dev_priv->ring[RCS].default_context->obj); | ||
284 | |||
285 | do_destroy(dev_priv->ring[RCS].default_context); | ||
286 | } | ||
287 | |||
288 | static int context_idr_cleanup(int id, void *p, void *data) | ||
289 | { | ||
290 | struct i915_hw_context *ctx = p; | ||
291 | |||
292 | BUG_ON(id == DEFAULT_CONTEXT_ID); | ||
293 | |||
294 | do_destroy(ctx); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) | ||
300 | { | ||
301 | struct drm_i915_file_private *file_priv = file->driver_priv; | ||
302 | |||
303 | mutex_lock(&dev->struct_mutex); | ||
304 | idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); | ||
305 | idr_destroy(&file_priv->context_idr); | ||
306 | mutex_unlock(&dev->struct_mutex); | ||
307 | } | ||
308 | |||
309 | static struct i915_hw_context * | ||
310 | i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) | ||
311 | { | ||
312 | return (struct i915_hw_context *)idr_find(&file_priv->context_idr, id); | ||
313 | } | ||
314 | |||
315 | static inline int | ||
316 | mi_set_context(struct intel_ring_buffer *ring, | ||
317 | struct i915_hw_context *new_context, | ||
318 | u32 hw_flags) | ||
319 | { | ||
320 | int ret; | ||
321 | |||
322 | /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB | ||
323 | * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value | ||
324 | * explicitly, so we rely on the value at ring init, stored in | ||
325 | * itlb_before_ctx_switch. | ||
326 | */ | ||
327 | if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) { | ||
328 | ret = ring->flush(ring, 0, 0); | ||
329 | if (ret) | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | ret = intel_ring_begin(ring, 6); | ||
334 | if (ret) | ||
335 | return ret; | ||
336 | |||
337 | if (IS_GEN7(ring->dev)) | ||
338 | intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); | ||
339 | else | ||
340 | intel_ring_emit(ring, MI_NOOP); | ||
341 | |||
342 | intel_ring_emit(ring, MI_NOOP); | ||
343 | intel_ring_emit(ring, MI_SET_CONTEXT); | ||
344 | intel_ring_emit(ring, new_context->obj->gtt_offset | | ||
345 | MI_MM_SPACE_GTT | | ||
346 | MI_SAVE_EXT_STATE_EN | | ||
347 | MI_RESTORE_EXT_STATE_EN | | ||
348 | hw_flags); | ||
349 | /* w/a: MI_SET_CONTEXT must always be followed by MI_NOOP */ | ||
350 | intel_ring_emit(ring, MI_NOOP); | ||
351 | |||
352 | if (IS_GEN7(ring->dev)) | ||
353 | intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); | ||
354 | else | ||
355 | intel_ring_emit(ring, MI_NOOP); | ||
356 | |||
357 | intel_ring_advance(ring); | ||
358 | |||
359 | return ret; | ||
360 | } | ||
361 | |||
362 | static int do_switch(struct drm_i915_gem_object *from_obj, | ||
363 | struct i915_hw_context *to, | ||
364 | u32 seqno) | ||
365 | { | ||
366 | struct intel_ring_buffer *ring = NULL; | ||
367 | u32 hw_flags = 0; | ||
368 | int ret; | ||
369 | |||
370 | BUG_ON(to == NULL); | ||
371 | BUG_ON(from_obj != NULL && from_obj->pin_count == 0); | ||
372 | |||
373 | ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false); | ||
374 | if (ret) | ||
375 | return ret; | ||
376 | |||
377 | /* Clear this page out of any CPU caches for coherent swap-in/out. Note | ||
378 | * that thanks to write = false in this call and us not setting any gpu | ||
379 | * write domains when putting a context object onto the active list | ||
380 | * (when switching away from it), this won't block. | ||
381 | * XXX: We need a real interface to do this instead of trickery. */ | ||
382 | ret = i915_gem_object_set_to_gtt_domain(to->obj, false); | ||
383 | if (ret) { | ||
384 | i915_gem_object_unpin(to->obj); | ||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | if (!to->obj->has_global_gtt_mapping) | ||
389 | i915_gem_gtt_bind_object(to->obj, to->obj->cache_level); | ||
390 | |||
391 | if (!to->is_initialized || is_default_context(to)) | ||
392 | hw_flags |= MI_RESTORE_INHIBIT; | ||
393 | else if (WARN_ON_ONCE(from_obj == to->obj)) /* not yet expected */ | ||
394 | hw_flags |= MI_FORCE_RESTORE; | ||
395 | |||
396 | ring = to->ring; | ||
397 | ret = mi_set_context(ring, to, hw_flags); | ||
398 | if (ret) { | ||
399 | i915_gem_object_unpin(to->obj); | ||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | /* The backing object for the context is done after switching to the | ||
404 | * *next* context. Therefore we cannot retire the previous context until | ||
405 | * the next context has already started running. In fact, the below code | ||
406 | * is a bit suboptimal because the retiring can occur simply after the | ||
407 | * MI_SET_CONTEXT instead of when the next seqno has completed. | ||
408 | */ | ||
409 | if (from_obj != NULL) { | ||
410 | from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; | ||
411 | i915_gem_object_move_to_active(from_obj, ring, seqno); | ||
412 | /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the | ||
413 | * whole damn pipeline, we don't need to explicitly mark the | ||
414 | * object dirty. The only exception is that the context must be | ||
415 | * correct in case the object gets swapped out. Ideally we'd be | ||
416 | * able to defer doing this until we know the object would be | ||
417 | * swapped, but there is no way to do that yet. | ||
418 | */ | ||
419 | from_obj->dirty = 1; | ||
420 | BUG_ON(from_obj->ring != to->ring); | ||
421 | i915_gem_object_unpin(from_obj); | ||
422 | |||
423 | drm_gem_object_unreference(&from_obj->base); | ||
424 | } | ||
425 | |||
426 | drm_gem_object_reference(&to->obj->base); | ||
427 | ring->last_context_obj = to->obj; | ||
428 | to->is_initialized = true; | ||
429 | |||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * i915_switch_context() - perform a GPU context switch. | ||
435 | * @ring: ring for which we'll execute the context switch | ||
436 | * @file_priv: file_priv associated with the context, may be NULL | ||
437 | * @id: context id number | ||
438 | * @seqno: sequence number by which the new context will be switched to | ||
439 | * @flags: | ||
440 | * | ||
441 | * The context life cycle is simple. The context refcount is incremented and | ||
442 | * decremented by 1 and create and destroy. If the context is in use by the GPU, | ||
443 | * it will have a refoucnt > 1. This allows us to destroy the context abstract | ||
444 | * object while letting the normal object tracking destroy the backing BO. | ||
445 | */ | ||
446 | int i915_switch_context(struct intel_ring_buffer *ring, | ||
447 | struct drm_file *file, | ||
448 | int to_id) | ||
449 | { | ||
450 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
451 | struct drm_i915_file_private *file_priv = NULL; | ||
452 | struct i915_hw_context *to; | ||
453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; | ||
454 | int ret; | ||
455 | |||
456 | if (dev_priv->hw_contexts_disabled) | ||
457 | return 0; | ||
458 | |||
459 | if (ring != &dev_priv->ring[RCS]) | ||
460 | return 0; | ||
461 | |||
462 | if (file) | ||
463 | file_priv = file->driver_priv; | ||
464 | |||
465 | if (to_id == DEFAULT_CONTEXT_ID) { | ||
466 | to = ring->default_context; | ||
467 | } else { | ||
468 | to = i915_gem_context_get(file_priv, to_id); | ||
469 | if (to == NULL) | ||
470 | return -ENOENT; | ||
471 | } | ||
472 | |||
473 | if (from_obj == to->obj) | ||
474 | return 0; | ||
475 | |||
476 | return do_switch(from_obj, to, i915_gem_next_request_seqno(to->ring)); | ||
477 | } | ||
478 | |||
479 | int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, | ||
480 | struct drm_file *file) | ||
481 | { | ||
482 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
483 | struct drm_i915_gem_context_create *args = data; | ||
484 | struct drm_i915_file_private *file_priv = file->driver_priv; | ||
485 | struct i915_hw_context *ctx; | ||
486 | int ret; | ||
487 | |||
488 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
489 | return -ENODEV; | ||
490 | |||
491 | if (dev_priv->hw_contexts_disabled) | ||
492 | return -ENODEV; | ||
493 | |||
494 | ret = i915_mutex_lock_interruptible(dev); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | |||
498 | ctx = create_hw_context(dev, file_priv); | ||
499 | mutex_unlock(&dev->struct_mutex); | ||
500 | if (IS_ERR(ctx)) | ||
501 | return PTR_ERR(ctx); | ||
502 | |||
503 | args->ctx_id = ctx->id; | ||
504 | DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); | ||
505 | |||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, | ||
510 | struct drm_file *file) | ||
511 | { | ||
512 | struct drm_i915_gem_context_destroy *args = data; | ||
513 | struct drm_i915_file_private *file_priv = file->driver_priv; | ||
514 | struct i915_hw_context *ctx; | ||
515 | int ret; | ||
516 | |||
517 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
518 | return -ENODEV; | ||
519 | |||
520 | ret = i915_mutex_lock_interruptible(dev); | ||
521 | if (ret) | ||
522 | return ret; | ||
523 | |||
524 | ctx = i915_gem_context_get(file_priv, args->ctx_id); | ||
525 | if (!ctx) { | ||
526 | mutex_unlock(&dev->struct_mutex); | ||
527 | return -ENOENT; | ||
528 | } | ||
529 | |||
530 | do_destroy(ctx); | ||
531 | |||
532 | mutex_unlock(&dev->struct_mutex); | ||
533 | |||
534 | DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id); | ||
535 | return 0; | ||
536 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index a4f6aaabca99..bddf7bed183f 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -132,7 +132,8 @@ i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle) | |||
132 | __func__, obj, obj->gtt_offset, handle, | 132 | __func__, obj, obj->gtt_offset, handle, |
133 | obj->size / 1024); | 133 | obj->size / 1024); |
134 | 134 | ||
135 | gtt_mapping = ioremap(dev->agp->base + obj->gtt_offset, obj->base.size); | 135 | gtt_mapping = ioremap(dev_priv->mm.gtt_base_addr + obj->gtt_offset, |
136 | obj->base.size); | ||
136 | if (gtt_mapping == NULL) { | 137 | if (gtt_mapping == NULL) { |
137 | DRM_ERROR("failed to map GTT space\n"); | 138 | DRM_ERROR("failed to map GTT space\n"); |
138 | return; | 139 | return; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index ae7c24e12e52..eba0308f10e3 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -78,11 +78,12 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, | |||
78 | 78 | ||
79 | INIT_LIST_HEAD(&unwind_list); | 79 | INIT_LIST_HEAD(&unwind_list); |
80 | if (mappable) | 80 | if (mappable) |
81 | drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size, | 81 | drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, |
82 | alignment, 0, | 82 | min_size, alignment, 0, |
83 | dev_priv->mm.gtt_mappable_end); | 83 | 0, dev_priv->mm.gtt_mappable_end); |
84 | else | 84 | else |
85 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | 85 | drm_mm_init_scan(&dev_priv->mm.gtt_space, |
86 | min_size, alignment, 0); | ||
86 | 87 | ||
87 | /* First see if there is a large enough contiguous idle region... */ | 88 | /* First see if there is a large enough contiguous idle region... */ |
88 | list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { | 89 | list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 974a9f1068a3..5af631e788c8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -810,33 +810,16 @@ err: | |||
810 | return ret; | 810 | return ret; |
811 | } | 811 | } |
812 | 812 | ||
813 | static int | 813 | static void |
814 | i915_gem_execbuffer_flush(struct drm_device *dev, | 814 | i915_gem_execbuffer_flush(struct drm_device *dev, |
815 | uint32_t invalidate_domains, | 815 | uint32_t invalidate_domains, |
816 | uint32_t flush_domains, | 816 | uint32_t flush_domains) |
817 | uint32_t flush_rings) | ||
818 | { | 817 | { |
819 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
820 | int i, ret; | ||
821 | |||
822 | if (flush_domains & I915_GEM_DOMAIN_CPU) | 818 | if (flush_domains & I915_GEM_DOMAIN_CPU) |
823 | intel_gtt_chipset_flush(); | 819 | intel_gtt_chipset_flush(); |
824 | 820 | ||
825 | if (flush_domains & I915_GEM_DOMAIN_GTT) | 821 | if (flush_domains & I915_GEM_DOMAIN_GTT) |
826 | wmb(); | 822 | wmb(); |
827 | |||
828 | if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { | ||
829 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
830 | if (flush_rings & (1 << i)) { | ||
831 | ret = i915_gem_flush_ring(&dev_priv->ring[i], | ||
832 | invalidate_domains, | ||
833 | flush_domains); | ||
834 | if (ret) | ||
835 | return ret; | ||
836 | } | ||
837 | } | ||
838 | |||
839 | return 0; | ||
840 | } | 823 | } |
841 | 824 | ||
842 | static int | 825 | static int |
@@ -885,12 +868,9 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | |||
885 | i915_gem_object_set_to_gpu_domain(obj, ring, &cd); | 868 | i915_gem_object_set_to_gpu_domain(obj, ring, &cd); |
886 | 869 | ||
887 | if (cd.invalidate_domains | cd.flush_domains) { | 870 | if (cd.invalidate_domains | cd.flush_domains) { |
888 | ret = i915_gem_execbuffer_flush(ring->dev, | 871 | i915_gem_execbuffer_flush(ring->dev, |
889 | cd.invalidate_domains, | 872 | cd.invalidate_domains, |
890 | cd.flush_domains, | 873 | cd.flush_domains); |
891 | cd.flush_rings); | ||
892 | if (ret) | ||
893 | return ret; | ||
894 | } | 874 | } |
895 | 875 | ||
896 | if (cd.flips) { | 876 | if (cd.flips) { |
@@ -905,6 +885,16 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | |||
905 | return ret; | 885 | return ret; |
906 | } | 886 | } |
907 | 887 | ||
888 | /* Unconditionally invalidate gpu caches and ensure that we do flush | ||
889 | * any residual writes from the previous batch. | ||
890 | */ | ||
891 | ret = i915_gem_flush_ring(ring, | ||
892 | I915_GEM_GPU_DOMAINS, | ||
893 | ring->gpu_caches_dirty ? I915_GEM_GPU_DOMAINS : 0); | ||
894 | if (ret) | ||
895 | return ret; | ||
896 | |||
897 | ring->gpu_caches_dirty = false; | ||
908 | return 0; | 898 | return 0; |
909 | } | 899 | } |
910 | 900 | ||
@@ -983,26 +973,13 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, | |||
983 | struct intel_ring_buffer *ring) | 973 | struct intel_ring_buffer *ring) |
984 | { | 974 | { |
985 | struct drm_i915_gem_request *request; | 975 | struct drm_i915_gem_request *request; |
986 | u32 invalidate; | ||
987 | 976 | ||
988 | /* | 977 | /* Unconditionally force add_request to emit a full flush. */ |
989 | * Ensure that the commands in the batch buffer are | 978 | ring->gpu_caches_dirty = true; |
990 | * finished before the interrupt fires. | ||
991 | * | ||
992 | * The sampler always gets flushed on i965 (sigh). | ||
993 | */ | ||
994 | invalidate = I915_GEM_DOMAIN_COMMAND; | ||
995 | if (INTEL_INFO(dev)->gen >= 4) | ||
996 | invalidate |= I915_GEM_DOMAIN_SAMPLER; | ||
997 | if (ring->flush(ring, invalidate, 0)) { | ||
998 | i915_gem_next_request_seqno(ring); | ||
999 | return; | ||
1000 | } | ||
1001 | 979 | ||
1002 | /* Add a breadcrumb for the completion of the batch buffer */ | 980 | /* Add a breadcrumb for the completion of the batch buffer */ |
1003 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 981 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
1004 | if (request == NULL || i915_add_request(ring, file, request)) { | 982 | if (request == NULL || i915_add_request(ring, file, request)) { |
1005 | i915_gem_next_request_seqno(ring); | ||
1006 | kfree(request); | 983 | kfree(request); |
1007 | } | 984 | } |
1008 | } | 985 | } |
@@ -1044,6 +1021,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1044 | struct drm_i915_gem_object *batch_obj; | 1021 | struct drm_i915_gem_object *batch_obj; |
1045 | struct drm_clip_rect *cliprects = NULL; | 1022 | struct drm_clip_rect *cliprects = NULL; |
1046 | struct intel_ring_buffer *ring; | 1023 | struct intel_ring_buffer *ring; |
1024 | u32 ctx_id = i915_execbuffer2_get_context_id(*args); | ||
1047 | u32 exec_start, exec_len; | 1025 | u32 exec_start, exec_len; |
1048 | u32 seqno; | 1026 | u32 seqno; |
1049 | u32 mask; | 1027 | u32 mask; |
@@ -1065,9 +1043,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1065 | break; | 1043 | break; |
1066 | case I915_EXEC_BSD: | 1044 | case I915_EXEC_BSD: |
1067 | ring = &dev_priv->ring[VCS]; | 1045 | ring = &dev_priv->ring[VCS]; |
1046 | if (ctx_id != 0) { | ||
1047 | DRM_DEBUG("Ring %s doesn't support contexts\n", | ||
1048 | ring->name); | ||
1049 | return -EPERM; | ||
1050 | } | ||
1068 | break; | 1051 | break; |
1069 | case I915_EXEC_BLT: | 1052 | case I915_EXEC_BLT: |
1070 | ring = &dev_priv->ring[BCS]; | 1053 | ring = &dev_priv->ring[BCS]; |
1054 | if (ctx_id != 0) { | ||
1055 | DRM_DEBUG("Ring %s doesn't support contexts\n", | ||
1056 | ring->name); | ||
1057 | return -EPERM; | ||
1058 | } | ||
1071 | break; | 1059 | break; |
1072 | default: | 1060 | default: |
1073 | DRM_DEBUG("execbuf with unknown ring: %d\n", | 1061 | DRM_DEBUG("execbuf with unknown ring: %d\n", |
@@ -1240,6 +1228,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1240 | } | 1228 | } |
1241 | } | 1229 | } |
1242 | 1230 | ||
1231 | ret = i915_switch_context(ring, file, ctx_id); | ||
1232 | if (ret) | ||
1233 | goto err; | ||
1234 | |||
1243 | if (ring == &dev_priv->ring[RCS] && | 1235 | if (ring == &dev_priv->ring[RCS] && |
1244 | mode != dev_priv->relative_constants_mode) { | 1236 | mode != dev_priv->relative_constants_mode) { |
1245 | ret = intel_ring_begin(ring, 4); | 1237 | ret = intel_ring_begin(ring, 4); |
@@ -1367,6 +1359,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
1367 | exec2.num_cliprects = args->num_cliprects; | 1359 | exec2.num_cliprects = args->num_cliprects; |
1368 | exec2.cliprects_ptr = args->cliprects_ptr; | 1360 | exec2.cliprects_ptr = args->cliprects_ptr; |
1369 | exec2.flags = I915_EXEC_RENDER; | 1361 | exec2.flags = I915_EXEC_RENDER; |
1362 | i915_execbuffer2_set_context_id(exec2, 0); | ||
1370 | 1363 | ||
1371 | ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); | 1364 | ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); |
1372 | if (!ret) { | 1365 | if (!ret) { |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ed3224c37423..8a3828528b9d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -375,6 +375,86 @@ static void gen6_pm_rps_work(struct work_struct *work) | |||
375 | mutex_unlock(&dev_priv->dev->struct_mutex); | 375 | mutex_unlock(&dev_priv->dev->struct_mutex); |
376 | } | 376 | } |
377 | 377 | ||
378 | |||
379 | /** | ||
380 | * ivybridge_parity_work - Workqueue called when a parity error interrupt | ||
381 | * occurred. | ||
382 | * @work: workqueue struct | ||
383 | * | ||
384 | * Doesn't actually do anything except notify userspace. As a consequence of | ||
385 | * this event, userspace should try to remap the bad rows since statistically | ||
386 | * it is likely the same row is more likely to go bad again. | ||
387 | */ | ||
388 | static void ivybridge_parity_work(struct work_struct *work) | ||
389 | { | ||
390 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
391 | parity_error_work); | ||
392 | u32 error_status, row, bank, subbank; | ||
393 | char *parity_event[5]; | ||
394 | uint32_t misccpctl; | ||
395 | unsigned long flags; | ||
396 | |||
397 | /* We must turn off DOP level clock gating to access the L3 registers. | ||
398 | * In order to prevent a get/put style interface, acquire struct mutex | ||
399 | * any time we access those registers. | ||
400 | */ | ||
401 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
402 | |||
403 | misccpctl = I915_READ(GEN7_MISCCPCTL); | ||
404 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); | ||
405 | POSTING_READ(GEN7_MISCCPCTL); | ||
406 | |||
407 | error_status = I915_READ(GEN7_L3CDERRST1); | ||
408 | row = GEN7_PARITY_ERROR_ROW(error_status); | ||
409 | bank = GEN7_PARITY_ERROR_BANK(error_status); | ||
410 | subbank = GEN7_PARITY_ERROR_SUBBANK(error_status); | ||
411 | |||
412 | I915_WRITE(GEN7_L3CDERRST1, GEN7_PARITY_ERROR_VALID | | ||
413 | GEN7_L3CDERRST1_ENABLE); | ||
414 | POSTING_READ(GEN7_L3CDERRST1); | ||
415 | |||
416 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | ||
417 | |||
418 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
419 | dev_priv->gt_irq_mask &= ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT; | ||
420 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
421 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | ||
422 | |||
423 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
424 | |||
425 | parity_event[0] = "L3_PARITY_ERROR=1"; | ||
426 | parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row); | ||
427 | parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank); | ||
428 | parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank); | ||
429 | parity_event[4] = NULL; | ||
430 | |||
431 | kobject_uevent_env(&dev_priv->dev->primary->kdev.kobj, | ||
432 | KOBJ_CHANGE, parity_event); | ||
433 | |||
434 | DRM_DEBUG("Parity error: Row = %d, Bank = %d, Sub bank = %d.\n", | ||
435 | row, bank, subbank); | ||
436 | |||
437 | kfree(parity_event[3]); | ||
438 | kfree(parity_event[2]); | ||
439 | kfree(parity_event[1]); | ||
440 | } | ||
441 | |||
442 | static void ivybridge_handle_parity_error(struct drm_device *dev) | ||
443 | { | ||
444 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
445 | unsigned long flags; | ||
446 | |||
447 | if (!IS_IVYBRIDGE(dev)) | ||
448 | return; | ||
449 | |||
450 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
451 | dev_priv->gt_irq_mask |= GT_GEN7_L3_PARITY_ERROR_INTERRUPT; | ||
452 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
453 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | ||
454 | |||
455 | queue_work(dev_priv->wq, &dev_priv->parity_error_work); | ||
456 | } | ||
457 | |||
378 | static void snb_gt_irq_handler(struct drm_device *dev, | 458 | static void snb_gt_irq_handler(struct drm_device *dev, |
379 | struct drm_i915_private *dev_priv, | 459 | struct drm_i915_private *dev_priv, |
380 | u32 gt_iir) | 460 | u32 gt_iir) |
@@ -394,6 +474,9 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
394 | DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); | 474 | DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); |
395 | i915_handle_error(dev, false); | 475 | i915_handle_error(dev, false); |
396 | } | 476 | } |
477 | |||
478 | if (gt_iir & GT_GEN7_L3_PARITY_ERROR_INTERRUPT) | ||
479 | ivybridge_handle_parity_error(dev); | ||
397 | } | 480 | } |
398 | 481 | ||
399 | static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, | 482 | static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, |
@@ -429,15 +512,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) | |||
429 | unsigned long irqflags; | 512 | unsigned long irqflags; |
430 | int pipe; | 513 | int pipe; |
431 | u32 pipe_stats[I915_MAX_PIPES]; | 514 | u32 pipe_stats[I915_MAX_PIPES]; |
432 | u32 vblank_status; | ||
433 | int vblank = 0; | ||
434 | bool blc_event; | 515 | bool blc_event; |
435 | 516 | ||
436 | atomic_inc(&dev_priv->irq_received); | 517 | atomic_inc(&dev_priv->irq_received); |
437 | 518 | ||
438 | vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS | | ||
439 | PIPE_VBLANK_INTERRUPT_STATUS; | ||
440 | |||
441 | while (true) { | 519 | while (true) { |
442 | iir = I915_READ(VLV_IIR); | 520 | iir = I915_READ(VLV_IIR); |
443 | gt_iir = I915_READ(GTIIR); | 521 | gt_iir = I915_READ(GTIIR); |
@@ -467,6 +545,16 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) | |||
467 | } | 545 | } |
468 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 546 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
469 | 547 | ||
548 | for_each_pipe(pipe) { | ||
549 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) | ||
550 | drm_handle_vblank(dev, pipe); | ||
551 | |||
552 | if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { | ||
553 | intel_prepare_page_flip(dev, pipe); | ||
554 | intel_finish_page_flip(dev, pipe); | ||
555 | } | ||
556 | } | ||
557 | |||
470 | /* Consume port. Then clear IIR or we'll miss events */ | 558 | /* Consume port. Then clear IIR or we'll miss events */ |
471 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { | 559 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
472 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); | 560 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
@@ -481,19 +569,6 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) | |||
481 | I915_READ(PORT_HOTPLUG_STAT); | 569 | I915_READ(PORT_HOTPLUG_STAT); |
482 | } | 570 | } |
483 | 571 | ||
484 | |||
485 | if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) { | ||
486 | drm_handle_vblank(dev, 0); | ||
487 | vblank++; | ||
488 | intel_finish_page_flip(dev, 0); | ||
489 | } | ||
490 | |||
491 | if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) { | ||
492 | drm_handle_vblank(dev, 1); | ||
493 | vblank++; | ||
494 | intel_finish_page_flip(dev, 0); | ||
495 | } | ||
496 | |||
497 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) | 572 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
498 | blc_event = true; | 573 | blc_event = true; |
499 | 574 | ||
@@ -991,6 +1066,7 @@ static void i915_record_ring_state(struct drm_device *dev, | |||
991 | struct drm_i915_private *dev_priv = dev->dev_private; | 1066 | struct drm_i915_private *dev_priv = dev->dev_private; |
992 | 1067 | ||
993 | if (INTEL_INFO(dev)->gen >= 6) { | 1068 | if (INTEL_INFO(dev)->gen >= 6) { |
1069 | error->rc_psmi[ring->id] = I915_READ(ring->mmio_base + 0x50); | ||
994 | error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); | 1070 | error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); |
995 | error->semaphore_mboxes[ring->id][0] | 1071 | error->semaphore_mboxes[ring->id][0] |
996 | = I915_READ(RING_SYNC_0(ring->mmio_base)); | 1072 | = I915_READ(RING_SYNC_0(ring->mmio_base)); |
@@ -1104,6 +1180,7 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
1104 | kref_init(&error->ref); | 1180 | kref_init(&error->ref); |
1105 | error->eir = I915_READ(EIR); | 1181 | error->eir = I915_READ(EIR); |
1106 | error->pgtbl_er = I915_READ(PGTBL_ER); | 1182 | error->pgtbl_er = I915_READ(PGTBL_ER); |
1183 | error->ccid = I915_READ(CCID); | ||
1107 | 1184 | ||
1108 | if (HAS_PCH_SPLIT(dev)) | 1185 | if (HAS_PCH_SPLIT(dev)) |
1109 | error->ier = I915_READ(DEIER) | I915_READ(GTIER); | 1186 | error->ier = I915_READ(DEIER) | I915_READ(GTIER); |
@@ -1426,23 +1503,20 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe) | |||
1426 | { | 1503 | { |
1427 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1504 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1428 | unsigned long irqflags; | 1505 | unsigned long irqflags; |
1429 | u32 dpfl, imr; | 1506 | u32 imr; |
1430 | 1507 | ||
1431 | if (!i915_pipe_enabled(dev, pipe)) | 1508 | if (!i915_pipe_enabled(dev, pipe)) |
1432 | return -EINVAL; | 1509 | return -EINVAL; |
1433 | 1510 | ||
1434 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 1511 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1435 | dpfl = I915_READ(VLV_DPFLIPSTAT); | ||
1436 | imr = I915_READ(VLV_IMR); | 1512 | imr = I915_READ(VLV_IMR); |
1437 | if (pipe == 0) { | 1513 | if (pipe == 0) |
1438 | dpfl |= PIPEA_VBLANK_INT_EN; | ||
1439 | imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; | 1514 | imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; |
1440 | } else { | 1515 | else |
1441 | dpfl |= PIPEA_VBLANK_INT_EN; | ||
1442 | imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | 1516 | imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
1443 | } | ||
1444 | I915_WRITE(VLV_DPFLIPSTAT, dpfl); | ||
1445 | I915_WRITE(VLV_IMR, imr); | 1517 | I915_WRITE(VLV_IMR, imr); |
1518 | i915_enable_pipestat(dev_priv, pipe, | ||
1519 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | ||
1446 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1520 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1447 | 1521 | ||
1448 | return 0; | 1522 | return 0; |
@@ -1492,20 +1566,17 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) | |||
1492 | { | 1566 | { |
1493 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1567 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1494 | unsigned long irqflags; | 1568 | unsigned long irqflags; |
1495 | u32 dpfl, imr; | 1569 | u32 imr; |
1496 | 1570 | ||
1497 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 1571 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1498 | dpfl = I915_READ(VLV_DPFLIPSTAT); | 1572 | i915_disable_pipestat(dev_priv, pipe, |
1573 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | ||
1499 | imr = I915_READ(VLV_IMR); | 1574 | imr = I915_READ(VLV_IMR); |
1500 | if (pipe == 0) { | 1575 | if (pipe == 0) |
1501 | dpfl &= ~PIPEA_VBLANK_INT_EN; | ||
1502 | imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; | 1576 | imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; |
1503 | } else { | 1577 | else |
1504 | dpfl &= ~PIPEB_VBLANK_INT_EN; | ||
1505 | imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | 1578 | imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
1506 | } | ||
1507 | I915_WRITE(VLV_IMR, imr); | 1579 | I915_WRITE(VLV_IMR, imr); |
1508 | I915_WRITE(VLV_DPFLIPSTAT, dpfl); | ||
1509 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1580 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1510 | } | 1581 | } |
1511 | 1582 | ||
@@ -1648,7 +1719,6 @@ static void ironlake_irq_preinstall(struct drm_device *dev) | |||
1648 | 1719 | ||
1649 | atomic_set(&dev_priv->irq_received, 0); | 1720 | atomic_set(&dev_priv->irq_received, 0); |
1650 | 1721 | ||
1651 | |||
1652 | I915_WRITE(HWSTAM, 0xeffe); | 1722 | I915_WRITE(HWSTAM, 0xeffe); |
1653 | 1723 | ||
1654 | /* XXX hotplug from PCH */ | 1724 | /* XXX hotplug from PCH */ |
@@ -1811,13 +1881,13 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) | |||
1811 | DE_PIPEA_VBLANK_IVB); | 1881 | DE_PIPEA_VBLANK_IVB); |
1812 | POSTING_READ(DEIER); | 1882 | POSTING_READ(DEIER); |
1813 | 1883 | ||
1814 | dev_priv->gt_irq_mask = ~0; | 1884 | dev_priv->gt_irq_mask = ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT; |
1815 | 1885 | ||
1816 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1886 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1817 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 1887 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
1818 | 1888 | ||
1819 | render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT | | 1889 | render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT | |
1820 | GEN6_BLITTER_USER_INTERRUPT; | 1890 | GEN6_BLITTER_USER_INTERRUPT | GT_GEN7_L3_PARITY_ERROR_INTERRUPT; |
1821 | I915_WRITE(GTIER, render_irqs); | 1891 | I915_WRITE(GTIER, render_irqs); |
1822 | POSTING_READ(GTIER); | 1892 | POSTING_READ(GTIER); |
1823 | 1893 | ||
@@ -1840,16 +1910,24 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) | |||
1840 | static int valleyview_irq_postinstall(struct drm_device *dev) | 1910 | static int valleyview_irq_postinstall(struct drm_device *dev) |
1841 | { | 1911 | { |
1842 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1912 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1843 | u32 render_irqs; | ||
1844 | u32 enable_mask; | 1913 | u32 enable_mask; |
1845 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 1914 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
1915 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; | ||
1846 | u16 msid; | 1916 | u16 msid; |
1847 | 1917 | ||
1848 | enable_mask = I915_DISPLAY_PORT_INTERRUPT; | 1918 | enable_mask = I915_DISPLAY_PORT_INTERRUPT; |
1849 | enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | | 1919 | enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
1920 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | | ||
1921 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | | ||
1850 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | 1922 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
1851 | 1923 | ||
1852 | dev_priv->irq_mask = ~enable_mask; | 1924 | /* |
1925 | *Leave vblank interrupts masked initially. enable/disable will | ||
1926 | * toggle them based on usage. | ||
1927 | */ | ||
1928 | dev_priv->irq_mask = (~enable_mask) | | ||
1929 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | | ||
1930 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
1853 | 1931 | ||
1854 | dev_priv->pipestat[0] = 0; | 1932 | dev_priv->pipestat[0] = 0; |
1855 | dev_priv->pipestat[1] = 0; | 1933 | dev_priv->pipestat[1] = 0; |
@@ -1868,26 +1946,27 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
1868 | I915_WRITE(PIPESTAT(1), 0xffff); | 1946 | I915_WRITE(PIPESTAT(1), 0xffff); |
1869 | POSTING_READ(VLV_IER); | 1947 | POSTING_READ(VLV_IER); |
1870 | 1948 | ||
1949 | i915_enable_pipestat(dev_priv, 0, pipestat_enable); | ||
1950 | i915_enable_pipestat(dev_priv, 1, pipestat_enable); | ||
1951 | |||
1871 | I915_WRITE(VLV_IIR, 0xffffffff); | 1952 | I915_WRITE(VLV_IIR, 0xffffffff); |
1872 | I915_WRITE(VLV_IIR, 0xffffffff); | 1953 | I915_WRITE(VLV_IIR, 0xffffffff); |
1873 | 1954 | ||
1874 | render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT | | 1955 | dev_priv->gt_irq_mask = ~0; |
1875 | GT_GEN6_BLT_CS_ERROR_INTERRUPT | | ||
1876 | GT_GEN6_BLT_USER_INTERRUPT | | ||
1877 | GT_GEN6_BSD_USER_INTERRUPT | | ||
1878 | GT_GEN6_BSD_CS_ERROR_INTERRUPT | | ||
1879 | GT_GEN7_L3_PARITY_ERROR_INTERRUPT | | ||
1880 | GT_PIPE_NOTIFY | | ||
1881 | GT_RENDER_CS_ERROR_INTERRUPT | | ||
1882 | GT_SYNC_STATUS | | ||
1883 | GT_USER_INTERRUPT; | ||
1884 | |||
1885 | dev_priv->gt_irq_mask = ~render_irqs; | ||
1886 | 1956 | ||
1887 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1957 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1888 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1958 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1889 | I915_WRITE(GTIMR, 0); | 1959 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
1890 | I915_WRITE(GTIER, render_irqs); | 1960 | I915_WRITE(GTIER, GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT | |
1961 | GT_GEN6_BLT_CS_ERROR_INTERRUPT | | ||
1962 | GT_GEN6_BLT_USER_INTERRUPT | | ||
1963 | GT_GEN6_BSD_USER_INTERRUPT | | ||
1964 | GT_GEN6_BSD_CS_ERROR_INTERRUPT | | ||
1965 | GT_GEN7_L3_PARITY_ERROR_INTERRUPT | | ||
1966 | GT_PIPE_NOTIFY | | ||
1967 | GT_RENDER_CS_ERROR_INTERRUPT | | ||
1968 | GT_SYNC_STATUS | | ||
1969 | GT_USER_INTERRUPT); | ||
1891 | POSTING_READ(GTIER); | 1970 | POSTING_READ(GTIER); |
1892 | 1971 | ||
1893 | /* ack & enable invalid PTE error interrupts */ | 1972 | /* ack & enable invalid PTE error interrupts */ |
@@ -2166,9 +2245,9 @@ static int i915_irq_postinstall(struct drm_device *dev) | |||
2166 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | 2245 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; |
2167 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | 2246 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) |
2168 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | 2247 | hotplug_en |= HDMID_HOTPLUG_INT_EN; |
2169 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | 2248 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) |
2170 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | 2249 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
2171 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | 2250 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915) |
2172 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | 2251 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
2173 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | 2252 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { |
2174 | hotplug_en |= CRT_HOTPLUG_INT_EN; | 2253 | hotplug_en |= CRT_HOTPLUG_INT_EN; |
@@ -2328,10 +2407,8 @@ static void i965_irq_preinstall(struct drm_device * dev) | |||
2328 | 2407 | ||
2329 | atomic_set(&dev_priv->irq_received, 0); | 2408 | atomic_set(&dev_priv->irq_received, 0); |
2330 | 2409 | ||
2331 | if (I915_HAS_HOTPLUG(dev)) { | 2410 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
2332 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 2411 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
2333 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | ||
2334 | } | ||
2335 | 2412 | ||
2336 | I915_WRITE(HWSTAM, 0xeffe); | 2413 | I915_WRITE(HWSTAM, 0xeffe); |
2337 | for_each_pipe(pipe) | 2414 | for_each_pipe(pipe) |
@@ -2344,11 +2421,13 @@ static void i965_irq_preinstall(struct drm_device * dev) | |||
2344 | static int i965_irq_postinstall(struct drm_device *dev) | 2421 | static int i965_irq_postinstall(struct drm_device *dev) |
2345 | { | 2422 | { |
2346 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2423 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2424 | u32 hotplug_en; | ||
2347 | u32 enable_mask; | 2425 | u32 enable_mask; |
2348 | u32 error_mask; | 2426 | u32 error_mask; |
2349 | 2427 | ||
2350 | /* Unmask the interrupts that we always want on. */ | 2428 | /* Unmask the interrupts that we always want on. */ |
2351 | dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | | 2429 | dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | |
2430 | I915_DISPLAY_PORT_INTERRUPT | | ||
2352 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | | 2431 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
2353 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | | 2432 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | |
2354 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | | 2433 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
@@ -2364,13 +2443,6 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
2364 | dev_priv->pipestat[0] = 0; | 2443 | dev_priv->pipestat[0] = 0; |
2365 | dev_priv->pipestat[1] = 0; | 2444 | dev_priv->pipestat[1] = 0; |
2366 | 2445 | ||
2367 | if (I915_HAS_HOTPLUG(dev)) { | ||
2368 | /* Enable in IER... */ | ||
2369 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | ||
2370 | /* and unmask in IMR */ | ||
2371 | dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; | ||
2372 | } | ||
2373 | |||
2374 | /* | 2446 | /* |
2375 | * Enable some error detection, note the instruction error mask | 2447 | * Enable some error detection, note the instruction error mask |
2376 | * bit is reserved, so we leave it masked. | 2448 | * bit is reserved, so we leave it masked. |
@@ -2390,36 +2462,40 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
2390 | I915_WRITE(IER, enable_mask); | 2462 | I915_WRITE(IER, enable_mask); |
2391 | POSTING_READ(IER); | 2463 | POSTING_READ(IER); |
2392 | 2464 | ||
2393 | if (I915_HAS_HOTPLUG(dev)) { | 2465 | /* Note HDMI and DP share hotplug bits */ |
2394 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 2466 | hotplug_en = 0; |
2395 | 2467 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | |
2396 | /* Note HDMI and DP share bits */ | 2468 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; |
2397 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | 2469 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) |
2398 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | 2470 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; |
2399 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | 2471 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) |
2400 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | 2472 | hotplug_en |= HDMID_HOTPLUG_INT_EN; |
2401 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | 2473 | if (IS_G4X(dev)) { |
2402 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | 2474 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X) |
2403 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
2404 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | 2475 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
2405 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | 2476 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_G4X) |
2406 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | 2477 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
2407 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | 2478 | } else { |
2408 | hotplug_en |= CRT_HOTPLUG_INT_EN; | 2479 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I965) |
2480 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
2481 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I965) | ||
2482 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
2483 | } | ||
2484 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | ||
2485 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
2409 | 2486 | ||
2410 | /* Programming the CRT detection parameters tends | 2487 | /* Programming the CRT detection parameters tends |
2411 | to generate a spurious hotplug event about three | 2488 | to generate a spurious hotplug event about three |
2412 | seconds later. So just do it once. | 2489 | seconds later. So just do it once. |
2413 | */ | 2490 | */ |
2414 | if (IS_G4X(dev)) | 2491 | if (IS_G4X(dev)) |
2415 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; | 2492 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; |
2416 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; | 2493 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; |
2417 | } | 2494 | } |
2418 | 2495 | ||
2419 | /* Ignore TV since it's buggy */ | 2496 | /* Ignore TV since it's buggy */ |
2420 | 2497 | ||
2421 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 2498 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
2422 | } | ||
2423 | 2499 | ||
2424 | intel_opregion_enable_asle(dev); | 2500 | intel_opregion_enable_asle(dev); |
2425 | 2501 | ||
@@ -2477,8 +2553,7 @@ static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS) | |||
2477 | ret = IRQ_HANDLED; | 2553 | ret = IRQ_HANDLED; |
2478 | 2554 | ||
2479 | /* Consume port. Then clear IIR or we'll miss events */ | 2555 | /* Consume port. Then clear IIR or we'll miss events */ |
2480 | if ((I915_HAS_HOTPLUG(dev)) && | 2556 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
2481 | (iir & I915_DISPLAY_PORT_INTERRUPT)) { | ||
2482 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); | 2557 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
2483 | 2558 | ||
2484 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", | 2559 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
@@ -2551,10 +2626,8 @@ static void i965_irq_uninstall(struct drm_device * dev) | |||
2551 | if (!dev_priv) | 2626 | if (!dev_priv) |
2552 | return; | 2627 | return; |
2553 | 2628 | ||
2554 | if (I915_HAS_HOTPLUG(dev)) { | 2629 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
2555 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 2630 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
2556 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | ||
2557 | } | ||
2558 | 2631 | ||
2559 | I915_WRITE(HWSTAM, 0xffffffff); | 2632 | I915_WRITE(HWSTAM, 0xffffffff); |
2560 | for_each_pipe(pipe) | 2633 | for_each_pipe(pipe) |
@@ -2575,6 +2648,7 @@ void intel_irq_init(struct drm_device *dev) | |||
2575 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); | 2648 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); |
2576 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); | 2649 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); |
2577 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 2650 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
2651 | INIT_WORK(&dev_priv->parity_error_work, ivybridge_parity_work); | ||
2578 | 2652 | ||
2579 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 2653 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
2580 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 2654 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 48d5e8e051cf..acc99b21e0b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -217,6 +217,9 @@ | |||
217 | #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) | 217 | #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) |
218 | #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) | 218 | #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) |
219 | #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) | 219 | #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) |
220 | #define MI_ARB_ON_OFF MI_INSTR(0x08, 0) | ||
221 | #define MI_ARB_ENABLE (1<<0) | ||
222 | #define MI_ARB_DISABLE (0<<0) | ||
220 | 223 | ||
221 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) | 224 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) |
222 | #define MI_MM_SPACE_GTT (1<<8) | 225 | #define MI_MM_SPACE_GTT (1<<8) |
@@ -299,6 +302,7 @@ | |||
299 | #define DISPLAY_PLANE_B (1<<20) | 302 | #define DISPLAY_PLANE_B (1<<20) |
300 | #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) | 303 | #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) |
301 | #define PIPE_CONTROL_CS_STALL (1<<20) | 304 | #define PIPE_CONTROL_CS_STALL (1<<20) |
305 | #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) | ||
302 | #define PIPE_CONTROL_QW_WRITE (1<<14) | 306 | #define PIPE_CONTROL_QW_WRITE (1<<14) |
303 | #define PIPE_CONTROL_DEPTH_STALL (1<<13) | 307 | #define PIPE_CONTROL_DEPTH_STALL (1<<13) |
304 | #define PIPE_CONTROL_WRITE_FLUSH (1<<12) | 308 | #define PIPE_CONTROL_WRITE_FLUSH (1<<12) |
@@ -686,10 +690,10 @@ | |||
686 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) | 690 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) |
687 | 691 | ||
688 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 | 692 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 |
689 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK (1 << 16) | 693 | #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) |
690 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE (1 << 0) | 694 | #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) |
691 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 | 695 | #define GEN6_BSD_SLEEP_INDICATOR (1 << 3) |
692 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) | 696 | #define GEN6_BSD_GO_INDICATOR (1 << 4) |
693 | 697 | ||
694 | #define GEN6_BSD_HWSTAM 0x12098 | 698 | #define GEN6_BSD_HWSTAM 0x12098 |
695 | #define GEN6_BSD_IMR 0x120a8 | 699 | #define GEN6_BSD_IMR 0x120a8 |
@@ -908,6 +912,7 @@ | |||
908 | #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ | 912 | #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ |
909 | #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ | 913 | #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ |
910 | #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ | 914 | #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ |
915 | #define DPLL_LOCK_VLV (1<<15) | ||
911 | #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) | 916 | #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) |
912 | 917 | ||
913 | #define SRX_INDEX 0x3c4 | 918 | #define SRX_INDEX 0x3c4 |
@@ -1453,6 +1458,10 @@ | |||
1453 | #define DDRMPLL1 0X12c20 | 1458 | #define DDRMPLL1 0X12c20 |
1454 | #define PEG_BAND_GAP_DATA 0x14d68 | 1459 | #define PEG_BAND_GAP_DATA 0x14d68 |
1455 | 1460 | ||
1461 | #define GEN6_GT_THREAD_STATUS_REG 0x13805c | ||
1462 | #define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7 | ||
1463 | #define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16)) | ||
1464 | |||
1456 | #define GEN6_GT_PERF_STATUS 0x145948 | 1465 | #define GEN6_GT_PERF_STATUS 0x145948 |
1457 | #define GEN6_RP_STATE_LIMITS 0x145994 | 1466 | #define GEN6_RP_STATE_LIMITS 0x145994 |
1458 | #define GEN6_RP_STATE_CAP 0x145998 | 1467 | #define GEN6_RP_STATE_CAP 0x145998 |
@@ -1462,6 +1471,31 @@ | |||
1462 | */ | 1471 | */ |
1463 | #define CCID 0x2180 | 1472 | #define CCID 0x2180 |
1464 | #define CCID_EN (1<<0) | 1473 | #define CCID_EN (1<<0) |
1474 | #define CXT_SIZE 0x21a0 | ||
1475 | #define GEN6_CXT_POWER_SIZE(cxt_reg) ((cxt_reg >> 24) & 0x3f) | ||
1476 | #define GEN6_CXT_RING_SIZE(cxt_reg) ((cxt_reg >> 18) & 0x3f) | ||
1477 | #define GEN6_CXT_RENDER_SIZE(cxt_reg) ((cxt_reg >> 12) & 0x3f) | ||
1478 | #define GEN6_CXT_EXTENDED_SIZE(cxt_reg) ((cxt_reg >> 6) & 0x3f) | ||
1479 | #define GEN6_CXT_PIPELINE_SIZE(cxt_reg) ((cxt_reg >> 0) & 0x3f) | ||
1480 | #define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_POWER_SIZE(cxt_reg) + \ | ||
1481 | GEN6_CXT_RING_SIZE(cxt_reg) + \ | ||
1482 | GEN6_CXT_RENDER_SIZE(cxt_reg) + \ | ||
1483 | GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ | ||
1484 | GEN6_CXT_PIPELINE_SIZE(cxt_reg)) | ||
1485 | #define GEN7_CXT_SIZE 0x21a8 | ||
1486 | #define GEN7_CXT_POWER_SIZE(ctx_reg) ((ctx_reg >> 25) & 0x7f) | ||
1487 | #define GEN7_CXT_RING_SIZE(ctx_reg) ((ctx_reg >> 22) & 0x7) | ||
1488 | #define GEN7_CXT_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f) | ||
1489 | #define GEN7_CXT_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) | ||
1490 | #define GEN7_CXT_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) | ||
1491 | #define GEN7_CXT_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) | ||
1492 | #define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_POWER_SIZE(ctx_reg) + \ | ||
1493 | GEN7_CXT_RING_SIZE(ctx_reg) + \ | ||
1494 | GEN7_CXT_RENDER_SIZE(ctx_reg) + \ | ||
1495 | GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \ | ||
1496 | GEN7_CXT_GT1_SIZE(ctx_reg) + \ | ||
1497 | GEN7_CXT_VFSTATE_SIZE(ctx_reg)) | ||
1498 | |||
1465 | /* | 1499 | /* |
1466 | * Overlay regs | 1500 | * Overlay regs |
1467 | */ | 1501 | */ |
@@ -1566,20 +1600,34 @@ | |||
1566 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1600 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
1567 | 1601 | ||
1568 | #define PORT_HOTPLUG_STAT 0x61114 | 1602 | #define PORT_HOTPLUG_STAT 0x61114 |
1569 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) | 1603 | /* HDMI/DP bits are gen4+ */ |
1570 | #define DPB_HOTPLUG_INT_STATUS (1 << 29) | 1604 | #define DPB_HOTPLUG_LIVE_STATUS (1 << 29) |
1571 | #define HDMIC_HOTPLUG_INT_STATUS (1 << 28) | 1605 | #define DPC_HOTPLUG_LIVE_STATUS (1 << 28) |
1572 | #define DPC_HOTPLUG_INT_STATUS (1 << 28) | 1606 | #define DPD_HOTPLUG_LIVE_STATUS (1 << 27) |
1573 | #define HDMID_HOTPLUG_INT_STATUS (1 << 27) | 1607 | #define DPD_HOTPLUG_INT_STATUS (3 << 21) |
1574 | #define DPD_HOTPLUG_INT_STATUS (1 << 27) | 1608 | #define DPC_HOTPLUG_INT_STATUS (3 << 19) |
1609 | #define DPB_HOTPLUG_INT_STATUS (3 << 17) | ||
1610 | /* HDMI bits are shared with the DP bits */ | ||
1611 | #define HDMIB_HOTPLUG_LIVE_STATUS (1 << 29) | ||
1612 | #define HDMIC_HOTPLUG_LIVE_STATUS (1 << 28) | ||
1613 | #define HDMID_HOTPLUG_LIVE_STATUS (1 << 27) | ||
1614 | #define HDMID_HOTPLUG_INT_STATUS (3 << 21) | ||
1615 | #define HDMIC_HOTPLUG_INT_STATUS (3 << 19) | ||
1616 | #define HDMIB_HOTPLUG_INT_STATUS (3 << 17) | ||
1617 | /* CRT/TV common between gen3+ */ | ||
1575 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) | 1618 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) |
1576 | #define TV_HOTPLUG_INT_STATUS (1 << 10) | 1619 | #define TV_HOTPLUG_INT_STATUS (1 << 10) |
1577 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) | 1620 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) |
1578 | #define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) | 1621 | #define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) |
1579 | #define CRT_HOTPLUG_MONITOR_MONO (2 << 8) | 1622 | #define CRT_HOTPLUG_MONITOR_MONO (2 << 8) |
1580 | #define CRT_HOTPLUG_MONITOR_NONE (0 << 8) | 1623 | #define CRT_HOTPLUG_MONITOR_NONE (0 << 8) |
1581 | #define SDVOC_HOTPLUG_INT_STATUS (1 << 7) | 1624 | /* SDVO is different across gen3/4 */ |
1582 | #define SDVOB_HOTPLUG_INT_STATUS (1 << 6) | 1625 | #define SDVOC_HOTPLUG_INT_STATUS_G4X (1 << 3) |
1626 | #define SDVOB_HOTPLUG_INT_STATUS_G4X (1 << 2) | ||
1627 | #define SDVOC_HOTPLUG_INT_STATUS_I965 (3 << 4) | ||
1628 | #define SDVOB_HOTPLUG_INT_STATUS_I965 (3 << 2) | ||
1629 | #define SDVOC_HOTPLUG_INT_STATUS_I915 (1 << 7) | ||
1630 | #define SDVOB_HOTPLUG_INT_STATUS_I915 (1 << 6) | ||
1583 | 1631 | ||
1584 | /* SDVO port control */ | 1632 | /* SDVO port control */ |
1585 | #define SDVOB 0x61140 | 1633 | #define SDVOB 0x61140 |
@@ -1711,8 +1759,10 @@ | |||
1711 | #define VIDEO_DIP_PORT_C (2 << 29) | 1759 | #define VIDEO_DIP_PORT_C (2 << 29) |
1712 | #define VIDEO_DIP_PORT_D (3 << 29) | 1760 | #define VIDEO_DIP_PORT_D (3 << 29) |
1713 | #define VIDEO_DIP_PORT_MASK (3 << 29) | 1761 | #define VIDEO_DIP_PORT_MASK (3 << 29) |
1762 | #define VIDEO_DIP_ENABLE_GCP (1 << 25) | ||
1714 | #define VIDEO_DIP_ENABLE_AVI (1 << 21) | 1763 | #define VIDEO_DIP_ENABLE_AVI (1 << 21) |
1715 | #define VIDEO_DIP_ENABLE_VENDOR (2 << 21) | 1764 | #define VIDEO_DIP_ENABLE_VENDOR (2 << 21) |
1765 | #define VIDEO_DIP_ENABLE_GAMUT (4 << 21) | ||
1716 | #define VIDEO_DIP_ENABLE_SPD (8 << 21) | 1766 | #define VIDEO_DIP_ENABLE_SPD (8 << 21) |
1717 | #define VIDEO_DIP_SELECT_AVI (0 << 19) | 1767 | #define VIDEO_DIP_SELECT_AVI (0 << 19) |
1718 | #define VIDEO_DIP_SELECT_VENDOR (1 << 19) | 1768 | #define VIDEO_DIP_SELECT_VENDOR (1 << 19) |
@@ -1723,7 +1773,11 @@ | |||
1723 | #define VIDEO_DIP_FREQ_2VSYNC (2 << 16) | 1773 | #define VIDEO_DIP_FREQ_2VSYNC (2 << 16) |
1724 | #define VIDEO_DIP_FREQ_MASK (3 << 16) | 1774 | #define VIDEO_DIP_FREQ_MASK (3 << 16) |
1725 | /* HSW and later: */ | 1775 | /* HSW and later: */ |
1776 | #define VIDEO_DIP_ENABLE_VSC_HSW (1 << 20) | ||
1777 | #define VIDEO_DIP_ENABLE_GCP_HSW (1 << 16) | ||
1726 | #define VIDEO_DIP_ENABLE_AVI_HSW (1 << 12) | 1778 | #define VIDEO_DIP_ENABLE_AVI_HSW (1 << 12) |
1779 | #define VIDEO_DIP_ENABLE_VS_HSW (1 << 8) | ||
1780 | #define VIDEO_DIP_ENABLE_GMP_HSW (1 << 4) | ||
1727 | #define VIDEO_DIP_ENABLE_SPD_HSW (1 << 0) | 1781 | #define VIDEO_DIP_ENABLE_SPD_HSW (1 << 0) |
1728 | 1782 | ||
1729 | /* Panel power sequencing */ | 1783 | /* Panel power sequencing */ |
@@ -1795,18 +1849,35 @@ | |||
1795 | #define PFIT_AUTO_RATIOS 0x61238 | 1849 | #define PFIT_AUTO_RATIOS 0x61238 |
1796 | 1850 | ||
1797 | /* Backlight control */ | 1851 | /* Backlight control */ |
1798 | #define BLC_PWM_CTL 0x61254 | ||
1799 | #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) | ||
1800 | #define BLC_PWM_CTL2 0x61250 /* 965+ only */ | 1852 | #define BLC_PWM_CTL2 0x61250 /* 965+ only */ |
1801 | #define BLM_COMBINATION_MODE (1 << 30) | 1853 | #define BLM_PWM_ENABLE (1 << 31) |
1854 | #define BLM_COMBINATION_MODE (1 << 30) /* gen4 only */ | ||
1855 | #define BLM_PIPE_SELECT (1 << 29) | ||
1856 | #define BLM_PIPE_SELECT_IVB (3 << 29) | ||
1857 | #define BLM_PIPE_A (0 << 29) | ||
1858 | #define BLM_PIPE_B (1 << 29) | ||
1859 | #define BLM_PIPE_C (2 << 29) /* ivb + */ | ||
1860 | #define BLM_PIPE(pipe) ((pipe) << 29) | ||
1861 | #define BLM_POLARITY_I965 (1 << 28) /* gen4 only */ | ||
1862 | #define BLM_PHASE_IN_INTERUPT_STATUS (1 << 26) | ||
1863 | #define BLM_PHASE_IN_ENABLE (1 << 25) | ||
1864 | #define BLM_PHASE_IN_INTERUPT_ENABL (1 << 24) | ||
1865 | #define BLM_PHASE_IN_TIME_BASE_SHIFT (16) | ||
1866 | #define BLM_PHASE_IN_TIME_BASE_MASK (0xff << 16) | ||
1867 | #define BLM_PHASE_IN_COUNT_SHIFT (8) | ||
1868 | #define BLM_PHASE_IN_COUNT_MASK (0xff << 8) | ||
1869 | #define BLM_PHASE_IN_INCR_SHIFT (0) | ||
1870 | #define BLM_PHASE_IN_INCR_MASK (0xff << 0) | ||
1871 | #define BLC_PWM_CTL 0x61254 | ||
1802 | /* | 1872 | /* |
1803 | * This is the most significant 15 bits of the number of backlight cycles in a | 1873 | * This is the most significant 15 bits of the number of backlight cycles in a |
1804 | * complete cycle of the modulated backlight control. | 1874 | * complete cycle of the modulated backlight control. |
1805 | * | 1875 | * |
1806 | * The actual value is this field multiplied by two. | 1876 | * The actual value is this field multiplied by two. |
1807 | */ | 1877 | */ |
1808 | #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) | 1878 | #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) |
1809 | #define BLM_LEGACY_MODE (1 << 16) | 1879 | #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) |
1880 | #define BLM_LEGACY_MODE (1 << 16) /* gen2 only */ | ||
1810 | /* | 1881 | /* |
1811 | * This is the number of cycles out of the backlight modulation cycle for which | 1882 | * This is the number of cycles out of the backlight modulation cycle for which |
1812 | * the backlight is on. | 1883 | * the backlight is on. |
@@ -1816,9 +1887,24 @@ | |||
1816 | */ | 1887 | */ |
1817 | #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) | 1888 | #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) |
1818 | #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) | 1889 | #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) |
1890 | #define BACKLIGHT_DUTY_CYCLE_MASK_PNV (0xfffe) | ||
1891 | #define BLM_POLARITY_PNV (1 << 0) /* pnv only */ | ||
1819 | 1892 | ||
1820 | #define BLC_HIST_CTL 0x61260 | 1893 | #define BLC_HIST_CTL 0x61260 |
1821 | 1894 | ||
1895 | /* New registers for PCH-split platforms. Safe where new bits show up, the | ||
1896 | * register layout machtes with gen4 BLC_PWM_CTL[12]. */ | ||
1897 | #define BLC_PWM_CPU_CTL2 0x48250 | ||
1898 | #define BLC_PWM_CPU_CTL 0x48254 | ||
1899 | |||
1900 | /* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is | ||
1901 | * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */ | ||
1902 | #define BLC_PWM_PCH_CTL1 0xc8250 | ||
1903 | #define BLM_PCH_PWM_ENABLE (1 << 31) | ||
1904 | #define BLM_PCH_OVERRIDE_ENABLE (1 << 30) | ||
1905 | #define BLM_PCH_POLARITY (1 << 29) | ||
1906 | #define BLC_PWM_PCH_CTL2 0xc8254 | ||
1907 | |||
1822 | /* TV port control */ | 1908 | /* TV port control */ |
1823 | #define TV_CTL 0x68000 | 1909 | #define TV_CTL 0x68000 |
1824 | /** Enables the TV encoder */ | 1910 | /** Enables the TV encoder */ |
@@ -2583,13 +2669,13 @@ | |||
2583 | #define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) | 2669 | #define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) |
2584 | 2670 | ||
2585 | #define VLV_DPFLIPSTAT 0x70028 | 2671 | #define VLV_DPFLIPSTAT 0x70028 |
2586 | #define PIPEB_LINE_COMPARE_STATUS (1<<29) | 2672 | #define PIPEB_LINE_COMPARE_INT_EN (1<<29) |
2587 | #define PIPEB_HLINE_INT_EN (1<<28) | 2673 | #define PIPEB_HLINE_INT_EN (1<<28) |
2588 | #define PIPEB_VBLANK_INT_EN (1<<27) | 2674 | #define PIPEB_VBLANK_INT_EN (1<<27) |
2589 | #define SPRITED_FLIPDONE_INT_EN (1<<26) | 2675 | #define SPRITED_FLIPDONE_INT_EN (1<<26) |
2590 | #define SPRITEC_FLIPDONE_INT_EN (1<<25) | 2676 | #define SPRITEC_FLIPDONE_INT_EN (1<<25) |
2591 | #define PLANEB_FLIPDONE_INT_EN (1<<24) | 2677 | #define PLANEB_FLIPDONE_INT_EN (1<<24) |
2592 | #define PIPEA_LINE_COMPARE_STATUS (1<<21) | 2678 | #define PIPEA_LINE_COMPARE_INT_EN (1<<21) |
2593 | #define PIPEA_HLINE_INT_EN (1<<20) | 2679 | #define PIPEA_HLINE_INT_EN (1<<20) |
2594 | #define PIPEA_VBLANK_INT_EN (1<<19) | 2680 | #define PIPEA_VBLANK_INT_EN (1<<19) |
2595 | #define SPRITEB_FLIPDONE_INT_EN (1<<18) | 2681 | #define SPRITEB_FLIPDONE_INT_EN (1<<18) |
@@ -2897,13 +2983,14 @@ | |||
2897 | #define DSPSIZE(plane) _PIPE(plane, _DSPASIZE, _DSPBSIZE) | 2983 | #define DSPSIZE(plane) _PIPE(plane, _DSPASIZE, _DSPBSIZE) |
2898 | #define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF) | 2984 | #define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF) |
2899 | #define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF) | 2985 | #define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF) |
2986 | #define DSPLINOFF(plane) DSPADDR(plane) | ||
2900 | 2987 | ||
2901 | /* Display/Sprite base address macros */ | 2988 | /* Display/Sprite base address macros */ |
2902 | #define DISP_BASEADDR_MASK (0xfffff000) | 2989 | #define DISP_BASEADDR_MASK (0xfffff000) |
2903 | #define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) | 2990 | #define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) |
2904 | #define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK) | 2991 | #define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK) |
2905 | #define I915_MODIFY_DISPBASE(reg, gfx_addr) \ | 2992 | #define I915_MODIFY_DISPBASE(reg, gfx_addr) \ |
2906 | (I915_WRITE(reg, gfx_addr | I915_LO_DISPBASE(I915_READ(reg)))) | 2993 | (I915_WRITE((reg), (gfx_addr) | I915_LO_DISPBASE(I915_READ(reg)))) |
2907 | 2994 | ||
2908 | /* VBIOS flags */ | 2995 | /* VBIOS flags */ |
2909 | #define SWF00 0x71410 | 2996 | #define SWF00 0x71410 |
@@ -3771,6 +3858,9 @@ | |||
3771 | #define _FDI_RXA_TUSIZE2 0xf0038 | 3858 | #define _FDI_RXA_TUSIZE2 0xf0038 |
3772 | #define _FDI_RXB_TUSIZE1 0xf1030 | 3859 | #define _FDI_RXB_TUSIZE1 0xf1030 |
3773 | #define _FDI_RXB_TUSIZE2 0xf1038 | 3860 | #define _FDI_RXB_TUSIZE2 0xf1038 |
3861 | #define FDI_RX_TP1_TO_TP2_48 (2<<20) | ||
3862 | #define FDI_RX_TP1_TO_TP2_64 (3<<20) | ||
3863 | #define FDI_RX_FDI_DELAY_90 (0x90<<0) | ||
3774 | #define FDI_RX_MISC(pipe) _PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC) | 3864 | #define FDI_RX_MISC(pipe) _PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC) |
3775 | #define FDI_RX_TUSIZE1(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1) | 3865 | #define FDI_RX_TUSIZE1(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1) |
3776 | #define FDI_RX_TUSIZE2(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2) | 3866 | #define FDI_RX_TUSIZE2(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2) |
@@ -3824,7 +3914,6 @@ | |||
3824 | #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) | 3914 | #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) |
3825 | 3915 | ||
3826 | /* or SDVOB */ | 3916 | /* or SDVOB */ |
3827 | #define VLV_HDMIB 0x61140 | ||
3828 | #define HDMIB 0xe1140 | 3917 | #define HDMIB 0xe1140 |
3829 | #define PORT_ENABLE (1 << 31) | 3918 | #define PORT_ENABLE (1 << 31) |
3830 | #define TRANSCODER(pipe) ((pipe) << 30) | 3919 | #define TRANSCODER(pipe) ((pipe) << 30) |
@@ -3855,20 +3944,18 @@ | |||
3855 | #define PCH_LVDS 0xe1180 | 3944 | #define PCH_LVDS 0xe1180 |
3856 | #define LVDS_DETECTED (1 << 1) | 3945 | #define LVDS_DETECTED (1 << 1) |
3857 | 3946 | ||
3858 | #define BLC_PWM_CPU_CTL2 0x48250 | 3947 | /* vlv has 2 sets of panel control regs. */ |
3859 | #define PWM_ENABLE (1 << 31) | 3948 | #define PIPEA_PP_STATUS 0x61200 |
3860 | #define PWM_PIPE_A (0 << 29) | 3949 | #define PIPEA_PP_CONTROL 0x61204 |
3861 | #define PWM_PIPE_B (1 << 29) | 3950 | #define PIPEA_PP_ON_DELAYS 0x61208 |
3862 | #define BLC_PWM_CPU_CTL 0x48254 | 3951 | #define PIPEA_PP_OFF_DELAYS 0x6120c |
3952 | #define PIPEA_PP_DIVISOR 0x61210 | ||
3863 | 3953 | ||
3864 | #define BLC_PWM_PCH_CTL1 0xc8250 | 3954 | #define PIPEB_PP_STATUS 0x61300 |
3865 | #define PWM_PCH_ENABLE (1 << 31) | 3955 | #define PIPEB_PP_CONTROL 0x61304 |
3866 | #define PWM_POLARITY_ACTIVE_LOW (1 << 29) | 3956 | #define PIPEB_PP_ON_DELAYS 0x61308 |
3867 | #define PWM_POLARITY_ACTIVE_HIGH (0 << 29) | 3957 | #define PIPEB_PP_OFF_DELAYS 0x6130c |
3868 | #define PWM_POLARITY_ACTIVE_LOW2 (1 << 28) | 3958 | #define PIPEB_PP_DIVISOR 0x61310 |
3869 | #define PWM_POLARITY_ACTIVE_HIGH2 (0 << 28) | ||
3870 | |||
3871 | #define BLC_PWM_PCH_CTL2 0xc8254 | ||
3872 | 3959 | ||
3873 | #define PCH_PP_STATUS 0xc7200 | 3960 | #define PCH_PP_STATUS 0xc7200 |
3874 | #define PCH_PP_CONTROL 0xc7204 | 3961 | #define PCH_PP_CONTROL 0xc7204 |
@@ -3992,6 +4079,7 @@ | |||
3992 | #define FORCEWAKE 0xA18C | 4079 | #define FORCEWAKE 0xA18C |
3993 | #define FORCEWAKE_VLV 0x1300b0 | 4080 | #define FORCEWAKE_VLV 0x1300b0 |
3994 | #define FORCEWAKE_ACK_VLV 0x1300b4 | 4081 | #define FORCEWAKE_ACK_VLV 0x1300b4 |
4082 | #define FORCEWAKE_ACK_HSW 0x130044 | ||
3995 | #define FORCEWAKE_ACK 0x130090 | 4083 | #define FORCEWAKE_ACK 0x130090 |
3996 | #define FORCEWAKE_MT 0xa188 /* multi-threaded */ | 4084 | #define FORCEWAKE_MT 0xa188 /* multi-threaded */ |
3997 | #define FORCEWAKE_MT_ACK 0x130040 | 4085 | #define FORCEWAKE_MT_ACK 0x130040 |
@@ -4012,10 +4100,15 @@ | |||
4012 | # define GEN6_CSUNIT_CLOCK_GATE_DISABLE (1 << 7) | 4100 | # define GEN6_CSUNIT_CLOCK_GATE_DISABLE (1 << 7) |
4013 | 4101 | ||
4014 | #define GEN6_UCGCTL2 0x9404 | 4102 | #define GEN6_UCGCTL2 0x9404 |
4103 | # define GEN7_VDSUNIT_CLOCK_GATE_DISABLE (1 << 30) | ||
4104 | # define GEN7_TDLUNIT_CLOCK_GATE_DISABLE (1 << 22) | ||
4015 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) | 4105 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) |
4016 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) | 4106 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) |
4017 | # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) | 4107 | # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) |
4018 | 4108 | ||
4109 | #define GEN7_UCGCTL4 0x940c | ||
4110 | #define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25) | ||
4111 | |||
4019 | #define GEN6_RPNSWREQ 0xA008 | 4112 | #define GEN6_RPNSWREQ 0xA008 |
4020 | #define GEN6_TURBO_DISABLE (1<<31) | 4113 | #define GEN6_TURBO_DISABLE (1<<31) |
4021 | #define GEN6_FREQUENCY(x) ((x)<<25) | 4114 | #define GEN6_FREQUENCY(x) ((x)<<25) |
@@ -4047,6 +4140,7 @@ | |||
4047 | #define GEN6_RP_UP_IDLE_MIN (0x1<<3) | 4140 | #define GEN6_RP_UP_IDLE_MIN (0x1<<3) |
4048 | #define GEN6_RP_UP_BUSY_AVG (0x2<<3) | 4141 | #define GEN6_RP_UP_BUSY_AVG (0x2<<3) |
4049 | #define GEN6_RP_UP_BUSY_CONT (0x4<<3) | 4142 | #define GEN6_RP_UP_BUSY_CONT (0x4<<3) |
4143 | #define GEN7_RP_DOWN_IDLE_AVG (0x2<<0) | ||
4050 | #define GEN6_RP_DOWN_IDLE_CONT (0x1<<0) | 4144 | #define GEN6_RP_DOWN_IDLE_CONT (0x1<<0) |
4051 | #define GEN6_RP_UP_THRESHOLD 0xA02C | 4145 | #define GEN6_RP_UP_THRESHOLD 0xA02C |
4052 | #define GEN6_RP_DOWN_THRESHOLD 0xA030 | 4146 | #define GEN6_RP_DOWN_THRESHOLD 0xA030 |
@@ -4111,6 +4205,26 @@ | |||
4111 | #define GEN6_RC6 3 | 4205 | #define GEN6_RC6 3 |
4112 | #define GEN6_RC7 4 | 4206 | #define GEN6_RC7 4 |
4113 | 4207 | ||
4208 | #define GEN7_MISCCPCTL (0x9424) | ||
4209 | #define GEN7_DOP_CLOCK_GATE_ENABLE (1<<0) | ||
4210 | |||
4211 | /* IVYBRIDGE DPF */ | ||
4212 | #define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */ | ||
4213 | #define GEN7_L3CDERRST1_ROW_MASK (0x7ff<<14) | ||
4214 | #define GEN7_PARITY_ERROR_VALID (1<<13) | ||
4215 | #define GEN7_L3CDERRST1_BANK_MASK (3<<11) | ||
4216 | #define GEN7_L3CDERRST1_SUBBANK_MASK (7<<8) | ||
4217 | #define GEN7_PARITY_ERROR_ROW(reg) \ | ||
4218 | ((reg & GEN7_L3CDERRST1_ROW_MASK) >> 14) | ||
4219 | #define GEN7_PARITY_ERROR_BANK(reg) \ | ||
4220 | ((reg & GEN7_L3CDERRST1_BANK_MASK) >> 11) | ||
4221 | #define GEN7_PARITY_ERROR_SUBBANK(reg) \ | ||
4222 | ((reg & GEN7_L3CDERRST1_SUBBANK_MASK) >> 8) | ||
4223 | #define GEN7_L3CDERRST1_ENABLE (1<<7) | ||
4224 | |||
4225 | #define GEN7_L3LOG_BASE 0xB070 | ||
4226 | #define GEN7_L3LOG_SIZE 0x80 | ||
4227 | |||
4114 | #define G4X_AUD_VID_DID 0x62020 | 4228 | #define G4X_AUD_VID_DID 0x62020 |
4115 | #define INTEL_AUDIO_DEVCL 0x808629FB | 4229 | #define INTEL_AUDIO_DEVCL 0x808629FB |
4116 | #define INTEL_AUDIO_DEVBLC 0x80862801 | 4230 | #define INTEL_AUDIO_DEVBLC 0x80862801 |
@@ -4177,7 +4291,7 @@ | |||
4177 | PIPE_DDI_FUNC_CTL_B) | 4291 | PIPE_DDI_FUNC_CTL_B) |
4178 | #define PIPE_DDI_FUNC_ENABLE (1<<31) | 4292 | #define PIPE_DDI_FUNC_ENABLE (1<<31) |
4179 | /* Those bits are ignored by pipe EDP since it can only connect to DDI A */ | 4293 | /* Those bits are ignored by pipe EDP since it can only connect to DDI A */ |
4180 | #define PIPE_DDI_PORT_MASK (0xf<<28) | 4294 | #define PIPE_DDI_PORT_MASK (7<<28) |
4181 | #define PIPE_DDI_SELECT_PORT(x) ((x)<<28) | 4295 | #define PIPE_DDI_SELECT_PORT(x) ((x)<<28) |
4182 | #define PIPE_DDI_MODE_SELECT_HDMI (0<<24) | 4296 | #define PIPE_DDI_MODE_SELECT_HDMI (0<<24) |
4183 | #define PIPE_DDI_MODE_SELECT_DVI (1<<24) | 4297 | #define PIPE_DDI_MODE_SELECT_DVI (1<<24) |
@@ -4335,7 +4449,7 @@ | |||
4335 | #define PIPE_WM_LINETIME_B 0x45274 | 4449 | #define PIPE_WM_LINETIME_B 0x45274 |
4336 | #define PIPE_WM_LINETIME(pipe) _PIPE(pipe, \ | 4450 | #define PIPE_WM_LINETIME(pipe) _PIPE(pipe, \ |
4337 | PIPE_WM_LINETIME_A, \ | 4451 | PIPE_WM_LINETIME_A, \ |
4338 | PIPE_WM_LINETIME_A) | 4452 | PIPE_WM_LINETIME_B) |
4339 | #define PIPE_WM_LINETIME_MASK (0x1ff) | 4453 | #define PIPE_WM_LINETIME_MASK (0x1ff) |
4340 | #define PIPE_WM_LINETIME_TIME(x) ((x)) | 4454 | #define PIPE_WM_LINETIME_TIME(x) ((x)) |
4341 | #define PIPE_WM_LINETIME_IPS_LINETIME_MASK (0x1ff<<16) | 4455 | #define PIPE_WM_LINETIME_IPS_LINETIME_MASK (0x1ff<<16) |
@@ -4347,4 +4461,9 @@ | |||
4347 | #define SFUSE_STRAP_DDIC_DETECTED (1<<1) | 4461 | #define SFUSE_STRAP_DDIC_DETECTED (1<<1) |
4348 | #define SFUSE_STRAP_DDID_DETECTED (1<<0) | 4462 | #define SFUSE_STRAP_DDID_DETECTED (1<<0) |
4349 | 4463 | ||
4464 | #define WM_DBG 0x45280 | ||
4465 | #define WM_DBG_DISALLOW_MULTIPLE_LP (1<<0) | ||
4466 | #define WM_DBG_DISALLOW_MAXFIFO (1<<1) | ||
4467 | #define WM_DBG_DISALLOW_SPRITE (1<<2) | ||
4468 | |||
4350 | #endif /* _I915_REG_H_ */ | 4469 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a748e5cabe14..4776ccf1b3cd 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -828,10 +828,7 @@ int i915_save_state(struct drm_device *dev) | |||
828 | dev_priv->saveIMR = I915_READ(IMR); | 828 | dev_priv->saveIMR = I915_READ(IMR); |
829 | } | 829 | } |
830 | 830 | ||
831 | if (IS_IRONLAKE_M(dev)) | 831 | intel_disable_gt_powersave(dev); |
832 | ironlake_disable_drps(dev); | ||
833 | if (INTEL_INFO(dev)->gen >= 6) | ||
834 | gen6_disable_rps(dev); | ||
835 | 832 | ||
836 | /* Cache mode state */ | 833 | /* Cache mode state */ |
837 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | 834 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 79f83445afa0..2f5388af8df9 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/sysfs.h> | 31 | #include <linux/sysfs.h> |
32 | #include "intel_drv.h" | ||
32 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
33 | 34 | ||
34 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | 35 | static u32 calc_residency(struct drm_device *dev, const u32 reg) |
@@ -92,20 +93,134 @@ static struct attribute_group rc6_attr_group = { | |||
92 | .attrs = rc6_attrs | 93 | .attrs = rc6_attrs |
93 | }; | 94 | }; |
94 | 95 | ||
95 | void i915_setup_sysfs(struct drm_device *dev) | 96 | static int l3_access_valid(struct drm_device *dev, loff_t offset) |
97 | { | ||
98 | if (!IS_IVYBRIDGE(dev)) | ||
99 | return -EPERM; | ||
100 | |||
101 | if (offset % 4 != 0) | ||
102 | return -EINVAL; | ||
103 | |||
104 | if (offset >= GEN7_L3LOG_SIZE) | ||
105 | return -ENXIO; | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static ssize_t | ||
111 | i915_l3_read(struct file *filp, struct kobject *kobj, | ||
112 | struct bin_attribute *attr, char *buf, | ||
113 | loff_t offset, size_t count) | ||
114 | { | ||
115 | struct device *dev = container_of(kobj, struct device, kobj); | ||
116 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
117 | struct drm_device *drm_dev = dminor->dev; | ||
118 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | ||
119 | uint32_t misccpctl; | ||
120 | int i, ret; | ||
121 | |||
122 | ret = l3_access_valid(drm_dev, offset); | ||
123 | if (ret) | ||
124 | return ret; | ||
125 | |||
126 | ret = i915_mutex_lock_interruptible(drm_dev); | ||
127 | if (ret) | ||
128 | return ret; | ||
129 | |||
130 | misccpctl = I915_READ(GEN7_MISCCPCTL); | ||
131 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); | ||
132 | |||
133 | for (i = offset; count >= 4 && i < GEN7_L3LOG_SIZE; i += 4, count -= 4) | ||
134 | *((uint32_t *)(&buf[i])) = I915_READ(GEN7_L3LOG_BASE + i); | ||
135 | |||
136 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | ||
137 | |||
138 | mutex_unlock(&drm_dev->struct_mutex); | ||
139 | |||
140 | return i - offset; | ||
141 | } | ||
142 | |||
143 | static ssize_t | ||
144 | i915_l3_write(struct file *filp, struct kobject *kobj, | ||
145 | struct bin_attribute *attr, char *buf, | ||
146 | loff_t offset, size_t count) | ||
96 | { | 147 | { |
148 | struct device *dev = container_of(kobj, struct device, kobj); | ||
149 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
150 | struct drm_device *drm_dev = dminor->dev; | ||
151 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | ||
152 | u32 *temp = NULL; /* Just here to make handling failures easy */ | ||
97 | int ret; | 153 | int ret; |
98 | 154 | ||
99 | /* ILK doesn't have any residency information */ | 155 | ret = l3_access_valid(drm_dev, offset); |
100 | if (INTEL_INFO(dev)->gen < 6) | 156 | if (ret) |
101 | return; | 157 | return ret; |
102 | 158 | ||
103 | ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 159 | ret = i915_mutex_lock_interruptible(drm_dev); |
104 | if (ret) | 160 | if (ret) |
105 | DRM_ERROR("sysfs setup failed\n"); | 161 | return ret; |
162 | |||
163 | if (!dev_priv->mm.l3_remap_info) { | ||
164 | temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL); | ||
165 | if (!temp) { | ||
166 | mutex_unlock(&drm_dev->struct_mutex); | ||
167 | return -ENOMEM; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | ret = i915_gpu_idle(drm_dev); | ||
172 | if (ret) { | ||
173 | kfree(temp); | ||
174 | mutex_unlock(&drm_dev->struct_mutex); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | /* TODO: Ideally we really want a GPU reset here to make sure errors | ||
179 | * aren't propagated. Since I cannot find a stable way to reset the GPU | ||
180 | * at this point it is left as a TODO. | ||
181 | */ | ||
182 | if (temp) | ||
183 | dev_priv->mm.l3_remap_info = temp; | ||
184 | |||
185 | memcpy(dev_priv->mm.l3_remap_info + (offset/4), | ||
186 | buf + (offset/4), | ||
187 | count); | ||
188 | |||
189 | i915_gem_l3_remap(drm_dev); | ||
190 | |||
191 | mutex_unlock(&drm_dev->struct_mutex); | ||
192 | |||
193 | return count; | ||
194 | } | ||
195 | |||
196 | static struct bin_attribute dpf_attrs = { | ||
197 | .attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)}, | ||
198 | .size = GEN7_L3LOG_SIZE, | ||
199 | .read = i915_l3_read, | ||
200 | .write = i915_l3_write, | ||
201 | .mmap = NULL | ||
202 | }; | ||
203 | |||
204 | void i915_setup_sysfs(struct drm_device *dev) | ||
205 | { | ||
206 | int ret; | ||
207 | |||
208 | if (INTEL_INFO(dev)->gen >= 6) { | ||
209 | ret = sysfs_merge_group(&dev->primary->kdev.kobj, | ||
210 | &rc6_attr_group); | ||
211 | if (ret) | ||
212 | DRM_ERROR("RC6 residency sysfs setup failed\n"); | ||
213 | } | ||
214 | |||
215 | if (IS_IVYBRIDGE(dev)) { | ||
216 | ret = device_create_bin_file(&dev->primary->kdev, &dpf_attrs); | ||
217 | if (ret) | ||
218 | DRM_ERROR("l3 parity sysfs setup failed\n"); | ||
219 | } | ||
106 | } | 220 | } |
107 | 221 | ||
108 | void i915_teardown_sysfs(struct drm_device *dev) | 222 | void i915_teardown_sysfs(struct drm_device *dev) |
109 | { | 223 | { |
224 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); | ||
110 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 225 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); |
111 | } | 226 | } |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index dac7bba4d9da..fe90b3a84a6d 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -311,9 +311,33 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_retire, | |||
311 | TP_ARGS(ring, seqno) | 311 | TP_ARGS(ring, seqno) |
312 | ); | 312 | ); |
313 | 313 | ||
314 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_begin, | 314 | TRACE_EVENT(i915_gem_request_wait_begin, |
315 | TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), | 315 | TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), |
316 | TP_ARGS(ring, seqno) | 316 | TP_ARGS(ring, seqno), |
317 | |||
318 | TP_STRUCT__entry( | ||
319 | __field(u32, dev) | ||
320 | __field(u32, ring) | ||
321 | __field(u32, seqno) | ||
322 | __field(bool, blocking) | ||
323 | ), | ||
324 | |||
325 | /* NB: the blocking information is racy since mutex_is_locked | ||
326 | * doesn't check that the current thread holds the lock. The only | ||
327 | * other option would be to pass the boolean information of whether | ||
328 | * or not the class was blocking down through the stack which is | ||
329 | * less desirable. | ||
330 | */ | ||
331 | TP_fast_assign( | ||
332 | __entry->dev = ring->dev->primary->index; | ||
333 | __entry->ring = ring->id; | ||
334 | __entry->seqno = seqno; | ||
335 | __entry->blocking = mutex_is_locked(&ring->dev->struct_mutex); | ||
336 | ), | ||
337 | |||
338 | TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s", | ||
339 | __entry->dev, __entry->ring, __entry->seqno, | ||
340 | __entry->blocking ? "yes (NB)" : "no") | ||
317 | ); | 341 | ); |
318 | 342 | ||
319 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end, | 343 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end, |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 353459362f6f..8c6074154bf6 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -692,7 +692,7 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = { | |||
692 | * | 692 | * |
693 | * Returns 0 on success, nonzero on failure. | 693 | * Returns 0 on success, nonzero on failure. |
694 | */ | 694 | */ |
695 | bool | 695 | int |
696 | intel_parse_bios(struct drm_device *dev) | 696 | intel_parse_bios(struct drm_device *dev) |
697 | { | 697 | { |
698 | struct drm_i915_private *dev_priv = dev->dev_private; | 698 | struct drm_i915_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index dbda6e3bdf07..31c2107e7825 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -476,7 +476,7 @@ struct bdb_edp { | |||
476 | } __attribute__ ((packed)); | 476 | } __attribute__ ((packed)); |
477 | 477 | ||
478 | void intel_setup_bios(struct drm_device *dev); | 478 | void intel_setup_bios(struct drm_device *dev); |
479 | bool intel_parse_bios(struct drm_device *dev); | 479 | int intel_parse_bios(struct drm_device *dev); |
480 | 480 | ||
481 | /* | 481 | /* |
482 | * Driver<->VBIOS interaction occurs through scratch bits in | 482 | * Driver<->VBIOS interaction occurs through scratch bits in |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 75a70c46ef1b..7ed4a41c3965 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -88,6 +88,9 @@ static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) | |||
88 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 88 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
89 | temp &= ~ADPA_DAC_ENABLE; | 89 | temp &= ~ADPA_DAC_ENABLE; |
90 | 90 | ||
91 | if (IS_VALLEYVIEW(dev) && mode != DRM_MODE_DPMS_ON) | ||
92 | mode = DRM_MODE_DPMS_OFF; | ||
93 | |||
91 | switch (mode) { | 94 | switch (mode) { |
92 | case DRM_MODE_DPMS_ON: | 95 | case DRM_MODE_DPMS_ON: |
93 | temp |= ADPA_DAC_ENABLE; | 96 | temp |= ADPA_DAC_ENABLE; |
@@ -129,7 +132,7 @@ static int intel_crt_mode_valid(struct drm_connector *connector, | |||
129 | } | 132 | } |
130 | 133 | ||
131 | static bool intel_crt_mode_fixup(struct drm_encoder *encoder, | 134 | static bool intel_crt_mode_fixup(struct drm_encoder *encoder, |
132 | struct drm_display_mode *mode, | 135 | const struct drm_display_mode *mode, |
133 | struct drm_display_mode *adjusted_mode) | 136 | struct drm_display_mode *adjusted_mode) |
134 | { | 137 | { |
135 | return true; | 138 | return true; |
@@ -230,6 +233,42 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
230 | return ret; | 233 | return ret; |
231 | } | 234 | } |
232 | 235 | ||
236 | static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) | ||
237 | { | ||
238 | struct drm_device *dev = connector->dev; | ||
239 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
240 | u32 adpa; | ||
241 | bool ret; | ||
242 | u32 save_adpa; | ||
243 | |||
244 | save_adpa = adpa = I915_READ(ADPA); | ||
245 | DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); | ||
246 | |||
247 | adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; | ||
248 | |||
249 | I915_WRITE(ADPA, adpa); | ||
250 | |||
251 | if (wait_for((I915_READ(ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, | ||
252 | 1000)) { | ||
253 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); | ||
254 | I915_WRITE(ADPA, save_adpa); | ||
255 | } | ||
256 | |||
257 | /* Check the status to see if both blue and green are on now */ | ||
258 | adpa = I915_READ(ADPA); | ||
259 | if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) | ||
260 | ret = true; | ||
261 | else | ||
262 | ret = false; | ||
263 | |||
264 | DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret); | ||
265 | |||
266 | /* FIXME: debug force function and remove */ | ||
267 | ret = true; | ||
268 | |||
269 | return ret; | ||
270 | } | ||
271 | |||
233 | /** | 272 | /** |
234 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. | 273 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. |
235 | * | 274 | * |
@@ -249,6 +288,9 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
249 | if (HAS_PCH_SPLIT(dev)) | 288 | if (HAS_PCH_SPLIT(dev)) |
250 | return intel_ironlake_crt_detect_hotplug(connector); | 289 | return intel_ironlake_crt_detect_hotplug(connector); |
251 | 290 | ||
291 | if (IS_VALLEYVIEW(dev)) | ||
292 | return valleyview_crt_detect_hotplug(connector); | ||
293 | |||
252 | /* | 294 | /* |
253 | * On 4 series desktop, CRT detect sequence need to be done twice | 295 | * On 4 series desktop, CRT detect sequence need to be done twice |
254 | * to get a reliable result. | 296 | * to get a reliable result. |
@@ -288,39 +330,34 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) | |||
288 | { | 330 | { |
289 | struct intel_crt *crt = intel_attached_crt(connector); | 331 | struct intel_crt *crt = intel_attached_crt(connector); |
290 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; | 332 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; |
333 | struct edid *edid; | ||
334 | struct i2c_adapter *i2c; | ||
291 | 335 | ||
292 | /* CRT should always be at 0, but check anyway */ | 336 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); |
293 | if (crt->base.type != INTEL_OUTPUT_ANALOG) | 337 | |
294 | return false; | 338 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
339 | edid = drm_get_edid(connector, i2c); | ||
295 | 340 | ||
296 | if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { | 341 | if (edid) { |
297 | struct edid *edid; | 342 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; |
298 | bool is_digital = false; | ||
299 | struct i2c_adapter *i2c; | ||
300 | 343 | ||
301 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); | ||
302 | edid = drm_get_edid(connector, i2c); | ||
303 | /* | 344 | /* |
304 | * This may be a DVI-I connector with a shared DDC | 345 | * This may be a DVI-I connector with a shared DDC |
305 | * link between analog and digital outputs, so we | 346 | * link between analog and digital outputs, so we |
306 | * have to check the EDID input spec of the attached device. | 347 | * have to check the EDID input spec of the attached device. |
307 | * | ||
308 | * On the other hand, what should we do if it is a broken EDID? | ||
309 | */ | 348 | */ |
310 | if (edid != NULL) { | ||
311 | is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; | ||
312 | connector->display_info.raw_edid = NULL; | ||
313 | kfree(edid); | ||
314 | } | ||
315 | |||
316 | if (!is_digital) { | 349 | if (!is_digital) { |
317 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); | 350 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); |
318 | return true; | 351 | return true; |
319 | } else { | ||
320 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); | ||
321 | } | 352 | } |
353 | |||
354 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); | ||
355 | } else { | ||
356 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n"); | ||
322 | } | 357 | } |
323 | 358 | ||
359 | kfree(edid); | ||
360 | |||
324 | return false; | 361 | return false; |
325 | } | 362 | } |
326 | 363 | ||
@@ -453,18 +490,27 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
453 | struct intel_load_detect_pipe tmp; | 490 | struct intel_load_detect_pipe tmp; |
454 | 491 | ||
455 | if (I915_HAS_HOTPLUG(dev)) { | 492 | if (I915_HAS_HOTPLUG(dev)) { |
493 | /* We can not rely on the HPD pin always being correctly wired | ||
494 | * up, for example many KVM do not pass it through, and so | ||
495 | * only trust an assertion that the monitor is connected. | ||
496 | */ | ||
456 | if (intel_crt_detect_hotplug(connector)) { | 497 | if (intel_crt_detect_hotplug(connector)) { |
457 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); | 498 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); |
458 | return connector_status_connected; | 499 | return connector_status_connected; |
459 | } else { | 500 | } else |
460 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); | 501 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); |
461 | return connector_status_disconnected; | ||
462 | } | ||
463 | } | 502 | } |
464 | 503 | ||
465 | if (intel_crt_detect_ddc(connector)) | 504 | if (intel_crt_detect_ddc(connector)) |
466 | return connector_status_connected; | 505 | return connector_status_connected; |
467 | 506 | ||
507 | /* Load detection is broken on HPD capable machines. Whoever wants a | ||
508 | * broken monitor (without edid) to work behind a broken kvm (that fails | ||
509 | * to have the right resistors for HP detection) needs to fix this up. | ||
510 | * For now just bail out. */ | ||
511 | if (I915_HAS_HOTPLUG(dev)) | ||
512 | return connector_status_disconnected; | ||
513 | |||
468 | if (!force) | 514 | if (!force) |
469 | return connector->status; | 515 | return connector->status; |
470 | 516 | ||
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 46d1e886c692..933c74859172 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -170,6 +170,15 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
170 | 170 | ||
171 | udelay(600); | 171 | udelay(600); |
172 | 172 | ||
173 | /* We need to program FDI_RX_MISC with the default TP1 to TP2 | ||
174 | * values before enabling the receiver, and configure the delay | ||
175 | * for the FDI timing generator to 90h. Luckily, all the other | ||
176 | * bits are supposed to be zeroed, so we can write those values | ||
177 | * directly. | ||
178 | */ | ||
179 | I915_WRITE(FDI_RX_MISC(pipe), FDI_RX_TP1_TO_TP2_48 | | ||
180 | FDI_RX_FDI_DELAY_90); | ||
181 | |||
173 | /* Enable CPU FDI Receiver with auto-training */ | 182 | /* Enable CPU FDI Receiver with auto-training */ |
174 | reg = FDI_RX_CTL(pipe); | 183 | reg = FDI_RX_CTL(pipe); |
175 | I915_WRITE(reg, | 184 | I915_WRITE(reg, |
@@ -726,8 +735,7 @@ void intel_ddi_mode_set(struct drm_encoder *encoder, | |||
726 | 735 | ||
727 | I915_WRITE(DDI_FUNC_CTL(pipe), temp); | 736 | I915_WRITE(DDI_FUNC_CTL(pipe), temp); |
728 | 737 | ||
729 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | 738 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
730 | intel_hdmi_set_spd_infoframe(encoder); | ||
731 | } | 739 | } |
732 | 740 | ||
733 | void intel_ddi_dpms(struct drm_encoder *encoder, int mode) | 741 | void intel_ddi_dpms(struct drm_encoder *encoder, int mode) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a8538ac0299d..f6159765f1eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -98,6 +98,11 @@ intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, | |||
98 | int target, int refclk, intel_clock_t *match_clock, | 98 | int target, int refclk, intel_clock_t *match_clock, |
99 | intel_clock_t *best_clock); | 99 | intel_clock_t *best_clock); |
100 | 100 | ||
101 | static bool | ||
102 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
103 | int target, int refclk, intel_clock_t *match_clock, | ||
104 | intel_clock_t *best_clock); | ||
105 | |||
101 | static inline u32 /* units of 100MHz */ | 106 | static inline u32 /* units of 100MHz */ |
102 | intel_fdi_link_freq(struct drm_device *dev) | 107 | intel_fdi_link_freq(struct drm_device *dev) |
103 | { | 108 | { |
@@ -359,6 +364,48 @@ static const intel_limit_t intel_limits_ironlake_display_port = { | |||
359 | .find_pll = intel_find_pll_ironlake_dp, | 364 | .find_pll = intel_find_pll_ironlake_dp, |
360 | }; | 365 | }; |
361 | 366 | ||
367 | static const intel_limit_t intel_limits_vlv_dac = { | ||
368 | .dot = { .min = 25000, .max = 270000 }, | ||
369 | .vco = { .min = 4000000, .max = 6000000 }, | ||
370 | .n = { .min = 1, .max = 7 }, | ||
371 | .m = { .min = 22, .max = 450 }, /* guess */ | ||
372 | .m1 = { .min = 2, .max = 3 }, | ||
373 | .m2 = { .min = 11, .max = 156 }, | ||
374 | .p = { .min = 10, .max = 30 }, | ||
375 | .p1 = { .min = 2, .max = 3 }, | ||
376 | .p2 = { .dot_limit = 270000, | ||
377 | .p2_slow = 2, .p2_fast = 20 }, | ||
378 | .find_pll = intel_vlv_find_best_pll, | ||
379 | }; | ||
380 | |||
381 | static const intel_limit_t intel_limits_vlv_hdmi = { | ||
382 | .dot = { .min = 20000, .max = 165000 }, | ||
383 | .vco = { .min = 5994000, .max = 4000000 }, | ||
384 | .n = { .min = 1, .max = 7 }, | ||
385 | .m = { .min = 60, .max = 300 }, /* guess */ | ||
386 | .m1 = { .min = 2, .max = 3 }, | ||
387 | .m2 = { .min = 11, .max = 156 }, | ||
388 | .p = { .min = 10, .max = 30 }, | ||
389 | .p1 = { .min = 2, .max = 3 }, | ||
390 | .p2 = { .dot_limit = 270000, | ||
391 | .p2_slow = 2, .p2_fast = 20 }, | ||
392 | .find_pll = intel_vlv_find_best_pll, | ||
393 | }; | ||
394 | |||
395 | static const intel_limit_t intel_limits_vlv_dp = { | ||
396 | .dot = { .min = 162000, .max = 270000 }, | ||
397 | .vco = { .min = 5994000, .max = 4000000 }, | ||
398 | .n = { .min = 1, .max = 7 }, | ||
399 | .m = { .min = 60, .max = 300 }, /* guess */ | ||
400 | .m1 = { .min = 2, .max = 3 }, | ||
401 | .m2 = { .min = 11, .max = 156 }, | ||
402 | .p = { .min = 10, .max = 30 }, | ||
403 | .p1 = { .min = 2, .max = 3 }, | ||
404 | .p2 = { .dot_limit = 270000, | ||
405 | .p2_slow = 2, .p2_fast = 20 }, | ||
406 | .find_pll = intel_vlv_find_best_pll, | ||
407 | }; | ||
408 | |||
362 | u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) | 409 | u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) |
363 | { | 410 | { |
364 | unsigned long flags; | 411 | unsigned long flags; |
@@ -384,6 +431,28 @@ out_unlock: | |||
384 | return val; | 431 | return val; |
385 | } | 432 | } |
386 | 433 | ||
434 | static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, | ||
435 | u32 val) | ||
436 | { | ||
437 | unsigned long flags; | ||
438 | |||
439 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); | ||
440 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { | ||
441 | DRM_ERROR("DPIO idle wait timed out\n"); | ||
442 | goto out_unlock; | ||
443 | } | ||
444 | |||
445 | I915_WRITE(DPIO_DATA, val); | ||
446 | I915_WRITE(DPIO_REG, reg); | ||
447 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | | ||
448 | DPIO_BYTE); | ||
449 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) | ||
450 | DRM_ERROR("DPIO write wait timed out\n"); | ||
451 | |||
452 | out_unlock: | ||
453 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); | ||
454 | } | ||
455 | |||
387 | static void vlv_init_dpio(struct drm_device *dev) | 456 | static void vlv_init_dpio(struct drm_device *dev) |
388 | { | 457 | { |
389 | struct drm_i915_private *dev_priv = dev->dev_private; | 458 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -434,7 +503,7 @@ static bool is_dual_link_lvds(struct drm_i915_private *dev_priv, | |||
434 | * register is uninitialized. | 503 | * register is uninitialized. |
435 | */ | 504 | */ |
436 | val = I915_READ(reg); | 505 | val = I915_READ(reg); |
437 | if (!(val & ~LVDS_DETECTED)) | 506 | if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) |
438 | val = dev_priv->bios_lvds_val; | 507 | val = dev_priv->bios_lvds_val; |
439 | dev_priv->lvds_val = val; | 508 | dev_priv->lvds_val = val; |
440 | } | 509 | } |
@@ -510,6 +579,13 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) | |||
510 | limit = &intel_limits_pineview_lvds; | 579 | limit = &intel_limits_pineview_lvds; |
511 | else | 580 | else |
512 | limit = &intel_limits_pineview_sdvo; | 581 | limit = &intel_limits_pineview_sdvo; |
582 | } else if (IS_VALLEYVIEW(dev)) { | ||
583 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) | ||
584 | limit = &intel_limits_vlv_dac; | ||
585 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) | ||
586 | limit = &intel_limits_vlv_hdmi; | ||
587 | else | ||
588 | limit = &intel_limits_vlv_dp; | ||
513 | } else if (!IS_GEN2(dev)) { | 589 | } else if (!IS_GEN2(dev)) { |
514 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 590 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
515 | limit = &intel_limits_i9xx_lvds; | 591 | limit = &intel_limits_i9xx_lvds; |
@@ -551,11 +627,10 @@ static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock | |||
551 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) | 627 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) |
552 | { | 628 | { |
553 | struct drm_device *dev = crtc->dev; | 629 | struct drm_device *dev = crtc->dev; |
554 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
555 | struct intel_encoder *encoder; | 630 | struct intel_encoder *encoder; |
556 | 631 | ||
557 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) | 632 | for_each_encoder_on_crtc(dev, crtc, encoder) |
558 | if (encoder->base.crtc == crtc && encoder->type == type) | 633 | if (encoder->type == type) |
559 | return true; | 634 | return true; |
560 | 635 | ||
561 | return false; | 636 | return false; |
@@ -783,6 +858,73 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
783 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | 858 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
784 | return true; | 859 | return true; |
785 | } | 860 | } |
861 | static bool | ||
862 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
863 | int target, int refclk, intel_clock_t *match_clock, | ||
864 | intel_clock_t *best_clock) | ||
865 | { | ||
866 | u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; | ||
867 | u32 m, n, fastclk; | ||
868 | u32 updrate, minupdate, fracbits, p; | ||
869 | unsigned long bestppm, ppm, absppm; | ||
870 | int dotclk, flag; | ||
871 | |||
872 | dotclk = target * 1000; | ||
873 | bestppm = 1000000; | ||
874 | ppm = absppm = 0; | ||
875 | fastclk = dotclk / (2*100); | ||
876 | updrate = 0; | ||
877 | minupdate = 19200; | ||
878 | fracbits = 1; | ||
879 | n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0; | ||
880 | bestm1 = bestm2 = bestp1 = bestp2 = 0; | ||
881 | |||
882 | /* based on hardware requirement, prefer smaller n to precision */ | ||
883 | for (n = limit->n.min; n <= ((refclk) / minupdate); n++) { | ||
884 | updrate = refclk / n; | ||
885 | for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) { | ||
886 | for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) { | ||
887 | if (p2 > 10) | ||
888 | p2 = p2 - 1; | ||
889 | p = p1 * p2; | ||
890 | /* based on hardware requirement, prefer bigger m1,m2 values */ | ||
891 | for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) { | ||
892 | m2 = (((2*(fastclk * p * n / m1 )) + | ||
893 | refclk) / (2*refclk)); | ||
894 | m = m1 * m2; | ||
895 | vco = updrate * m; | ||
896 | if (vco >= limit->vco.min && vco < limit->vco.max) { | ||
897 | ppm = 1000000 * ((vco / p) - fastclk) / fastclk; | ||
898 | absppm = (ppm > 0) ? ppm : (-ppm); | ||
899 | if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) { | ||
900 | bestppm = 0; | ||
901 | flag = 1; | ||
902 | } | ||
903 | if (absppm < bestppm - 10) { | ||
904 | bestppm = absppm; | ||
905 | flag = 1; | ||
906 | } | ||
907 | if (flag) { | ||
908 | bestn = n; | ||
909 | bestm1 = m1; | ||
910 | bestm2 = m2; | ||
911 | bestp1 = p1; | ||
912 | bestp2 = p2; | ||
913 | flag = 0; | ||
914 | } | ||
915 | } | ||
916 | } | ||
917 | } | ||
918 | } | ||
919 | } | ||
920 | best_clock->n = bestn; | ||
921 | best_clock->m1 = bestm1; | ||
922 | best_clock->m2 = bestm2; | ||
923 | best_clock->p1 = bestp1; | ||
924 | best_clock->p2 = bestp2; | ||
925 | |||
926 | return true; | ||
927 | } | ||
786 | 928 | ||
787 | static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe) | 929 | static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe) |
788 | { | 930 | { |
@@ -1232,6 +1374,9 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | |||
1232 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), | 1374 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), |
1233 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1375 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1234 | reg, pipe_name(pipe)); | 1376 | reg, pipe_name(pipe)); |
1377 | |||
1378 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | ||
1379 | "IBX PCH dp port still using transcoder B\n"); | ||
1235 | } | 1380 | } |
1236 | 1381 | ||
1237 | static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | 1382 | static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, |
@@ -1241,6 +1386,9 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
1241 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), | 1386 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), |
1242 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | 1387 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
1243 | reg, pipe_name(pipe)); | 1388 | reg, pipe_name(pipe)); |
1389 | |||
1390 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | ||
1391 | "IBX PCH hdmi port still using transcoder B\n"); | ||
1244 | } | 1392 | } |
1245 | 1393 | ||
1246 | static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | 1394 | static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, |
@@ -1287,7 +1435,7 @@ static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) | |||
1287 | u32 val; | 1435 | u32 val; |
1288 | 1436 | ||
1289 | /* No really, not for ILK+ */ | 1437 | /* No really, not for ILK+ */ |
1290 | BUG_ON(dev_priv->info->gen >= 5); | 1438 | BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); |
1291 | 1439 | ||
1292 | /* PLL is protected by panel, make sure we can write it */ | 1440 | /* PLL is protected by panel, make sure we can write it */ |
1293 | if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) | 1441 | if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) |
@@ -1344,7 +1492,7 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) | |||
1344 | unsigned long flags; | 1492 | unsigned long flags; |
1345 | 1493 | ||
1346 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); | 1494 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
1347 | if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0, | 1495 | if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, |
1348 | 100)) { | 1496 | 100)) { |
1349 | DRM_ERROR("timeout waiting for SBI to become ready\n"); | 1497 | DRM_ERROR("timeout waiting for SBI to become ready\n"); |
1350 | goto out_unlock; | 1498 | goto out_unlock; |
@@ -1358,7 +1506,7 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) | |||
1358 | SBI_BUSY | | 1506 | SBI_BUSY | |
1359 | SBI_CTL_OP_CRWR); | 1507 | SBI_CTL_OP_CRWR); |
1360 | 1508 | ||
1361 | if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0, | 1509 | if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, |
1362 | 100)) { | 1510 | 100)) { |
1363 | DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); | 1511 | DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); |
1364 | goto out_unlock; | 1512 | goto out_unlock; |
@@ -1372,10 +1520,10 @@ static u32 | |||
1372 | intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) | 1520 | intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) |
1373 | { | 1521 | { |
1374 | unsigned long flags; | 1522 | unsigned long flags; |
1375 | u32 value; | 1523 | u32 value = 0; |
1376 | 1524 | ||
1377 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); | 1525 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
1378 | if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0, | 1526 | if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, |
1379 | 100)) { | 1527 | 100)) { |
1380 | DRM_ERROR("timeout waiting for SBI to become ready\n"); | 1528 | DRM_ERROR("timeout waiting for SBI to become ready\n"); |
1381 | goto out_unlock; | 1529 | goto out_unlock; |
@@ -1387,7 +1535,7 @@ intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) | |||
1387 | SBI_BUSY | | 1535 | SBI_BUSY | |
1388 | SBI_CTL_OP_CRRD); | 1536 | SBI_CTL_OP_CRRD); |
1389 | 1537 | ||
1390 | if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0, | 1538 | if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, |
1391 | 100)) { | 1539 | 100)) { |
1392 | DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); | 1540 | DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); |
1393 | goto out_unlock; | 1541 | goto out_unlock; |
@@ -1824,6 +1972,22 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) | |||
1824 | i915_gem_object_unpin(obj); | 1972 | i915_gem_object_unpin(obj); |
1825 | } | 1973 | } |
1826 | 1974 | ||
1975 | /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel | ||
1976 | * is assumed to be a power-of-two. */ | ||
1977 | static unsigned long gen4_compute_dspaddr_offset_xtiled(int *x, int *y, | ||
1978 | unsigned int bpp, | ||
1979 | unsigned int pitch) | ||
1980 | { | ||
1981 | int tile_rows, tiles; | ||
1982 | |||
1983 | tile_rows = *y / 8; | ||
1984 | *y %= 8; | ||
1985 | tiles = *x / (512/bpp); | ||
1986 | *x %= 512/bpp; | ||
1987 | |||
1988 | return tile_rows * pitch * 8 + tiles * 4096; | ||
1989 | } | ||
1990 | |||
1827 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 1991 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
1828 | int x, int y) | 1992 | int x, int y) |
1829 | { | 1993 | { |
@@ -1833,7 +1997,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1833 | struct intel_framebuffer *intel_fb; | 1997 | struct intel_framebuffer *intel_fb; |
1834 | struct drm_i915_gem_object *obj; | 1998 | struct drm_i915_gem_object *obj; |
1835 | int plane = intel_crtc->plane; | 1999 | int plane = intel_crtc->plane; |
1836 | unsigned long Start, Offset; | 2000 | unsigned long linear_offset; |
1837 | u32 dspcntr; | 2001 | u32 dspcntr; |
1838 | u32 reg; | 2002 | u32 reg; |
1839 | 2003 | ||
@@ -1880,18 +2044,28 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1880 | 2044 | ||
1881 | I915_WRITE(reg, dspcntr); | 2045 | I915_WRITE(reg, dspcntr); |
1882 | 2046 | ||
1883 | Start = obj->gtt_offset; | 2047 | linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
1884 | Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); | ||
1885 | 2048 | ||
1886 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | 2049 | if (INTEL_INFO(dev)->gen >= 4) { |
1887 | Start, Offset, x, y, fb->pitches[0]); | 2050 | intel_crtc->dspaddr_offset = |
2051 | gen4_compute_dspaddr_offset_xtiled(&x, &y, | ||
2052 | fb->bits_per_pixel / 8, | ||
2053 | fb->pitches[0]); | ||
2054 | linear_offset -= intel_crtc->dspaddr_offset; | ||
2055 | } else { | ||
2056 | intel_crtc->dspaddr_offset = linear_offset; | ||
2057 | } | ||
2058 | |||
2059 | DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", | ||
2060 | obj->gtt_offset, linear_offset, x, y, fb->pitches[0]); | ||
1888 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 2061 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
1889 | if (INTEL_INFO(dev)->gen >= 4) { | 2062 | if (INTEL_INFO(dev)->gen >= 4) { |
1890 | I915_MODIFY_DISPBASE(DSPSURF(plane), Start); | 2063 | I915_MODIFY_DISPBASE(DSPSURF(plane), |
2064 | obj->gtt_offset + intel_crtc->dspaddr_offset); | ||
1891 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); | 2065 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
1892 | I915_WRITE(DSPADDR(plane), Offset); | 2066 | I915_WRITE(DSPLINOFF(plane), linear_offset); |
1893 | } else | 2067 | } else |
1894 | I915_WRITE(DSPADDR(plane), Start + Offset); | 2068 | I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset); |
1895 | POSTING_READ(reg); | 2069 | POSTING_READ(reg); |
1896 | 2070 | ||
1897 | return 0; | 2071 | return 0; |
@@ -1906,7 +2080,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, | |||
1906 | struct intel_framebuffer *intel_fb; | 2080 | struct intel_framebuffer *intel_fb; |
1907 | struct drm_i915_gem_object *obj; | 2081 | struct drm_i915_gem_object *obj; |
1908 | int plane = intel_crtc->plane; | 2082 | int plane = intel_crtc->plane; |
1909 | unsigned long Start, Offset; | 2083 | unsigned long linear_offset; |
1910 | u32 dspcntr; | 2084 | u32 dspcntr; |
1911 | u32 reg; | 2085 | u32 reg; |
1912 | 2086 | ||
@@ -1961,15 +2135,20 @@ static int ironlake_update_plane(struct drm_crtc *crtc, | |||
1961 | 2135 | ||
1962 | I915_WRITE(reg, dspcntr); | 2136 | I915_WRITE(reg, dspcntr); |
1963 | 2137 | ||
1964 | Start = obj->gtt_offset; | 2138 | linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
1965 | Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); | 2139 | intel_crtc->dspaddr_offset = |
2140 | gen4_compute_dspaddr_offset_xtiled(&x, &y, | ||
2141 | fb->bits_per_pixel / 8, | ||
2142 | fb->pitches[0]); | ||
2143 | linear_offset -= intel_crtc->dspaddr_offset; | ||
1966 | 2144 | ||
1967 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | 2145 | DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", |
1968 | Start, Offset, x, y, fb->pitches[0]); | 2146 | obj->gtt_offset, linear_offset, x, y, fb->pitches[0]); |
1969 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 2147 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
1970 | I915_MODIFY_DISPBASE(DSPSURF(plane), Start); | 2148 | I915_MODIFY_DISPBASE(DSPSURF(plane), |
2149 | obj->gtt_offset + intel_crtc->dspaddr_offset); | ||
1971 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); | 2150 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
1972 | I915_WRITE(DSPADDR(plane), Offset); | 2151 | I915_WRITE(DSPLINOFF(plane), linear_offset); |
1973 | POSTING_READ(reg); | 2152 | POSTING_READ(reg); |
1974 | 2153 | ||
1975 | return 0; | 2154 | return 0; |
@@ -2656,16 +2835,13 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) | |||
2656 | static bool intel_crtc_driving_pch(struct drm_crtc *crtc) | 2835 | static bool intel_crtc_driving_pch(struct drm_crtc *crtc) |
2657 | { | 2836 | { |
2658 | struct drm_device *dev = crtc->dev; | 2837 | struct drm_device *dev = crtc->dev; |
2659 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
2660 | struct intel_encoder *encoder; | 2838 | struct intel_encoder *encoder; |
2661 | 2839 | ||
2662 | /* | 2840 | /* |
2663 | * If there's a non-PCH eDP on this crtc, it must be DP_A, and that | 2841 | * If there's a non-PCH eDP on this crtc, it must be DP_A, and that |
2664 | * must be driven by its own crtc; no sharing is possible. | 2842 | * must be driven by its own crtc; no sharing is possible. |
2665 | */ | 2843 | */ |
2666 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { | 2844 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
2667 | if (encoder->base.crtc != crtc) | ||
2668 | continue; | ||
2669 | 2845 | ||
2670 | /* On Haswell, LPT PCH handles the VGA connection via FDI, and Haswell | 2846 | /* On Haswell, LPT PCH handles the VGA connection via FDI, and Haswell |
2671 | * CPU handles all others */ | 2847 | * CPU handles all others */ |
@@ -3397,7 +3573,7 @@ void intel_encoder_destroy(struct drm_encoder *encoder) | |||
3397 | } | 3573 | } |
3398 | 3574 | ||
3399 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 3575 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
3400 | struct drm_display_mode *mode, | 3576 | const struct drm_display_mode *mode, |
3401 | struct drm_display_mode *adjusted_mode) | 3577 | struct drm_display_mode *adjusted_mode) |
3402 | { | 3578 | { |
3403 | struct drm_device *dev = crtc->dev; | 3579 | struct drm_device *dev = crtc->dev; |
@@ -3554,16 +3730,12 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
3554 | { | 3730 | { |
3555 | struct drm_device *dev = crtc->dev; | 3731 | struct drm_device *dev = crtc->dev; |
3556 | struct drm_i915_private *dev_priv = dev->dev_private; | 3732 | struct drm_i915_private *dev_priv = dev->dev_private; |
3557 | struct drm_encoder *encoder; | ||
3558 | struct drm_connector *connector; | 3733 | struct drm_connector *connector; |
3734 | struct intel_encoder *intel_encoder; | ||
3559 | unsigned int display_bpc = UINT_MAX, bpc; | 3735 | unsigned int display_bpc = UINT_MAX, bpc; |
3560 | 3736 | ||
3561 | /* Walk the encoders & connectors on this crtc, get min bpc */ | 3737 | /* Walk the encoders & connectors on this crtc, get min bpc */ |
3562 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 3738 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
3563 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | ||
3564 | |||
3565 | if (encoder->crtc != crtc) | ||
3566 | continue; | ||
3567 | 3739 | ||
3568 | if (intel_encoder->type == INTEL_OUTPUT_LVDS) { | 3740 | if (intel_encoder->type == INTEL_OUTPUT_LVDS) { |
3569 | unsigned int lvds_bpc; | 3741 | unsigned int lvds_bpc; |
@@ -3595,7 +3767,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
3595 | /* Not one of the known troublemakers, check the EDID */ | 3767 | /* Not one of the known troublemakers, check the EDID */ |
3596 | list_for_each_entry(connector, &dev->mode_config.connector_list, | 3768 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
3597 | head) { | 3769 | head) { |
3598 | if (connector->encoder != encoder) | 3770 | if (connector->encoder != &intel_encoder->base) |
3599 | continue; | 3771 | continue; |
3600 | 3772 | ||
3601 | /* Don't use an invalid EDID bpc value */ | 3773 | /* Don't use an invalid EDID bpc value */ |
@@ -3666,13 +3838,37 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
3666 | return display_bpc != bpc; | 3838 | return display_bpc != bpc; |
3667 | } | 3839 | } |
3668 | 3840 | ||
3841 | static int vlv_get_refclk(struct drm_crtc *crtc) | ||
3842 | { | ||
3843 | struct drm_device *dev = crtc->dev; | ||
3844 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3845 | int refclk = 27000; /* for DP & HDMI */ | ||
3846 | |||
3847 | return 100000; /* only one validated so far */ | ||
3848 | |||
3849 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { | ||
3850 | refclk = 96000; | ||
3851 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | ||
3852 | if (intel_panel_use_ssc(dev_priv)) | ||
3853 | refclk = 100000; | ||
3854 | else | ||
3855 | refclk = 96000; | ||
3856 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { | ||
3857 | refclk = 100000; | ||
3858 | } | ||
3859 | |||
3860 | return refclk; | ||
3861 | } | ||
3862 | |||
3669 | static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) | 3863 | static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) |
3670 | { | 3864 | { |
3671 | struct drm_device *dev = crtc->dev; | 3865 | struct drm_device *dev = crtc->dev; |
3672 | struct drm_i915_private *dev_priv = dev->dev_private; | 3866 | struct drm_i915_private *dev_priv = dev->dev_private; |
3673 | int refclk; | 3867 | int refclk; |
3674 | 3868 | ||
3675 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | 3869 | if (IS_VALLEYVIEW(dev)) { |
3870 | refclk = vlv_get_refclk(crtc); | ||
3871 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | ||
3676 | intel_panel_use_ssc(dev_priv) && num_connectors < 2) { | 3872 | intel_panel_use_ssc(dev_priv) && num_connectors < 2) { |
3677 | refclk = dev_priv->lvds_ssc_freq * 1000; | 3873 | refclk = dev_priv->lvds_ssc_freq * 1000; |
3678 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", | 3874 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", |
@@ -3787,6 +3983,72 @@ static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock, | |||
3787 | I915_WRITE(LVDS, temp); | 3983 | I915_WRITE(LVDS, temp); |
3788 | } | 3984 | } |
3789 | 3985 | ||
3986 | static void vlv_update_pll(struct drm_crtc *crtc, | ||
3987 | struct drm_display_mode *mode, | ||
3988 | struct drm_display_mode *adjusted_mode, | ||
3989 | intel_clock_t *clock, intel_clock_t *reduced_clock, | ||
3990 | int refclk, int num_connectors) | ||
3991 | { | ||
3992 | struct drm_device *dev = crtc->dev; | ||
3993 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3994 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3995 | int pipe = intel_crtc->pipe; | ||
3996 | u32 dpll, mdiv, pdiv; | ||
3997 | u32 bestn, bestm1, bestm2, bestp1, bestp2; | ||
3998 | bool is_hdmi; | ||
3999 | |||
4000 | is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); | ||
4001 | |||
4002 | bestn = clock->n; | ||
4003 | bestm1 = clock->m1; | ||
4004 | bestm2 = clock->m2; | ||
4005 | bestp1 = clock->p1; | ||
4006 | bestp2 = clock->p2; | ||
4007 | |||
4008 | /* Enable DPIO clock input */ | ||
4009 | dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | | ||
4010 | DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; | ||
4011 | I915_WRITE(DPLL(pipe), dpll); | ||
4012 | POSTING_READ(DPLL(pipe)); | ||
4013 | |||
4014 | mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); | ||
4015 | mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); | ||
4016 | mdiv |= ((bestn << DPIO_N_SHIFT)); | ||
4017 | mdiv |= (1 << DPIO_POST_DIV_SHIFT); | ||
4018 | mdiv |= (1 << DPIO_K_SHIFT); | ||
4019 | mdiv |= DPIO_ENABLE_CALIBRATION; | ||
4020 | intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); | ||
4021 | |||
4022 | intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000); | ||
4023 | |||
4024 | pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) | | ||
4025 | (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) | | ||
4026 | (8 << DPIO_DRIVER_CTL_SHIFT) | (5 << DPIO_CLK_BIAS_CTL_SHIFT); | ||
4027 | intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv); | ||
4028 | |||
4029 | intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051); | ||
4030 | |||
4031 | dpll |= DPLL_VCO_ENABLE; | ||
4032 | I915_WRITE(DPLL(pipe), dpll); | ||
4033 | POSTING_READ(DPLL(pipe)); | ||
4034 | if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) | ||
4035 | DRM_ERROR("DPLL %d failed to lock\n", pipe); | ||
4036 | |||
4037 | if (is_hdmi) { | ||
4038 | u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
4039 | |||
4040 | if (temp > 1) | ||
4041 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; | ||
4042 | else | ||
4043 | temp = 0; | ||
4044 | |||
4045 | I915_WRITE(DPLL_MD(pipe), temp); | ||
4046 | POSTING_READ(DPLL_MD(pipe)); | ||
4047 | } | ||
4048 | |||
4049 | intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */ | ||
4050 | } | ||
4051 | |||
3790 | static void i9xx_update_pll(struct drm_crtc *crtc, | 4052 | static void i9xx_update_pll(struct drm_crtc *crtc, |
3791 | struct drm_display_mode *mode, | 4053 | struct drm_display_mode *mode, |
3792 | struct drm_display_mode *adjusted_mode, | 4054 | struct drm_display_mode *adjusted_mode, |
@@ -3974,15 +4236,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
3974 | u32 dspcntr, pipeconf, vsyncshift; | 4236 | u32 dspcntr, pipeconf, vsyncshift; |
3975 | bool ok, has_reduced_clock = false, is_sdvo = false; | 4237 | bool ok, has_reduced_clock = false, is_sdvo = false; |
3976 | bool is_lvds = false, is_tv = false, is_dp = false; | 4238 | bool is_lvds = false, is_tv = false, is_dp = false; |
3977 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
3978 | struct intel_encoder *encoder; | 4239 | struct intel_encoder *encoder; |
3979 | const intel_limit_t *limit; | 4240 | const intel_limit_t *limit; |
3980 | int ret; | 4241 | int ret; |
3981 | 4242 | ||
3982 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { | 4243 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
3983 | if (encoder->base.crtc != crtc) | ||
3984 | continue; | ||
3985 | |||
3986 | switch (encoder->type) { | 4244 | switch (encoder->type) { |
3987 | case INTEL_OUTPUT_LVDS: | 4245 | case INTEL_OUTPUT_LVDS: |
3988 | is_lvds = true; | 4246 | is_lvds = true; |
@@ -4044,6 +4302,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
4044 | 4302 | ||
4045 | if (IS_GEN2(dev)) | 4303 | if (IS_GEN2(dev)) |
4046 | i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors); | 4304 | i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors); |
4305 | else if (IS_VALLEYVIEW(dev)) | ||
4306 | vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL, | ||
4307 | refclk, num_connectors); | ||
4047 | else | 4308 | else |
4048 | i9xx_update_pll(crtc, mode, adjusted_mode, &clock, | 4309 | i9xx_update_pll(crtc, mode, adjusted_mode, &clock, |
4049 | has_reduced_clock ? &reduced_clock : NULL, | 4310 | has_reduced_clock ? &reduced_clock : NULL, |
@@ -4282,15 +4543,11 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) | |||
4282 | struct drm_device *dev = crtc->dev; | 4543 | struct drm_device *dev = crtc->dev; |
4283 | struct drm_i915_private *dev_priv = dev->dev_private; | 4544 | struct drm_i915_private *dev_priv = dev->dev_private; |
4284 | struct intel_encoder *encoder; | 4545 | struct intel_encoder *encoder; |
4285 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
4286 | struct intel_encoder *edp_encoder = NULL; | 4546 | struct intel_encoder *edp_encoder = NULL; |
4287 | int num_connectors = 0; | 4547 | int num_connectors = 0; |
4288 | bool is_lvds = false; | 4548 | bool is_lvds = false; |
4289 | 4549 | ||
4290 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { | 4550 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
4291 | if (encoder->base.crtc != crtc) | ||
4292 | continue; | ||
4293 | |||
4294 | switch (encoder->type) { | 4551 | switch (encoder->type) { |
4295 | case INTEL_OUTPUT_LVDS: | 4552 | case INTEL_OUTPUT_LVDS: |
4296 | is_lvds = true; | 4553 | is_lvds = true; |
@@ -4327,7 +4584,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4327 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; | 4584 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; |
4328 | bool ok, has_reduced_clock = false, is_sdvo = false; | 4585 | bool ok, has_reduced_clock = false, is_sdvo = false; |
4329 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 4586 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
4330 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
4331 | struct intel_encoder *encoder, *edp_encoder = NULL; | 4587 | struct intel_encoder *encoder, *edp_encoder = NULL; |
4332 | const intel_limit_t *limit; | 4588 | const intel_limit_t *limit; |
4333 | int ret; | 4589 | int ret; |
@@ -4338,10 +4594,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4338 | bool dither; | 4594 | bool dither; |
4339 | bool is_cpu_edp = false, is_pch_edp = false; | 4595 | bool is_cpu_edp = false, is_pch_edp = false; |
4340 | 4596 | ||
4341 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { | 4597 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
4342 | if (encoder->base.crtc != crtc) | ||
4343 | continue; | ||
4344 | |||
4345 | switch (encoder->type) { | 4598 | switch (encoder->type) { |
4346 | case INTEL_OUTPUT_LVDS: | 4599 | case INTEL_OUTPUT_LVDS: |
4347 | is_lvds = true; | 4600 | is_lvds = true; |
@@ -4405,25 +4658,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4405 | &clock, | 4658 | &clock, |
4406 | &reduced_clock); | 4659 | &reduced_clock); |
4407 | } | 4660 | } |
4408 | /* SDVO TV has fixed PLL values depend on its clock range, | 4661 | |
4409 | this mirrors vbios setting. */ | 4662 | if (is_sdvo && is_tv) |
4410 | if (is_sdvo && is_tv) { | 4663 | i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); |
4411 | if (adjusted_mode->clock >= 100000 | 4664 | |
4412 | && adjusted_mode->clock < 140500) { | ||
4413 | clock.p1 = 2; | ||
4414 | clock.p2 = 10; | ||
4415 | clock.n = 3; | ||
4416 | clock.m1 = 16; | ||
4417 | clock.m2 = 8; | ||
4418 | } else if (adjusted_mode->clock >= 140500 | ||
4419 | && adjusted_mode->clock <= 200000) { | ||
4420 | clock.p1 = 1; | ||
4421 | clock.p2 = 10; | ||
4422 | clock.n = 6; | ||
4423 | clock.m1 = 12; | ||
4424 | clock.m2 = 8; | ||
4425 | } | ||
4426 | } | ||
4427 | 4665 | ||
4428 | /* FDI link */ | 4666 | /* FDI link */ |
4429 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | 4667 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
@@ -4431,16 +4669,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4431 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 4669 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
4432 | according to current link config */ | 4670 | according to current link config */ |
4433 | if (is_cpu_edp) { | 4671 | if (is_cpu_edp) { |
4434 | target_clock = mode->clock; | ||
4435 | intel_edp_link_config(edp_encoder, &lane, &link_bw); | 4672 | intel_edp_link_config(edp_encoder, &lane, &link_bw); |
4436 | } else { | 4673 | } else { |
4437 | /* [e]DP over FDI requires target mode clock | ||
4438 | instead of link clock */ | ||
4439 | if (is_dp) | ||
4440 | target_clock = mode->clock; | ||
4441 | else | ||
4442 | target_clock = adjusted_mode->clock; | ||
4443 | |||
4444 | /* FDI is a binary signal running at ~2.7GHz, encoding | 4674 | /* FDI is a binary signal running at ~2.7GHz, encoding |
4445 | * each output octet as 10 bits. The actual frequency | 4675 | * each output octet as 10 bits. The actual frequency |
4446 | * is stored as a divider into a 100MHz clock, and the | 4676 | * is stored as a divider into a 100MHz clock, and the |
@@ -4451,6 +4681,14 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4451 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; | 4681 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; |
4452 | } | 4682 | } |
4453 | 4683 | ||
4684 | /* [e]DP over FDI requires target mode clock instead of link clock. */ | ||
4685 | if (edp_encoder) | ||
4686 | target_clock = intel_edp_target_clock(edp_encoder, mode); | ||
4687 | else if (is_dp) | ||
4688 | target_clock = mode->clock; | ||
4689 | else | ||
4690 | target_clock = adjusted_mode->clock; | ||
4691 | |||
4454 | /* determine panel color depth */ | 4692 | /* determine panel color depth */ |
4455 | temp = I915_READ(PIPECONF(pipe)); | 4693 | temp = I915_READ(PIPECONF(pipe)); |
4456 | temp &= ~PIPE_BPC_MASK; | 4694 | temp &= ~PIPE_BPC_MASK; |
@@ -4662,16 +4900,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4662 | if (is_lvds && has_reduced_clock && i915_powersave) { | 4900 | if (is_lvds && has_reduced_clock && i915_powersave) { |
4663 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); | 4901 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); |
4664 | intel_crtc->lowfreq_avail = true; | 4902 | intel_crtc->lowfreq_avail = true; |
4665 | if (HAS_PIPE_CXSR(dev)) { | ||
4666 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); | ||
4667 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; | ||
4668 | } | ||
4669 | } else { | 4903 | } else { |
4670 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); | 4904 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); |
4671 | if (HAS_PIPE_CXSR(dev)) { | ||
4672 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); | ||
4673 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; | ||
4674 | } | ||
4675 | } | 4905 | } |
4676 | } | 4906 | } |
4677 | 4907 | ||
@@ -5975,7 +6205,6 @@ static int intel_gen2_queue_flip(struct drm_device *dev, | |||
5975 | { | 6205 | { |
5976 | struct drm_i915_private *dev_priv = dev->dev_private; | 6206 | struct drm_i915_private *dev_priv = dev->dev_private; |
5977 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 6207 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5978 | unsigned long offset; | ||
5979 | u32 flip_mask; | 6208 | u32 flip_mask; |
5980 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 6209 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
5981 | int ret; | 6210 | int ret; |
@@ -5984,9 +6213,6 @@ static int intel_gen2_queue_flip(struct drm_device *dev, | |||
5984 | if (ret) | 6213 | if (ret) |
5985 | goto err; | 6214 | goto err; |
5986 | 6215 | ||
5987 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | ||
5988 | offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; | ||
5989 | |||
5990 | ret = intel_ring_begin(ring, 6); | 6216 | ret = intel_ring_begin(ring, 6); |
5991 | if (ret) | 6217 | if (ret) |
5992 | goto err_unpin; | 6218 | goto err_unpin; |
@@ -6003,7 +6229,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, | |||
6003 | intel_ring_emit(ring, MI_DISPLAY_FLIP | | 6229 | intel_ring_emit(ring, MI_DISPLAY_FLIP | |
6004 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 6230 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
6005 | intel_ring_emit(ring, fb->pitches[0]); | 6231 | intel_ring_emit(ring, fb->pitches[0]); |
6006 | intel_ring_emit(ring, obj->gtt_offset + offset); | 6232 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
6007 | intel_ring_emit(ring, 0); /* aux display base address, unused */ | 6233 | intel_ring_emit(ring, 0); /* aux display base address, unused */ |
6008 | intel_ring_advance(ring); | 6234 | intel_ring_advance(ring); |
6009 | return 0; | 6235 | return 0; |
@@ -6021,7 +6247,6 @@ static int intel_gen3_queue_flip(struct drm_device *dev, | |||
6021 | { | 6247 | { |
6022 | struct drm_i915_private *dev_priv = dev->dev_private; | 6248 | struct drm_i915_private *dev_priv = dev->dev_private; |
6023 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 6249 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
6024 | unsigned long offset; | ||
6025 | u32 flip_mask; | 6250 | u32 flip_mask; |
6026 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 6251 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
6027 | int ret; | 6252 | int ret; |
@@ -6030,9 +6255,6 @@ static int intel_gen3_queue_flip(struct drm_device *dev, | |||
6030 | if (ret) | 6255 | if (ret) |
6031 | goto err; | 6256 | goto err; |
6032 | 6257 | ||
6033 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | ||
6034 | offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; | ||
6035 | |||
6036 | ret = intel_ring_begin(ring, 6); | 6258 | ret = intel_ring_begin(ring, 6); |
6037 | if (ret) | 6259 | if (ret) |
6038 | goto err_unpin; | 6260 | goto err_unpin; |
@@ -6046,7 +6268,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev, | |||
6046 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | | 6268 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | |
6047 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 6269 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
6048 | intel_ring_emit(ring, fb->pitches[0]); | 6270 | intel_ring_emit(ring, fb->pitches[0]); |
6049 | intel_ring_emit(ring, obj->gtt_offset + offset); | 6271 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
6050 | intel_ring_emit(ring, MI_NOOP); | 6272 | intel_ring_emit(ring, MI_NOOP); |
6051 | 6273 | ||
6052 | intel_ring_advance(ring); | 6274 | intel_ring_advance(ring); |
@@ -6084,7 +6306,9 @@ static int intel_gen4_queue_flip(struct drm_device *dev, | |||
6084 | intel_ring_emit(ring, MI_DISPLAY_FLIP | | 6306 | intel_ring_emit(ring, MI_DISPLAY_FLIP | |
6085 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 6307 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
6086 | intel_ring_emit(ring, fb->pitches[0]); | 6308 | intel_ring_emit(ring, fb->pitches[0]); |
6087 | intel_ring_emit(ring, obj->gtt_offset | obj->tiling_mode); | 6309 | intel_ring_emit(ring, |
6310 | (obj->gtt_offset + intel_crtc->dspaddr_offset) | | ||
6311 | obj->tiling_mode); | ||
6088 | 6312 | ||
6089 | /* XXX Enabling the panel-fitter across page-flip is so far | 6313 | /* XXX Enabling the panel-fitter across page-flip is so far |
6090 | * untested on non-native modes, so ignore it for now. | 6314 | * untested on non-native modes, so ignore it for now. |
@@ -6124,7 +6348,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, | |||
6124 | intel_ring_emit(ring, MI_DISPLAY_FLIP | | 6348 | intel_ring_emit(ring, MI_DISPLAY_FLIP | |
6125 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 6349 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
6126 | intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); | 6350 | intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); |
6127 | intel_ring_emit(ring, obj->gtt_offset); | 6351 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
6128 | 6352 | ||
6129 | /* Contrary to the suggestions in the documentation, | 6353 | /* Contrary to the suggestions in the documentation, |
6130 | * "Enable Panel Fitter" does not seem to be required when page | 6354 | * "Enable Panel Fitter" does not seem to be required when page |
@@ -6187,7 +6411,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, | |||
6187 | 6411 | ||
6188 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); | 6412 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); |
6189 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); | 6413 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); |
6190 | intel_ring_emit(ring, (obj->gtt_offset)); | 6414 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
6191 | intel_ring_emit(ring, (MI_NOOP)); | 6415 | intel_ring_emit(ring, (MI_NOOP)); |
6192 | intel_ring_advance(ring); | 6416 | intel_ring_advance(ring); |
6193 | return 0; | 6417 | return 0; |
@@ -6219,6 +6443,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6219 | unsigned long flags; | 6443 | unsigned long flags; |
6220 | int ret; | 6444 | int ret; |
6221 | 6445 | ||
6446 | /* Can't change pixel format via MI display flips. */ | ||
6447 | if (fb->pixel_format != crtc->fb->pixel_format) | ||
6448 | return -EINVAL; | ||
6449 | |||
6450 | /* | ||
6451 | * TILEOFF/LINOFF registers can't be changed via MI display flips. | ||
6452 | * Note that pitch changes could also affect these register. | ||
6453 | */ | ||
6454 | if (INTEL_INFO(dev)->gen > 3 && | ||
6455 | (fb->offsets[0] != crtc->fb->offsets[0] || | ||
6456 | fb->pitches[0] != crtc->fb->pitches[0])) | ||
6457 | return -EINVAL; | ||
6458 | |||
6222 | work = kzalloc(sizeof *work, GFP_KERNEL); | 6459 | work = kzalloc(sizeof *work, GFP_KERNEL); |
6223 | if (work == NULL) | 6460 | if (work == NULL) |
6224 | return -ENOMEM; | 6461 | return -ENOMEM; |
@@ -6249,7 +6486,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6249 | intel_fb = to_intel_framebuffer(fb); | 6486 | intel_fb = to_intel_framebuffer(fb); |
6250 | obj = intel_fb->obj; | 6487 | obj = intel_fb->obj; |
6251 | 6488 | ||
6252 | mutex_lock(&dev->struct_mutex); | 6489 | ret = i915_mutex_lock_interruptible(dev); |
6490 | if (ret) | ||
6491 | goto cleanup; | ||
6253 | 6492 | ||
6254 | /* Reference the objects for the scheduled work. */ | 6493 | /* Reference the objects for the scheduled work. */ |
6255 | drm_gem_object_reference(&work->old_fb_obj->base); | 6494 | drm_gem_object_reference(&work->old_fb_obj->base); |
@@ -6284,6 +6523,7 @@ cleanup_pending: | |||
6284 | drm_gem_object_unreference(&obj->base); | 6523 | drm_gem_object_unreference(&obj->base); |
6285 | mutex_unlock(&dev->struct_mutex); | 6524 | mutex_unlock(&dev->struct_mutex); |
6286 | 6525 | ||
6526 | cleanup: | ||
6287 | spin_lock_irqsave(&dev->event_lock, flags); | 6527 | spin_lock_irqsave(&dev->event_lock, flags); |
6288 | intel_crtc->unpin_work = NULL; | 6528 | intel_crtc->unpin_work = NULL; |
6289 | spin_unlock_irqrestore(&dev->event_lock, flags); | 6529 | spin_unlock_irqrestore(&dev->event_lock, flags); |
@@ -6566,7 +6806,24 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
6566 | 6806 | ||
6567 | if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) | 6807 | if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) |
6568 | intel_dp_init(dev, PCH_DP_D); | 6808 | intel_dp_init(dev, PCH_DP_D); |
6809 | } else if (IS_VALLEYVIEW(dev)) { | ||
6810 | int found; | ||
6569 | 6811 | ||
6812 | if (I915_READ(SDVOB) & PORT_DETECTED) { | ||
6813 | /* SDVOB multiplex with HDMIB */ | ||
6814 | found = intel_sdvo_init(dev, SDVOB, true); | ||
6815 | if (!found) | ||
6816 | intel_hdmi_init(dev, SDVOB); | ||
6817 | if (!found && (I915_READ(DP_B) & DP_DETECTED)) | ||
6818 | intel_dp_init(dev, DP_B); | ||
6819 | } | ||
6820 | |||
6821 | if (I915_READ(SDVOC) & PORT_DETECTED) | ||
6822 | intel_hdmi_init(dev, SDVOC); | ||
6823 | |||
6824 | /* Shares lanes with HDMI on SDVOC */ | ||
6825 | if (I915_READ(DP_C) & DP_DETECTED) | ||
6826 | intel_dp_init(dev, DP_C); | ||
6570 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { | 6827 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { |
6571 | bool found = false; | 6828 | bool found = false; |
6572 | 6829 | ||
@@ -6623,7 +6880,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
6623 | /* disable all the possible outputs/crtcs before entering KMS mode */ | 6880 | /* disable all the possible outputs/crtcs before entering KMS mode */ |
6624 | drm_helper_disable_unused_functions(dev); | 6881 | drm_helper_disable_unused_functions(dev); |
6625 | 6882 | ||
6626 | if (HAS_PCH_SPLIT(dev)) | 6883 | if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) |
6627 | ironlake_init_pch_refclk(dev); | 6884 | ironlake_init_pch_refclk(dev); |
6628 | } | 6885 | } |
6629 | 6886 | ||
@@ -6777,9 +7034,6 @@ static void intel_init_display(struct drm_device *dev) | |||
6777 | dev_priv->display.write_eld = ironlake_write_eld; | 7034 | dev_priv->display.write_eld = ironlake_write_eld; |
6778 | } else | 7035 | } else |
6779 | dev_priv->display.update_wm = NULL; | 7036 | dev_priv->display.update_wm = NULL; |
6780 | } else if (IS_VALLEYVIEW(dev)) { | ||
6781 | dev_priv->display.force_wake_get = vlv_force_wake_get; | ||
6782 | dev_priv->display.force_wake_put = vlv_force_wake_put; | ||
6783 | } else if (IS_G4X(dev)) { | 7037 | } else if (IS_G4X(dev)) { |
6784 | dev_priv->display.write_eld = g4x_write_eld; | 7038 | dev_priv->display.write_eld = g4x_write_eld; |
6785 | } | 7039 | } |
@@ -6923,20 +7177,18 @@ static void i915_disable_vga(struct drm_device *dev) | |||
6923 | 7177 | ||
6924 | void intel_modeset_init_hw(struct drm_device *dev) | 7178 | void intel_modeset_init_hw(struct drm_device *dev) |
6925 | { | 7179 | { |
6926 | struct drm_i915_private *dev_priv = dev->dev_private; | 7180 | /* We attempt to init the necessary power wells early in the initialization |
7181 | * time, so the subsystems that expect power to be enabled can work. | ||
7182 | */ | ||
7183 | intel_init_power_wells(dev); | ||
6927 | 7184 | ||
6928 | intel_init_clock_gating(dev); | 7185 | intel_prepare_ddi(dev); |
6929 | 7186 | ||
6930 | if (IS_IRONLAKE_M(dev)) { | 7187 | intel_init_clock_gating(dev); |
6931 | ironlake_enable_drps(dev); | ||
6932 | ironlake_enable_rc6(dev); | ||
6933 | intel_init_emon(dev); | ||
6934 | } | ||
6935 | 7188 | ||
6936 | if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) { | 7189 | mutex_lock(&dev->struct_mutex); |
6937 | gen6_enable_rps(dev_priv); | 7190 | intel_enable_gt_powersave(dev); |
6938 | gen6_update_ring_freq(dev_priv); | 7191 | mutex_unlock(&dev->struct_mutex); |
6939 | } | ||
6940 | } | 7192 | } |
6941 | 7193 | ||
6942 | void intel_modeset_init(struct drm_device *dev) | 7194 | void intel_modeset_init(struct drm_device *dev) |
@@ -6958,8 +7210,6 @@ void intel_modeset_init(struct drm_device *dev) | |||
6958 | 7210 | ||
6959 | intel_init_pm(dev); | 7211 | intel_init_pm(dev); |
6960 | 7212 | ||
6961 | intel_prepare_ddi(dev); | ||
6962 | |||
6963 | intel_init_display(dev); | 7213 | intel_init_display(dev); |
6964 | 7214 | ||
6965 | if (IS_GEN2(dev)) { | 7215 | if (IS_GEN2(dev)) { |
@@ -6972,7 +7222,7 @@ void intel_modeset_init(struct drm_device *dev) | |||
6972 | dev->mode_config.max_width = 8192; | 7222 | dev->mode_config.max_width = 8192; |
6973 | dev->mode_config.max_height = 8192; | 7223 | dev->mode_config.max_height = 8192; |
6974 | } | 7224 | } |
6975 | dev->mode_config.fb_base = dev->agp->base; | 7225 | dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr; |
6976 | 7226 | ||
6977 | DRM_DEBUG_KMS("%d display pipe%s available.\n", | 7227 | DRM_DEBUG_KMS("%d display pipe%s available.\n", |
6978 | dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); | 7228 | dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); |
@@ -7025,13 +7275,9 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
7025 | 7275 | ||
7026 | intel_disable_fbc(dev); | 7276 | intel_disable_fbc(dev); |
7027 | 7277 | ||
7028 | if (IS_IRONLAKE_M(dev)) | 7278 | intel_disable_gt_powersave(dev); |
7029 | ironlake_disable_drps(dev); | ||
7030 | if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) | ||
7031 | gen6_disable_rps(dev); | ||
7032 | 7279 | ||
7033 | if (IS_IRONLAKE_M(dev)) | 7280 | ironlake_teardown_rc6(dev); |
7034 | ironlake_disable_rc6(dev); | ||
7035 | 7281 | ||
7036 | if (IS_VALLEYVIEW(dev)) | 7282 | if (IS_VALLEYVIEW(dev)) |
7037 | vlv_init_dpio(dev); | 7283 | vlv_init_dpio(dev); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c0449324143c..0a56b9ab0f58 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -155,6 +155,18 @@ intel_edp_link_config(struct intel_encoder *intel_encoder, | |||
155 | *link_bw = 270000; | 155 | *link_bw = 270000; |
156 | } | 156 | } |
157 | 157 | ||
158 | int | ||
159 | intel_edp_target_clock(struct intel_encoder *intel_encoder, | ||
160 | struct drm_display_mode *mode) | ||
161 | { | ||
162 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); | ||
163 | |||
164 | if (intel_dp->panel_fixed_mode) | ||
165 | return intel_dp->panel_fixed_mode->clock; | ||
166 | else | ||
167 | return mode->clock; | ||
168 | } | ||
169 | |||
158 | static int | 170 | static int |
159 | intel_dp_max_lane_count(struct intel_dp *intel_dp) | 171 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
160 | { | 172 | { |
@@ -225,7 +237,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) | |||
225 | static bool | 237 | static bool |
226 | intel_dp_adjust_dithering(struct intel_dp *intel_dp, | 238 | intel_dp_adjust_dithering(struct intel_dp *intel_dp, |
227 | struct drm_display_mode *mode, | 239 | struct drm_display_mode *mode, |
228 | struct drm_display_mode *adjusted_mode) | 240 | bool adjust_mode) |
229 | { | 241 | { |
230 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | 242 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
231 | int max_lanes = intel_dp_max_lane_count(intel_dp); | 243 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
@@ -239,8 +251,8 @@ intel_dp_adjust_dithering(struct intel_dp *intel_dp, | |||
239 | if (mode_rate > max_rate) | 251 | if (mode_rate > max_rate) |
240 | return false; | 252 | return false; |
241 | 253 | ||
242 | if (adjusted_mode) | 254 | if (adjust_mode) |
243 | adjusted_mode->private_flags | 255 | mode->private_flags |
244 | |= INTEL_MODE_DP_FORCE_6BPC; | 256 | |= INTEL_MODE_DP_FORCE_6BPC; |
245 | 257 | ||
246 | return true; | 258 | return true; |
@@ -263,7 +275,7 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
263 | return MODE_PANEL; | 275 | return MODE_PANEL; |
264 | } | 276 | } |
265 | 277 | ||
266 | if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) | 278 | if (!intel_dp_adjust_dithering(intel_dp, mode, false)) |
267 | return MODE_CLOCK_HIGH; | 279 | return MODE_CLOCK_HIGH; |
268 | 280 | ||
269 | if (mode->clock < 10000) | 281 | if (mode->clock < 10000) |
@@ -691,7 +703,8 @@ intel_dp_i2c_init(struct intel_dp *intel_dp, | |||
691 | } | 703 | } |
692 | 704 | ||
693 | static bool | 705 | static bool |
694 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 706 | intel_dp_mode_fixup(struct drm_encoder *encoder, |
707 | const struct drm_display_mode *mode, | ||
695 | struct drm_display_mode *adjusted_mode) | 708 | struct drm_display_mode *adjusted_mode) |
696 | { | 709 | { |
697 | struct drm_device *dev = encoder->dev; | 710 | struct drm_device *dev = encoder->dev; |
@@ -706,28 +719,23 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
706 | intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode); | 719 | intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode); |
707 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, | 720 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, |
708 | mode, adjusted_mode); | 721 | mode, adjusted_mode); |
709 | /* | ||
710 | * the mode->clock is used to calculate the Data&Link M/N | ||
711 | * of the pipe. For the eDP the fixed clock should be used. | ||
712 | */ | ||
713 | mode->clock = intel_dp->panel_fixed_mode->clock; | ||
714 | } | 722 | } |
715 | 723 | ||
716 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) | 724 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) |
717 | return false; | 725 | return false; |
718 | 726 | ||
719 | DRM_DEBUG_KMS("DP link computation with max lane count %i " | 727 | DRM_DEBUG_KMS("DP link computation with max lane count %i " |
720 | "max bw %02x pixel clock %iKHz\n", | 728 | "max bw %02x pixel clock %iKHz\n", |
721 | max_lane_count, bws[max_clock], mode->clock); | 729 | max_lane_count, bws[max_clock], adjusted_mode->clock); |
722 | 730 | ||
723 | if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) | 731 | if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true)) |
724 | return false; | 732 | return false; |
725 | 733 | ||
726 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | 734 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; |
727 | mode_rate = intel_dp_link_required(mode->clock, bpp); | 735 | mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); |
728 | 736 | ||
729 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 737 | for (clock = 0; clock <= max_clock; clock++) { |
730 | for (clock = 0; clock <= max_clock; clock++) { | 738 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
731 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 739 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
732 | 740 | ||
733 | if (mode_rate <= link_avail) { | 741 | if (mode_rate <= link_avail) { |
@@ -786,8 +794,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
786 | struct drm_display_mode *adjusted_mode) | 794 | struct drm_display_mode *adjusted_mode) |
787 | { | 795 | { |
788 | struct drm_device *dev = crtc->dev; | 796 | struct drm_device *dev = crtc->dev; |
789 | struct drm_mode_config *mode_config = &dev->mode_config; | 797 | struct intel_encoder *encoder; |
790 | struct drm_encoder *encoder; | ||
791 | struct drm_i915_private *dev_priv = dev->dev_private; | 798 | struct drm_i915_private *dev_priv = dev->dev_private; |
792 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 799 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
793 | int lane_count = 4; | 800 | int lane_count = 4; |
@@ -797,13 +804,9 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
797 | /* | 804 | /* |
798 | * Find the lane count in the intel_encoder private | 805 | * Find the lane count in the intel_encoder private |
799 | */ | 806 | */ |
800 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 807 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
801 | struct intel_dp *intel_dp; | 808 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
802 | |||
803 | if (encoder->crtc != crtc) | ||
804 | continue; | ||
805 | 809 | ||
806 | intel_dp = enc_to_intel_dp(encoder); | ||
807 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || | 810 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || |
808 | intel_dp->base.type == INTEL_OUTPUT_EDP) | 811 | intel_dp->base.type == INTEL_OUTPUT_EDP) |
809 | { | 812 | { |
@@ -1768,7 +1771,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1768 | for (i = 0; i < intel_dp->lane_count; i++) | 1771 | for (i = 0; i < intel_dp->lane_count; i++) |
1769 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1772 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1770 | break; | 1773 | break; |
1771 | if (i == intel_dp->lane_count) { | 1774 | if (i == intel_dp->lane_count && voltage_tries == 5) { |
1772 | ++loop_tries; | 1775 | ++loop_tries; |
1773 | if (loop_tries == 5) { | 1776 | if (loop_tries == 5) { |
1774 | DRM_DEBUG_KMS("too many full retries, give up\n"); | 1777 | DRM_DEBUG_KMS("too many full retries, give up\n"); |
@@ -1922,7 +1925,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1922 | DP |= DP_LINK_TRAIN_OFF; | 1925 | DP |= DP_LINK_TRAIN_OFF; |
1923 | } | 1926 | } |
1924 | 1927 | ||
1925 | if (!HAS_PCH_CPT(dev) && | 1928 | if (HAS_PCH_IBX(dev) && |
1926 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | 1929 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
1927 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 1930 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
1928 | 1931 | ||
@@ -2099,25 +2102,23 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
2099 | { | 2102 | { |
2100 | struct drm_device *dev = intel_dp->base.base.dev; | 2103 | struct drm_device *dev = intel_dp->base.base.dev; |
2101 | struct drm_i915_private *dev_priv = dev->dev_private; | 2104 | struct drm_i915_private *dev_priv = dev->dev_private; |
2102 | uint32_t temp, bit; | 2105 | uint32_t bit; |
2103 | 2106 | ||
2104 | switch (intel_dp->output_reg) { | 2107 | switch (intel_dp->output_reg) { |
2105 | case DP_B: | 2108 | case DP_B: |
2106 | bit = DPB_HOTPLUG_INT_STATUS; | 2109 | bit = DPB_HOTPLUG_LIVE_STATUS; |
2107 | break; | 2110 | break; |
2108 | case DP_C: | 2111 | case DP_C: |
2109 | bit = DPC_HOTPLUG_INT_STATUS; | 2112 | bit = DPC_HOTPLUG_LIVE_STATUS; |
2110 | break; | 2113 | break; |
2111 | case DP_D: | 2114 | case DP_D: |
2112 | bit = DPD_HOTPLUG_INT_STATUS; | 2115 | bit = DPD_HOTPLUG_LIVE_STATUS; |
2113 | break; | 2116 | break; |
2114 | default: | 2117 | default: |
2115 | return connector_status_unknown; | 2118 | return connector_status_unknown; |
2116 | } | 2119 | } |
2117 | 2120 | ||
2118 | temp = I915_READ(PORT_HOTPLUG_STAT); | 2121 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) |
2119 | |||
2120 | if ((temp & bit) == 0) | ||
2121 | return connector_status_disconnected; | 2122 | return connector_status_disconnected; |
2122 | 2123 | ||
2123 | return intel_dp_detect_dpcd(intel_dp); | 2124 | return intel_dp_detect_dpcd(intel_dp); |
@@ -2399,16 +2400,11 @@ int | |||
2399 | intel_trans_dp_port_sel(struct drm_crtc *crtc) | 2400 | intel_trans_dp_port_sel(struct drm_crtc *crtc) |
2400 | { | 2401 | { |
2401 | struct drm_device *dev = crtc->dev; | 2402 | struct drm_device *dev = crtc->dev; |
2402 | struct drm_mode_config *mode_config = &dev->mode_config; | 2403 | struct intel_encoder *encoder; |
2403 | struct drm_encoder *encoder; | ||
2404 | |||
2405 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | ||
2406 | struct intel_dp *intel_dp; | ||
2407 | 2404 | ||
2408 | if (encoder->crtc != crtc) | 2405 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
2409 | continue; | 2406 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2410 | 2407 | ||
2411 | intel_dp = enc_to_intel_dp(encoder); | ||
2412 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || | 2408 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || |
2413 | intel_dp->base.type == INTEL_OUTPUT_EDP) | 2409 | intel_dp->base.type == INTEL_OUTPUT_EDP) |
2414 | return intel_dp->output_reg; | 2410 | return intel_dp->output_reg; |
@@ -2520,19 +2516,19 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2520 | case DP_B: | 2516 | case DP_B: |
2521 | case PCH_DP_B: | 2517 | case PCH_DP_B: |
2522 | dev_priv->hotplug_supported_mask |= | 2518 | dev_priv->hotplug_supported_mask |= |
2523 | HDMIB_HOTPLUG_INT_STATUS; | 2519 | DPB_HOTPLUG_INT_STATUS; |
2524 | name = "DPDDC-B"; | 2520 | name = "DPDDC-B"; |
2525 | break; | 2521 | break; |
2526 | case DP_C: | 2522 | case DP_C: |
2527 | case PCH_DP_C: | 2523 | case PCH_DP_C: |
2528 | dev_priv->hotplug_supported_mask |= | 2524 | dev_priv->hotplug_supported_mask |= |
2529 | HDMIC_HOTPLUG_INT_STATUS; | 2525 | DPC_HOTPLUG_INT_STATUS; |
2530 | name = "DPDDC-C"; | 2526 | name = "DPDDC-C"; |
2531 | break; | 2527 | break; |
2532 | case DP_D: | 2528 | case DP_D: |
2533 | case PCH_DP_D: | 2529 | case PCH_DP_D: |
2534 | dev_priv->hotplug_supported_mask |= | 2530 | dev_priv->hotplug_supported_mask |= |
2535 | HDMID_HOTPLUG_INT_STATUS; | 2531 | DPD_HOTPLUG_INT_STATUS; |
2536 | name = "DPDDC-D"; | 2532 | name = "DPDDC-D"; |
2537 | break; | 2533 | break; |
2538 | } | 2534 | } |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3e0918834e7e..84353559441c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -169,6 +169,7 @@ struct intel_crtc { | |||
169 | u8 lut_r[256], lut_g[256], lut_b[256]; | 169 | u8 lut_r[256], lut_g[256], lut_b[256]; |
170 | int dpms_mode; | 170 | int dpms_mode; |
171 | bool active; /* is the crtc on? independent of the dpms mode */ | 171 | bool active; /* is the crtc on? independent of the dpms mode */ |
172 | bool primary_disabled; /* is the crtc obscured by a plane? */ | ||
172 | bool busy; /* is scanout buffer being updated frequently? */ | 173 | bool busy; /* is scanout buffer being updated frequently? */ |
173 | struct timer_list idle_timer; | 174 | struct timer_list idle_timer; |
174 | bool lowfreq_avail; | 175 | bool lowfreq_avail; |
@@ -176,6 +177,11 @@ struct intel_crtc { | |||
176 | struct intel_unpin_work *unpin_work; | 177 | struct intel_unpin_work *unpin_work; |
177 | int fdi_lanes; | 178 | int fdi_lanes; |
178 | 179 | ||
180 | /* Display surface base address adjustement for pageflips. Note that on | ||
181 | * gen4+ this only adjusts up to a tile, offsets within a tile are | ||
182 | * handled in the hw itself (with the TILEOFF register). */ | ||
183 | unsigned long dspaddr_offset; | ||
184 | |||
179 | struct drm_i915_gem_object *cursor_bo; | 185 | struct drm_i915_gem_object *cursor_bo; |
180 | uint32_t cursor_addr; | 186 | uint32_t cursor_addr; |
181 | int16_t cursor_x, cursor_y; | 187 | int16_t cursor_x, cursor_y; |
@@ -191,7 +197,6 @@ struct intel_plane { | |||
191 | struct drm_plane base; | 197 | struct drm_plane base; |
192 | enum pipe pipe; | 198 | enum pipe pipe; |
193 | struct drm_i915_gem_object *obj; | 199 | struct drm_i915_gem_object *obj; |
194 | bool primary_disabled; | ||
195 | int max_downscale; | 200 | int max_downscale; |
196 | u32 lut_r[1024], lut_g[1024], lut_b[1024]; | 201 | u32 lut_r[1024], lut_g[1024], lut_b[1024]; |
197 | void (*update_plane)(struct drm_plane *plane, | 202 | void (*update_plane)(struct drm_plane *plane, |
@@ -301,6 +306,8 @@ struct intel_hdmi { | |||
301 | enum hdmi_force_audio force_audio; | 306 | enum hdmi_force_audio force_audio; |
302 | void (*write_infoframe)(struct drm_encoder *encoder, | 307 | void (*write_infoframe)(struct drm_encoder *encoder, |
303 | struct dip_infoframe *frame); | 308 | struct dip_infoframe *frame); |
309 | void (*set_infoframes)(struct drm_encoder *encoder, | ||
310 | struct drm_display_mode *adjusted_mode); | ||
304 | }; | 311 | }; |
305 | 312 | ||
306 | static inline struct drm_crtc * | 313 | static inline struct drm_crtc * |
@@ -335,7 +342,6 @@ struct intel_fbc_work { | |||
335 | }; | 342 | }; |
336 | 343 | ||
337 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 344 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
338 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus); | ||
339 | 345 | ||
340 | extern void intel_attach_force_audio_property(struct drm_connector *connector); | 346 | extern void intel_attach_force_audio_property(struct drm_connector *connector); |
341 | extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); | 347 | extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); |
@@ -343,9 +349,6 @@ extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector) | |||
343 | extern void intel_crt_init(struct drm_device *dev); | 349 | extern void intel_crt_init(struct drm_device *dev); |
344 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); | 350 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); |
345 | extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); | 351 | extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); |
346 | extern void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | ||
347 | struct drm_display_mode *adjusted_mode); | ||
348 | extern void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder); | ||
349 | extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); | 352 | extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); |
350 | extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, | 353 | extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, |
351 | bool is_sdvob); | 354 | bool is_sdvob); |
@@ -360,6 +363,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
360 | struct drm_display_mode *adjusted_mode); | 363 | struct drm_display_mode *adjusted_mode); |
361 | extern bool intel_dpd_is_edp(struct drm_device *dev); | 364 | extern bool intel_dpd_is_edp(struct drm_device *dev); |
362 | extern void intel_edp_link_config(struct intel_encoder *, int *, int *); | 365 | extern void intel_edp_link_config(struct intel_encoder *, int *, int *); |
366 | extern int intel_edp_target_clock(struct intel_encoder *, | ||
367 | struct drm_display_mode *mode); | ||
363 | extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); | 368 | extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); |
364 | extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); | 369 | extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); |
365 | extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, | 370 | extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, |
@@ -372,13 +377,14 @@ extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | |||
372 | struct drm_display_mode *adjusted_mode); | 377 | struct drm_display_mode *adjusted_mode); |
373 | extern void intel_pch_panel_fitting(struct drm_device *dev, | 378 | extern void intel_pch_panel_fitting(struct drm_device *dev, |
374 | int fitting_mode, | 379 | int fitting_mode, |
375 | struct drm_display_mode *mode, | 380 | const struct drm_display_mode *mode, |
376 | struct drm_display_mode *adjusted_mode); | 381 | struct drm_display_mode *adjusted_mode); |
377 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 382 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
378 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | 383 | extern u32 intel_panel_get_backlight(struct drm_device *dev); |
379 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
380 | extern int intel_panel_setup_backlight(struct drm_device *dev); | 385 | extern int intel_panel_setup_backlight(struct drm_device *dev); |
381 | extern void intel_panel_enable_backlight(struct drm_device *dev); | 386 | extern void intel_panel_enable_backlight(struct drm_device *dev, |
387 | enum pipe pipe); | ||
382 | extern void intel_panel_disable_backlight(struct drm_device *dev); | 388 | extern void intel_panel_disable_backlight(struct drm_device *dev); |
383 | extern void intel_panel_destroy_backlight(struct drm_device *dev); | 389 | extern void intel_panel_destroy_backlight(struct drm_device *dev); |
384 | extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); | 390 | extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); |
@@ -423,9 +429,6 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |||
423 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | 429 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
424 | u16 *blue, int regno); | 430 | u16 *blue, int regno); |
425 | extern void intel_enable_clock_gating(struct drm_device *dev); | 431 | extern void intel_enable_clock_gating(struct drm_device *dev); |
426 | extern void ironlake_disable_rc6(struct drm_device *dev); | ||
427 | extern void ironlake_enable_drps(struct drm_device *dev); | ||
428 | extern void ironlake_disable_drps(struct drm_device *dev); | ||
429 | 432 | ||
430 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 433 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
431 | struct drm_i915_gem_object *obj, | 434 | struct drm_i915_gem_object *obj, |
@@ -492,10 +495,11 @@ extern void intel_update_fbc(struct drm_device *dev); | |||
492 | extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); | 495 | extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); |
493 | extern void intel_gpu_ips_teardown(void); | 496 | extern void intel_gpu_ips_teardown(void); |
494 | 497 | ||
495 | extern void gen6_enable_rps(struct drm_i915_private *dev_priv); | 498 | extern void intel_init_power_wells(struct drm_device *dev); |
496 | extern void gen6_update_ring_freq(struct drm_i915_private *dev_priv); | 499 | extern void intel_enable_gt_powersave(struct drm_device *dev); |
497 | extern void gen6_disable_rps(struct drm_device *dev); | 500 | extern void intel_disable_gt_powersave(struct drm_device *dev); |
498 | extern void intel_init_emon(struct drm_device *dev); | 501 | extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); |
502 | extern void ironlake_teardown_rc6(struct drm_device *dev); | ||
499 | 503 | ||
500 | extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode); | 504 | extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode); |
501 | extern void intel_ddi_mode_set(struct drm_encoder *encoder, | 505 | extern void intel_ddi_mode_set(struct drm_encoder *encoder, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 60ba50b956f2..36c542e5036b 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -136,7 +136,7 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | 138 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, |
139 | struct drm_display_mode *mode, | 139 | const struct drm_display_mode *mode, |
140 | struct drm_display_mode *adjusted_mode) | 140 | struct drm_display_mode *adjusted_mode) |
141 | { | 141 | { |
142 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | 142 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index bf8690720a0c..97f673523b97 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
65 | struct drm_i915_private *dev_priv = dev->dev_private; | 65 | struct drm_i915_private *dev_priv = dev->dev_private; |
66 | struct fb_info *info; | 66 | struct fb_info *info; |
67 | struct drm_framebuffer *fb; | 67 | struct drm_framebuffer *fb; |
68 | struct drm_mode_fb_cmd2 mode_cmd; | 68 | struct drm_mode_fb_cmd2 mode_cmd = {}; |
69 | struct drm_i915_gem_object *obj; | 69 | struct drm_i915_gem_object *obj; |
70 | struct device *device = &dev->pdev->dev; | 70 | struct device *device = &dev->pdev->dev; |
71 | int size, ret; | 71 | int size, ret; |
@@ -140,7 +140,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
140 | info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; | 140 | info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; |
141 | info->fix.smem_len = size; | 141 | info->fix.smem_len = size; |
142 | 142 | ||
143 | info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size); | 143 | info->screen_base = |
144 | ioremap_wc(dev_priv->mm.gtt_base_addr + obj->gtt_offset, | ||
145 | size); | ||
144 | if (!info->screen_base) { | 146 | if (!info->screen_base) { |
145 | ret = -ENOSPC; | 147 | ret = -ENOSPC; |
146 | goto out_unpin; | 148 | goto out_unpin; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2ead3bf7c21d..98f602427eb8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -37,6 +37,19 @@ | |||
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | 39 | ||
40 | static void | ||
41 | assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) | ||
42 | { | ||
43 | struct drm_device *dev = intel_hdmi->base.base.dev; | ||
44 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
45 | uint32_t enabled_bits; | ||
46 | |||
47 | enabled_bits = IS_HASWELL(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; | ||
48 | |||
49 | WARN(I915_READ(intel_hdmi->sdvox_reg) & enabled_bits, | ||
50 | "HDMI port enabled, expecting disabled\n"); | ||
51 | } | ||
52 | |||
40 | struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) | 53 | struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) |
41 | { | 54 | { |
42 | return container_of(encoder, struct intel_hdmi, base.base); | 55 | return container_of(encoder, struct intel_hdmi, base.base); |
@@ -121,36 +134,31 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, | |||
121 | uint32_t *data = (uint32_t *)frame; | 134 | uint32_t *data = (uint32_t *)frame; |
122 | struct drm_device *dev = encoder->dev; | 135 | struct drm_device *dev = encoder->dev; |
123 | struct drm_i915_private *dev_priv = dev->dev_private; | 136 | struct drm_i915_private *dev_priv = dev->dev_private; |
124 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
125 | u32 val = I915_READ(VIDEO_DIP_CTL); | 137 | u32 val = I915_READ(VIDEO_DIP_CTL); |
126 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 138 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
127 | 139 | ||
128 | val &= ~VIDEO_DIP_PORT_MASK; | 140 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
129 | if (intel_hdmi->sdvox_reg == SDVOB) | ||
130 | val |= VIDEO_DIP_PORT_B; | ||
131 | else if (intel_hdmi->sdvox_reg == SDVOC) | ||
132 | val |= VIDEO_DIP_PORT_C; | ||
133 | else | ||
134 | return; | ||
135 | 141 | ||
136 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 142 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
137 | val |= g4x_infoframe_index(frame); | 143 | val |= g4x_infoframe_index(frame); |
138 | 144 | ||
139 | val &= ~g4x_infoframe_enable(frame); | 145 | val &= ~g4x_infoframe_enable(frame); |
140 | val |= VIDEO_DIP_ENABLE; | ||
141 | 146 | ||
142 | I915_WRITE(VIDEO_DIP_CTL, val); | 147 | I915_WRITE(VIDEO_DIP_CTL, val); |
143 | 148 | ||
149 | mmiowb(); | ||
144 | for (i = 0; i < len; i += 4) { | 150 | for (i = 0; i < len; i += 4) { |
145 | I915_WRITE(VIDEO_DIP_DATA, *data); | 151 | I915_WRITE(VIDEO_DIP_DATA, *data); |
146 | data++; | 152 | data++; |
147 | } | 153 | } |
154 | mmiowb(); | ||
148 | 155 | ||
149 | val |= g4x_infoframe_enable(frame); | 156 | val |= g4x_infoframe_enable(frame); |
150 | val &= ~VIDEO_DIP_FREQ_MASK; | 157 | val &= ~VIDEO_DIP_FREQ_MASK; |
151 | val |= VIDEO_DIP_FREQ_VSYNC; | 158 | val |= VIDEO_DIP_FREQ_VSYNC; |
152 | 159 | ||
153 | I915_WRITE(VIDEO_DIP_CTL, val); | 160 | I915_WRITE(VIDEO_DIP_CTL, val); |
161 | POSTING_READ(VIDEO_DIP_CTL); | ||
154 | } | 162 | } |
155 | 163 | ||
156 | static void ibx_write_infoframe(struct drm_encoder *encoder, | 164 | static void ibx_write_infoframe(struct drm_encoder *encoder, |
@@ -160,46 +168,32 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, | |||
160 | struct drm_device *dev = encoder->dev; | 168 | struct drm_device *dev = encoder->dev; |
161 | struct drm_i915_private *dev_priv = dev->dev_private; | 169 | struct drm_i915_private *dev_priv = dev->dev_private; |
162 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 170 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
163 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
164 | int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | 171 | int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
165 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 172 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
166 | u32 val = I915_READ(reg); | 173 | u32 val = I915_READ(reg); |
167 | 174 | ||
168 | val &= ~VIDEO_DIP_PORT_MASK; | 175 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
169 | switch (intel_hdmi->sdvox_reg) { | ||
170 | case HDMIB: | ||
171 | val |= VIDEO_DIP_PORT_B; | ||
172 | break; | ||
173 | case HDMIC: | ||
174 | val |= VIDEO_DIP_PORT_C; | ||
175 | break; | ||
176 | case HDMID: | ||
177 | val |= VIDEO_DIP_PORT_D; | ||
178 | break; | ||
179 | default: | ||
180 | return; | ||
181 | } | ||
182 | |||
183 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
184 | 176 | ||
185 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 177 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
186 | val |= g4x_infoframe_index(frame); | 178 | val |= g4x_infoframe_index(frame); |
187 | 179 | ||
188 | val &= ~g4x_infoframe_enable(frame); | 180 | val &= ~g4x_infoframe_enable(frame); |
189 | val |= VIDEO_DIP_ENABLE; | ||
190 | 181 | ||
191 | I915_WRITE(reg, val); | 182 | I915_WRITE(reg, val); |
192 | 183 | ||
184 | mmiowb(); | ||
193 | for (i = 0; i < len; i += 4) { | 185 | for (i = 0; i < len; i += 4) { |
194 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 186 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
195 | data++; | 187 | data++; |
196 | } | 188 | } |
189 | mmiowb(); | ||
197 | 190 | ||
198 | val |= g4x_infoframe_enable(frame); | 191 | val |= g4x_infoframe_enable(frame); |
199 | val &= ~VIDEO_DIP_FREQ_MASK; | 192 | val &= ~VIDEO_DIP_FREQ_MASK; |
200 | val |= VIDEO_DIP_FREQ_VSYNC; | 193 | val |= VIDEO_DIP_FREQ_VSYNC; |
201 | 194 | ||
202 | I915_WRITE(reg, val); | 195 | I915_WRITE(reg, val); |
196 | POSTING_READ(reg); | ||
203 | } | 197 | } |
204 | 198 | ||
205 | static void cpt_write_infoframe(struct drm_encoder *encoder, | 199 | static void cpt_write_infoframe(struct drm_encoder *encoder, |
@@ -213,32 +207,31 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, | |||
213 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 207 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
214 | u32 val = I915_READ(reg); | 208 | u32 val = I915_READ(reg); |
215 | 209 | ||
216 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 210 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
217 | 211 | ||
218 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 212 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
219 | val |= g4x_infoframe_index(frame); | 213 | val |= g4x_infoframe_index(frame); |
220 | 214 | ||
221 | /* The DIP control register spec says that we need to update the AVI | 215 | /* The DIP control register spec says that we need to update the AVI |
222 | * infoframe without clearing its enable bit */ | 216 | * infoframe without clearing its enable bit */ |
223 | if (frame->type == DIP_TYPE_AVI) | 217 | if (frame->type != DIP_TYPE_AVI) |
224 | val |= VIDEO_DIP_ENABLE_AVI; | ||
225 | else | ||
226 | val &= ~g4x_infoframe_enable(frame); | 218 | val &= ~g4x_infoframe_enable(frame); |
227 | 219 | ||
228 | val |= VIDEO_DIP_ENABLE; | ||
229 | |||
230 | I915_WRITE(reg, val); | 220 | I915_WRITE(reg, val); |
231 | 221 | ||
222 | mmiowb(); | ||
232 | for (i = 0; i < len; i += 4) { | 223 | for (i = 0; i < len; i += 4) { |
233 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 224 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
234 | data++; | 225 | data++; |
235 | } | 226 | } |
227 | mmiowb(); | ||
236 | 228 | ||
237 | val |= g4x_infoframe_enable(frame); | 229 | val |= g4x_infoframe_enable(frame); |
238 | val &= ~VIDEO_DIP_FREQ_MASK; | 230 | val &= ~VIDEO_DIP_FREQ_MASK; |
239 | val |= VIDEO_DIP_FREQ_VSYNC; | 231 | val |= VIDEO_DIP_FREQ_VSYNC; |
240 | 232 | ||
241 | I915_WRITE(reg, val); | 233 | I915_WRITE(reg, val); |
234 | POSTING_READ(reg); | ||
242 | } | 235 | } |
243 | 236 | ||
244 | static void vlv_write_infoframe(struct drm_encoder *encoder, | 237 | static void vlv_write_infoframe(struct drm_encoder *encoder, |
@@ -252,26 +245,28 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, | |||
252 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 245 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
253 | u32 val = I915_READ(reg); | 246 | u32 val = I915_READ(reg); |
254 | 247 | ||
255 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 248 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
256 | 249 | ||
257 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 250 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
258 | val |= g4x_infoframe_index(frame); | 251 | val |= g4x_infoframe_index(frame); |
259 | 252 | ||
260 | val &= ~g4x_infoframe_enable(frame); | 253 | val &= ~g4x_infoframe_enable(frame); |
261 | val |= VIDEO_DIP_ENABLE; | ||
262 | 254 | ||
263 | I915_WRITE(reg, val); | 255 | I915_WRITE(reg, val); |
264 | 256 | ||
257 | mmiowb(); | ||
265 | for (i = 0; i < len; i += 4) { | 258 | for (i = 0; i < len; i += 4) { |
266 | I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 259 | I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
267 | data++; | 260 | data++; |
268 | } | 261 | } |
262 | mmiowb(); | ||
269 | 263 | ||
270 | val |= g4x_infoframe_enable(frame); | 264 | val |= g4x_infoframe_enable(frame); |
271 | val &= ~VIDEO_DIP_FREQ_MASK; | 265 | val &= ~VIDEO_DIP_FREQ_MASK; |
272 | val |= VIDEO_DIP_FREQ_VSYNC; | 266 | val |= VIDEO_DIP_FREQ_VSYNC; |
273 | 267 | ||
274 | I915_WRITE(reg, val); | 268 | I915_WRITE(reg, val); |
269 | POSTING_READ(reg); | ||
275 | } | 270 | } |
276 | 271 | ||
277 | static void hsw_write_infoframe(struct drm_encoder *encoder, | 272 | static void hsw_write_infoframe(struct drm_encoder *encoder, |
@@ -289,18 +284,19 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, | |||
289 | if (data_reg == 0) | 284 | if (data_reg == 0) |
290 | return; | 285 | return; |
291 | 286 | ||
292 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
293 | |||
294 | val &= ~hsw_infoframe_enable(frame); | 287 | val &= ~hsw_infoframe_enable(frame); |
295 | I915_WRITE(ctl_reg, val); | 288 | I915_WRITE(ctl_reg, val); |
296 | 289 | ||
290 | mmiowb(); | ||
297 | for (i = 0; i < len; i += 4) { | 291 | for (i = 0; i < len; i += 4) { |
298 | I915_WRITE(data_reg + i, *data); | 292 | I915_WRITE(data_reg + i, *data); |
299 | data++; | 293 | data++; |
300 | } | 294 | } |
295 | mmiowb(); | ||
301 | 296 | ||
302 | val |= hsw_infoframe_enable(frame); | 297 | val |= hsw_infoframe_enable(frame); |
303 | I915_WRITE(ctl_reg, val); | 298 | I915_WRITE(ctl_reg, val); |
299 | POSTING_READ(ctl_reg); | ||
304 | } | 300 | } |
305 | 301 | ||
306 | static void intel_set_infoframe(struct drm_encoder *encoder, | 302 | static void intel_set_infoframe(struct drm_encoder *encoder, |
@@ -308,14 +304,11 @@ static void intel_set_infoframe(struct drm_encoder *encoder, | |||
308 | { | 304 | { |
309 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 305 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
310 | 306 | ||
311 | if (!intel_hdmi->has_hdmi_sink) | ||
312 | return; | ||
313 | |||
314 | intel_dip_infoframe_csum(frame); | 307 | intel_dip_infoframe_csum(frame); |
315 | intel_hdmi->write_infoframe(encoder, frame); | 308 | intel_hdmi->write_infoframe(encoder, frame); |
316 | } | 309 | } |
317 | 310 | ||
318 | void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | 311 | static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, |
319 | struct drm_display_mode *adjusted_mode) | 312 | struct drm_display_mode *adjusted_mode) |
320 | { | 313 | { |
321 | struct dip_infoframe avi_if = { | 314 | struct dip_infoframe avi_if = { |
@@ -330,7 +323,7 @@ void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | |||
330 | intel_set_infoframe(encoder, &avi_if); | 323 | intel_set_infoframe(encoder, &avi_if); |
331 | } | 324 | } |
332 | 325 | ||
333 | void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) | 326 | static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) |
334 | { | 327 | { |
335 | struct dip_infoframe spd_if; | 328 | struct dip_infoframe spd_if; |
336 | 329 | ||
@@ -345,6 +338,223 @@ void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) | |||
345 | intel_set_infoframe(encoder, &spd_if); | 338 | intel_set_infoframe(encoder, &spd_if); |
346 | } | 339 | } |
347 | 340 | ||
341 | static void g4x_set_infoframes(struct drm_encoder *encoder, | ||
342 | struct drm_display_mode *adjusted_mode) | ||
343 | { | ||
344 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
345 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
346 | u32 reg = VIDEO_DIP_CTL; | ||
347 | u32 val = I915_READ(reg); | ||
348 | u32 port; | ||
349 | |||
350 | assert_hdmi_port_disabled(intel_hdmi); | ||
351 | |||
352 | /* If the registers were not initialized yet, they might be zeroes, | ||
353 | * which means we're selecting the AVI DIP and we're setting its | ||
354 | * frequency to once. This seems to really confuse the HW and make | ||
355 | * things stop working (the register spec says the AVI always needs to | ||
356 | * be sent every VSync). So here we avoid writing to the register more | ||
357 | * than we need and also explicitly select the AVI DIP and explicitly | ||
358 | * set its frequency to every VSync. Avoiding to write it twice seems to | ||
359 | * be enough to solve the problem, but being defensive shouldn't hurt us | ||
360 | * either. */ | ||
361 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
362 | |||
363 | if (!intel_hdmi->has_hdmi_sink) { | ||
364 | if (!(val & VIDEO_DIP_ENABLE)) | ||
365 | return; | ||
366 | val &= ~VIDEO_DIP_ENABLE; | ||
367 | I915_WRITE(reg, val); | ||
368 | POSTING_READ(reg); | ||
369 | return; | ||
370 | } | ||
371 | |||
372 | switch (intel_hdmi->sdvox_reg) { | ||
373 | case SDVOB: | ||
374 | port = VIDEO_DIP_PORT_B; | ||
375 | break; | ||
376 | case SDVOC: | ||
377 | port = VIDEO_DIP_PORT_C; | ||
378 | break; | ||
379 | default: | ||
380 | return; | ||
381 | } | ||
382 | |||
383 | if (port != (val & VIDEO_DIP_PORT_MASK)) { | ||
384 | if (val & VIDEO_DIP_ENABLE) { | ||
385 | val &= ~VIDEO_DIP_ENABLE; | ||
386 | I915_WRITE(reg, val); | ||
387 | POSTING_READ(reg); | ||
388 | } | ||
389 | val &= ~VIDEO_DIP_PORT_MASK; | ||
390 | val |= port; | ||
391 | } | ||
392 | |||
393 | val |= VIDEO_DIP_ENABLE; | ||
394 | val &= ~VIDEO_DIP_ENABLE_VENDOR; | ||
395 | |||
396 | I915_WRITE(reg, val); | ||
397 | POSTING_READ(reg); | ||
398 | |||
399 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
400 | intel_hdmi_set_spd_infoframe(encoder); | ||
401 | } | ||
402 | |||
403 | static void ibx_set_infoframes(struct drm_encoder *encoder, | ||
404 | struct drm_display_mode *adjusted_mode) | ||
405 | { | ||
406 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
407 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
408 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
409 | u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
410 | u32 val = I915_READ(reg); | ||
411 | u32 port; | ||
412 | |||
413 | assert_hdmi_port_disabled(intel_hdmi); | ||
414 | |||
415 | /* See the big comment in g4x_set_infoframes() */ | ||
416 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
417 | |||
418 | if (!intel_hdmi->has_hdmi_sink) { | ||
419 | if (!(val & VIDEO_DIP_ENABLE)) | ||
420 | return; | ||
421 | val &= ~VIDEO_DIP_ENABLE; | ||
422 | I915_WRITE(reg, val); | ||
423 | POSTING_READ(reg); | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | switch (intel_hdmi->sdvox_reg) { | ||
428 | case HDMIB: | ||
429 | port = VIDEO_DIP_PORT_B; | ||
430 | break; | ||
431 | case HDMIC: | ||
432 | port = VIDEO_DIP_PORT_C; | ||
433 | break; | ||
434 | case HDMID: | ||
435 | port = VIDEO_DIP_PORT_D; | ||
436 | break; | ||
437 | default: | ||
438 | return; | ||
439 | } | ||
440 | |||
441 | if (port != (val & VIDEO_DIP_PORT_MASK)) { | ||
442 | if (val & VIDEO_DIP_ENABLE) { | ||
443 | val &= ~VIDEO_DIP_ENABLE; | ||
444 | I915_WRITE(reg, val); | ||
445 | POSTING_READ(reg); | ||
446 | } | ||
447 | val &= ~VIDEO_DIP_PORT_MASK; | ||
448 | val |= port; | ||
449 | } | ||
450 | |||
451 | val |= VIDEO_DIP_ENABLE; | ||
452 | val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | | ||
453 | VIDEO_DIP_ENABLE_GCP); | ||
454 | |||
455 | I915_WRITE(reg, val); | ||
456 | POSTING_READ(reg); | ||
457 | |||
458 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
459 | intel_hdmi_set_spd_infoframe(encoder); | ||
460 | } | ||
461 | |||
462 | static void cpt_set_infoframes(struct drm_encoder *encoder, | ||
463 | struct drm_display_mode *adjusted_mode) | ||
464 | { | ||
465 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
466 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
467 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
468 | u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
469 | u32 val = I915_READ(reg); | ||
470 | |||
471 | assert_hdmi_port_disabled(intel_hdmi); | ||
472 | |||
473 | /* See the big comment in g4x_set_infoframes() */ | ||
474 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
475 | |||
476 | if (!intel_hdmi->has_hdmi_sink) { | ||
477 | if (!(val & VIDEO_DIP_ENABLE)) | ||
478 | return; | ||
479 | val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI); | ||
480 | I915_WRITE(reg, val); | ||
481 | POSTING_READ(reg); | ||
482 | return; | ||
483 | } | ||
484 | |||
485 | /* Set both together, unset both together: see the spec. */ | ||
486 | val |= VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI; | ||
487 | val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | | ||
488 | VIDEO_DIP_ENABLE_GCP); | ||
489 | |||
490 | I915_WRITE(reg, val); | ||
491 | POSTING_READ(reg); | ||
492 | |||
493 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
494 | intel_hdmi_set_spd_infoframe(encoder); | ||
495 | } | ||
496 | |||
497 | static void vlv_set_infoframes(struct drm_encoder *encoder, | ||
498 | struct drm_display_mode *adjusted_mode) | ||
499 | { | ||
500 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
501 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
502 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
503 | u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
504 | u32 val = I915_READ(reg); | ||
505 | |||
506 | assert_hdmi_port_disabled(intel_hdmi); | ||
507 | |||
508 | /* See the big comment in g4x_set_infoframes() */ | ||
509 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
510 | |||
511 | if (!intel_hdmi->has_hdmi_sink) { | ||
512 | if (!(val & VIDEO_DIP_ENABLE)) | ||
513 | return; | ||
514 | val &= ~VIDEO_DIP_ENABLE; | ||
515 | I915_WRITE(reg, val); | ||
516 | POSTING_READ(reg); | ||
517 | return; | ||
518 | } | ||
519 | |||
520 | val |= VIDEO_DIP_ENABLE; | ||
521 | val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | | ||
522 | VIDEO_DIP_ENABLE_GCP); | ||
523 | |||
524 | I915_WRITE(reg, val); | ||
525 | POSTING_READ(reg); | ||
526 | |||
527 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
528 | intel_hdmi_set_spd_infoframe(encoder); | ||
529 | } | ||
530 | |||
531 | static void hsw_set_infoframes(struct drm_encoder *encoder, | ||
532 | struct drm_display_mode *adjusted_mode) | ||
533 | { | ||
534 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
535 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
536 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
537 | u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
538 | u32 val = I915_READ(reg); | ||
539 | |||
540 | assert_hdmi_port_disabled(intel_hdmi); | ||
541 | |||
542 | if (!intel_hdmi->has_hdmi_sink) { | ||
543 | I915_WRITE(reg, 0); | ||
544 | POSTING_READ(reg); | ||
545 | return; | ||
546 | } | ||
547 | |||
548 | val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW | | ||
549 | VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW); | ||
550 | |||
551 | I915_WRITE(reg, val); | ||
552 | POSTING_READ(reg); | ||
553 | |||
554 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
555 | intel_hdmi_set_spd_infoframe(encoder); | ||
556 | } | ||
557 | |||
348 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 558 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
349 | struct drm_display_mode *mode, | 559 | struct drm_display_mode *mode, |
350 | struct drm_display_mode *adjusted_mode) | 560 | struct drm_display_mode *adjusted_mode) |
@@ -355,7 +565,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
355 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 565 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
356 | u32 sdvox; | 566 | u32 sdvox; |
357 | 567 | ||
358 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 568 | sdvox = SDVO_ENCODING_HDMI; |
359 | if (!HAS_PCH_SPLIT(dev)) | 569 | if (!HAS_PCH_SPLIT(dev)) |
360 | sdvox |= intel_hdmi->color_range; | 570 | sdvox |= intel_hdmi->color_range; |
361 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 571 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
@@ -382,14 +592,13 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
382 | 592 | ||
383 | if (HAS_PCH_CPT(dev)) | 593 | if (HAS_PCH_CPT(dev)) |
384 | sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); | 594 | sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); |
385 | else if (intel_crtc->pipe == 1) | 595 | else if (intel_crtc->pipe == PIPE_B) |
386 | sdvox |= SDVO_PIPE_B_SELECT; | 596 | sdvox |= SDVO_PIPE_B_SELECT; |
387 | 597 | ||
388 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); | 598 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
389 | POSTING_READ(intel_hdmi->sdvox_reg); | 599 | POSTING_READ(intel_hdmi->sdvox_reg); |
390 | 600 | ||
391 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | 601 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
392 | intel_hdmi_set_spd_infoframe(encoder); | ||
393 | } | 602 | } |
394 | 603 | ||
395 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 604 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) |
@@ -405,6 +614,36 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
405 | 614 | ||
406 | temp = I915_READ(intel_hdmi->sdvox_reg); | 615 | temp = I915_READ(intel_hdmi->sdvox_reg); |
407 | 616 | ||
617 | /* HW workaround for IBX, we need to move the port to transcoder A | ||
618 | * before disabling it. */ | ||
619 | if (HAS_PCH_IBX(dev)) { | ||
620 | struct drm_crtc *crtc = encoder->crtc; | ||
621 | int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; | ||
622 | |||
623 | if (mode != DRM_MODE_DPMS_ON) { | ||
624 | if (temp & SDVO_PIPE_B_SELECT) { | ||
625 | temp &= ~SDVO_PIPE_B_SELECT; | ||
626 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
627 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
628 | |||
629 | /* Again we need to write this twice. */ | ||
630 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
631 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
632 | |||
633 | /* Transcoder selection bits only update | ||
634 | * effectively on vblank. */ | ||
635 | if (crtc) | ||
636 | intel_wait_for_vblank(dev, pipe); | ||
637 | else | ||
638 | msleep(50); | ||
639 | } | ||
640 | } else { | ||
641 | /* Restore the transcoder select bit. */ | ||
642 | if (pipe == PIPE_B) | ||
643 | enable_bits |= SDVO_PIPE_B_SELECT; | ||
644 | } | ||
645 | } | ||
646 | |||
408 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | 647 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but |
409 | * we do this anyway which shows more stable in testing. | 648 | * we do this anyway which shows more stable in testing. |
410 | */ | 649 | */ |
@@ -446,12 +685,33 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector, | |||
446 | } | 685 | } |
447 | 686 | ||
448 | static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | 687 | static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, |
449 | struct drm_display_mode *mode, | 688 | const struct drm_display_mode *mode, |
450 | struct drm_display_mode *adjusted_mode) | 689 | struct drm_display_mode *adjusted_mode) |
451 | { | 690 | { |
452 | return true; | 691 | return true; |
453 | } | 692 | } |
454 | 693 | ||
694 | static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi) | ||
695 | { | ||
696 | struct drm_device *dev = intel_hdmi->base.base.dev; | ||
697 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
698 | uint32_t bit; | ||
699 | |||
700 | switch (intel_hdmi->sdvox_reg) { | ||
701 | case SDVOB: | ||
702 | bit = HDMIB_HOTPLUG_LIVE_STATUS; | ||
703 | break; | ||
704 | case SDVOC: | ||
705 | bit = HDMIC_HOTPLUG_LIVE_STATUS; | ||
706 | break; | ||
707 | default: | ||
708 | bit = 0; | ||
709 | break; | ||
710 | } | ||
711 | |||
712 | return I915_READ(PORT_HOTPLUG_STAT) & bit; | ||
713 | } | ||
714 | |||
455 | static enum drm_connector_status | 715 | static enum drm_connector_status |
456 | intel_hdmi_detect(struct drm_connector *connector, bool force) | 716 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
457 | { | 717 | { |
@@ -460,6 +720,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
460 | struct edid *edid; | 720 | struct edid *edid; |
461 | enum drm_connector_status status = connector_status_disconnected; | 721 | enum drm_connector_status status = connector_status_disconnected; |
462 | 722 | ||
723 | if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi)) | ||
724 | return status; | ||
725 | |||
463 | intel_hdmi->has_hdmi_sink = false; | 726 | intel_hdmi->has_hdmi_sink = false; |
464 | intel_hdmi->has_audio = false; | 727 | intel_hdmi->has_audio = false; |
465 | edid = drm_get_edid(connector, | 728 | edid = drm_get_edid(connector, |
@@ -633,7 +896,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
633 | struct intel_encoder *intel_encoder; | 896 | struct intel_encoder *intel_encoder; |
634 | struct intel_connector *intel_connector; | 897 | struct intel_connector *intel_connector; |
635 | struct intel_hdmi *intel_hdmi; | 898 | struct intel_hdmi *intel_hdmi; |
636 | int i; | ||
637 | 899 | ||
638 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); | 900 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
639 | if (!intel_hdmi) | 901 | if (!intel_hdmi) |
@@ -710,26 +972,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
710 | 972 | ||
711 | if (!HAS_PCH_SPLIT(dev)) { | 973 | if (!HAS_PCH_SPLIT(dev)) { |
712 | intel_hdmi->write_infoframe = g4x_write_infoframe; | 974 | intel_hdmi->write_infoframe = g4x_write_infoframe; |
713 | I915_WRITE(VIDEO_DIP_CTL, 0); | 975 | intel_hdmi->set_infoframes = g4x_set_infoframes; |
714 | } else if (IS_VALLEYVIEW(dev)) { | 976 | } else if (IS_VALLEYVIEW(dev)) { |
715 | intel_hdmi->write_infoframe = vlv_write_infoframe; | 977 | intel_hdmi->write_infoframe = vlv_write_infoframe; |
716 | for_each_pipe(i) | 978 | intel_hdmi->set_infoframes = vlv_set_infoframes; |
717 | I915_WRITE(VLV_TVIDEO_DIP_CTL(i), 0); | ||
718 | } else if (IS_HASWELL(dev)) { | 979 | } else if (IS_HASWELL(dev)) { |
719 | /* FIXME: Haswell has a new set of DIP frame registers, but we are | ||
720 | * just doing the minimal required for HDMI to work at this stage. | ||
721 | */ | ||
722 | intel_hdmi->write_infoframe = hsw_write_infoframe; | 980 | intel_hdmi->write_infoframe = hsw_write_infoframe; |
723 | for_each_pipe(i) | 981 | intel_hdmi->set_infoframes = hsw_set_infoframes; |
724 | I915_WRITE(HSW_TVIDEO_DIP_CTL(i), 0); | ||
725 | } else if (HAS_PCH_IBX(dev)) { | 982 | } else if (HAS_PCH_IBX(dev)) { |
726 | intel_hdmi->write_infoframe = ibx_write_infoframe; | 983 | intel_hdmi->write_infoframe = ibx_write_infoframe; |
727 | for_each_pipe(i) | 984 | intel_hdmi->set_infoframes = ibx_set_infoframes; |
728 | I915_WRITE(TVIDEO_DIP_CTL(i), 0); | ||
729 | } else { | 985 | } else { |
730 | intel_hdmi->write_infoframe = cpt_write_infoframe; | 986 | intel_hdmi->write_infoframe = cpt_write_infoframe; |
731 | for_each_pipe(i) | 987 | intel_hdmi->set_infoframes = cpt_set_infoframes; |
732 | I915_WRITE(TVIDEO_DIP_CTL(i), 0); | ||
733 | } | 988 | } |
734 | 989 | ||
735 | if (IS_HASWELL(dev)) | 990 | if (IS_HASWELL(dev)) |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 08eb04c787e8..e05c0d3e3440 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -71,6 +71,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) | |||
71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) | 71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) |
72 | { | 72 | { |
73 | struct drm_device *dev = intel_lvds->base.base.dev; | 73 | struct drm_device *dev = intel_lvds->base.base.dev; |
74 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc); | ||
74 | struct drm_i915_private *dev_priv = dev->dev_private; | 75 | struct drm_i915_private *dev_priv = dev->dev_private; |
75 | u32 ctl_reg, lvds_reg, stat_reg; | 76 | u32 ctl_reg, lvds_reg, stat_reg; |
76 | 77 | ||
@@ -107,7 +108,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) | |||
107 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) | 108 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) |
108 | DRM_ERROR("timed out waiting for panel to power on\n"); | 109 | DRM_ERROR("timed out waiting for panel to power on\n"); |
109 | 110 | ||
110 | intel_panel_enable_backlight(dev); | 111 | intel_panel_enable_backlight(dev, intel_crtc->pipe); |
111 | } | 112 | } |
112 | 113 | ||
113 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) | 114 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) |
@@ -228,14 +229,14 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) | |||
228 | } | 229 | } |
229 | 230 | ||
230 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | 231 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, |
231 | struct drm_display_mode *mode, | 232 | const struct drm_display_mode *mode, |
232 | struct drm_display_mode *adjusted_mode) | 233 | struct drm_display_mode *adjusted_mode) |
233 | { | 234 | { |
234 | struct drm_device *dev = encoder->dev; | 235 | struct drm_device *dev = encoder->dev; |
235 | struct drm_i915_private *dev_priv = dev->dev_private; | 236 | struct drm_i915_private *dev_priv = dev->dev_private; |
236 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 237 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
237 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 238 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
238 | struct drm_encoder *tmp_encoder; | 239 | struct intel_encoder *tmp_encoder; |
239 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 240 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
240 | int pipe; | 241 | int pipe; |
241 | 242 | ||
@@ -246,8 +247,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
246 | } | 247 | } |
247 | 248 | ||
248 | /* Should never happen!! */ | 249 | /* Should never happen!! */ |
249 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 250 | for_each_encoder_on_crtc(dev, encoder->crtc, tmp_encoder) { |
250 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 251 | if (&tmp_encoder->base != encoder) { |
251 | DRM_ERROR("Can't enable LVDS and another " | 252 | DRM_ERROR("Can't enable LVDS and another " |
252 | "encoder on the same pipe\n"); | 253 | "encoder on the same pipe\n"); |
253 | return false; | 254 | return false; |
@@ -408,13 +409,7 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) | |||
408 | { | 409 | { |
409 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 410 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
410 | 411 | ||
411 | /* | 412 | intel_lvds_disable(intel_lvds); |
412 | * Prior to Ironlake, we must disable the pipe if we want to adjust | ||
413 | * the panel fitter. However at all other times we can just reset | ||
414 | * the registers regardless. | ||
415 | */ | ||
416 | if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) | ||
417 | intel_lvds_disable(intel_lvds); | ||
418 | } | 413 | } |
419 | 414 | ||
420 | static void intel_lvds_commit(struct drm_encoder *encoder) | 415 | static void intel_lvds_commit(struct drm_encoder *encoder) |
@@ -777,6 +772,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
777 | DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), | 772 | DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), |
778 | }, | 773 | }, |
779 | }, | 774 | }, |
775 | { | ||
776 | .callback = intel_no_lvds_dmi_callback, | ||
777 | .ident = "ZOTAC ZBOXSD-ID12/ID13", | ||
778 | .matches = { | ||
779 | DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"), | ||
780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), | ||
781 | }, | ||
782 | }, | ||
780 | 783 | ||
781 | { } /* terminating entry */ | 784 | { } /* terminating entry */ |
782 | }; | 785 | }; |
@@ -967,6 +970,8 @@ bool intel_lvds_init(struct drm_device *dev) | |||
967 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 970 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
968 | if (HAS_PCH_SPLIT(dev)) | 971 | if (HAS_PCH_SPLIT(dev)) |
969 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); | 972 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
973 | else if (IS_GEN4(dev)) | ||
974 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | ||
970 | else | 975 | else |
971 | intel_encoder->crtc_mask = (1 << 1); | 976 | intel_encoder->crtc_mask = (1 << 1); |
972 | 977 | ||
@@ -1074,35 +1079,14 @@ bool intel_lvds_init(struct drm_device *dev) | |||
1074 | goto failed; | 1079 | goto failed; |
1075 | 1080 | ||
1076 | out: | 1081 | out: |
1082 | /* | ||
1083 | * Unlock registers and just | ||
1084 | * leave them unlocked | ||
1085 | */ | ||
1077 | if (HAS_PCH_SPLIT(dev)) { | 1086 | if (HAS_PCH_SPLIT(dev)) { |
1078 | u32 pwm; | ||
1079 | |||
1080 | pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; | ||
1081 | |||
1082 | /* make sure PWM is enabled and locked to the LVDS pipe */ | ||
1083 | pwm = I915_READ(BLC_PWM_CPU_CTL2); | ||
1084 | if (pipe == 0 && (pwm & PWM_PIPE_B)) | ||
1085 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); | ||
1086 | if (pipe) | ||
1087 | pwm |= PWM_PIPE_B; | ||
1088 | else | ||
1089 | pwm &= ~PWM_PIPE_B; | ||
1090 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); | ||
1091 | |||
1092 | pwm = I915_READ(BLC_PWM_PCH_CTL1); | ||
1093 | pwm |= PWM_PCH_ENABLE; | ||
1094 | I915_WRITE(BLC_PWM_PCH_CTL1, pwm); | ||
1095 | /* | ||
1096 | * Unlock registers and just | ||
1097 | * leave them unlocked | ||
1098 | */ | ||
1099 | I915_WRITE(PCH_PP_CONTROL, | 1087 | I915_WRITE(PCH_PP_CONTROL, |
1100 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | 1088 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); |
1101 | } else { | 1089 | } else { |
1102 | /* | ||
1103 | * Unlock registers and just | ||
1104 | * leave them unlocked | ||
1105 | */ | ||
1106 | I915_WRITE(PP_CONTROL, | 1090 | I915_WRITE(PP_CONTROL, |
1107 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | 1091 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); |
1108 | } | 1092 | } |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index d67ec3a51e42..45848b9b670b 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -33,34 +33,6 @@ | |||
33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * intel_ddc_probe | ||
37 | * | ||
38 | */ | ||
39 | bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus) | ||
40 | { | ||
41 | struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; | ||
42 | u8 out_buf[] = { 0x0, 0x0}; | ||
43 | u8 buf[2]; | ||
44 | struct i2c_msg msgs[] = { | ||
45 | { | ||
46 | .addr = DDC_ADDR, | ||
47 | .flags = 0, | ||
48 | .len = 1, | ||
49 | .buf = out_buf, | ||
50 | }, | ||
51 | { | ||
52 | .addr = DDC_ADDR, | ||
53 | .flags = I2C_M_RD, | ||
54 | .len = 1, | ||
55 | .buf = buf, | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | return i2c_transfer(intel_gmbus_get_adapter(dev_priv, ddc_bus), | ||
60 | msgs, 2) == 2; | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * intel_ddc_get_modes - get modelist from monitor | 36 | * intel_ddc_get_modes - get modelist from monitor |
65 | * @connector: DRM connector device to use | 37 | * @connector: DRM connector device to use |
66 | * @adapter: i2c adapter | 38 | * @adapter: i2c adapter |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 458743da3774..830d0dd610e1 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -226,7 +226,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
226 | } | 226 | } |
227 | overlay->last_flip_req = request->seqno; | 227 | overlay->last_flip_req = request->seqno; |
228 | overlay->flip_tail = tail; | 228 | overlay->flip_tail = tail; |
229 | ret = i915_wait_request(ring, overlay->last_flip_req); | 229 | ret = i915_wait_seqno(ring, overlay->last_flip_req); |
230 | if (ret) | 230 | if (ret) |
231 | return ret; | 231 | return ret; |
232 | i915_gem_retire_requests(dev); | 232 | i915_gem_retire_requests(dev); |
@@ -452,7 +452,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) | |||
452 | if (overlay->last_flip_req == 0) | 452 | if (overlay->last_flip_req == 0) |
453 | return 0; | 453 | return 0; |
454 | 454 | ||
455 | ret = i915_wait_request(ring, overlay->last_flip_req); | 455 | ret = i915_wait_seqno(ring, overlay->last_flip_req); |
456 | if (ret) | 456 | if (ret) |
457 | return ret; | 457 | return ret; |
458 | i915_gem_retire_requests(dev); | 458 | i915_gem_retire_requests(dev); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 2a1625d84a69..10c7d39034e1 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -56,7 +56,7 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | |||
56 | void | 56 | void |
57 | intel_pch_panel_fitting(struct drm_device *dev, | 57 | intel_pch_panel_fitting(struct drm_device *dev, |
58 | int fitting_mode, | 58 | int fitting_mode, |
59 | struct drm_display_mode *mode, | 59 | const struct drm_display_mode *mode, |
60 | struct drm_display_mode *adjusted_mode) | 60 | struct drm_display_mode *adjusted_mode) |
61 | { | 61 | { |
62 | struct drm_i915_private *dev_priv = dev->dev_private; | 62 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -287,9 +287,24 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
287 | 287 | ||
288 | dev_priv->backlight_enabled = false; | 288 | dev_priv->backlight_enabled = false; |
289 | intel_panel_actually_set_backlight(dev, 0); | 289 | intel_panel_actually_set_backlight(dev, 0); |
290 | |||
291 | if (INTEL_INFO(dev)->gen >= 4) { | ||
292 | uint32_t reg, tmp; | ||
293 | |||
294 | reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; | ||
295 | |||
296 | I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); | ||
297 | |||
298 | if (HAS_PCH_SPLIT(dev)) { | ||
299 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | ||
300 | tmp &= ~BLM_PCH_PWM_ENABLE; | ||
301 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | ||
302 | } | ||
303 | } | ||
290 | } | 304 | } |
291 | 305 | ||
292 | void intel_panel_enable_backlight(struct drm_device *dev) | 306 | void intel_panel_enable_backlight(struct drm_device *dev, |
307 | enum pipe pipe) | ||
293 | { | 308 | { |
294 | struct drm_i915_private *dev_priv = dev->dev_private; | 309 | struct drm_i915_private *dev_priv = dev->dev_private; |
295 | 310 | ||
@@ -298,6 +313,40 @@ void intel_panel_enable_backlight(struct drm_device *dev) | |||
298 | 313 | ||
299 | dev_priv->backlight_enabled = true; | 314 | dev_priv->backlight_enabled = true; |
300 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | 315 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); |
316 | |||
317 | if (INTEL_INFO(dev)->gen >= 4) { | ||
318 | uint32_t reg, tmp; | ||
319 | |||
320 | reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; | ||
321 | |||
322 | |||
323 | tmp = I915_READ(reg); | ||
324 | |||
325 | /* Note that this can also get called through dpms changes. And | ||
326 | * we don't track the backlight dpms state, hence check whether | ||
327 | * we have to do anything first. */ | ||
328 | if (tmp & BLM_PWM_ENABLE) | ||
329 | return; | ||
330 | |||
331 | if (dev_priv->num_pipe == 3) | ||
332 | tmp &= ~BLM_PIPE_SELECT_IVB; | ||
333 | else | ||
334 | tmp &= ~BLM_PIPE_SELECT; | ||
335 | |||
336 | tmp |= BLM_PIPE(pipe); | ||
337 | tmp &= ~BLM_PWM_ENABLE; | ||
338 | |||
339 | I915_WRITE(reg, tmp); | ||
340 | POSTING_READ(reg); | ||
341 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); | ||
342 | |||
343 | if (HAS_PCH_SPLIT(dev)) { | ||
344 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | ||
345 | tmp |= BLM_PCH_PWM_ENABLE; | ||
346 | tmp &= ~BLM_PCH_OVERRIDE_ENABLE; | ||
347 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | ||
348 | } | ||
349 | } | ||
301 | } | 350 | } |
302 | 351 | ||
303 | static void intel_panel_init_backlight(struct drm_device *dev) | 352 | static void intel_panel_init_backlight(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d0ce2a5b1d3f..94aabcaa3a67 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -387,8 +387,6 @@ void intel_update_fbc(struct drm_device *dev) | |||
387 | struct drm_i915_gem_object *obj; | 387 | struct drm_i915_gem_object *obj; |
388 | int enable_fbc; | 388 | int enable_fbc; |
389 | 389 | ||
390 | DRM_DEBUG_KMS("\n"); | ||
391 | |||
392 | if (!i915_powersave) | 390 | if (!i915_powersave) |
393 | return; | 391 | return; |
394 | 392 | ||
@@ -405,7 +403,9 @@ void intel_update_fbc(struct drm_device *dev) | |||
405 | * - going to an unsupported config (interlace, pixel multiply, etc.) | 403 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
406 | */ | 404 | */ |
407 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | 405 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { |
408 | if (tmp_crtc->enabled && tmp_crtc->fb) { | 406 | if (tmp_crtc->enabled && |
407 | !to_intel_crtc(tmp_crtc)->primary_disabled && | ||
408 | tmp_crtc->fb) { | ||
409 | if (crtc) { | 409 | if (crtc) { |
410 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); | 410 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); |
411 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; | 411 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; |
@@ -2182,7 +2182,7 @@ bool ironlake_set_drps(struct drm_device *dev, u8 val) | |||
2182 | return true; | 2182 | return true; |
2183 | } | 2183 | } |
2184 | 2184 | ||
2185 | void ironlake_enable_drps(struct drm_device *dev) | 2185 | static void ironlake_enable_drps(struct drm_device *dev) |
2186 | { | 2186 | { |
2187 | struct drm_i915_private *dev_priv = dev->dev_private; | 2187 | struct drm_i915_private *dev_priv = dev->dev_private; |
2188 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 2188 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
@@ -2246,7 +2246,7 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
2246 | getrawmonotonic(&dev_priv->last_time2); | 2246 | getrawmonotonic(&dev_priv->last_time2); |
2247 | } | 2247 | } |
2248 | 2248 | ||
2249 | void ironlake_disable_drps(struct drm_device *dev) | 2249 | static void ironlake_disable_drps(struct drm_device *dev) |
2250 | { | 2250 | { |
2251 | struct drm_i915_private *dev_priv = dev->dev_private; | 2251 | struct drm_i915_private *dev_priv = dev->dev_private; |
2252 | u16 rgvswctl = I915_READ16(MEMSWCTL); | 2252 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
@@ -2299,10 +2299,11 @@ void gen6_set_rps(struct drm_device *dev, u8 val) | |||
2299 | dev_priv->cur_delay = val; | 2299 | dev_priv->cur_delay = val; |
2300 | } | 2300 | } |
2301 | 2301 | ||
2302 | void gen6_disable_rps(struct drm_device *dev) | 2302 | static void gen6_disable_rps(struct drm_device *dev) |
2303 | { | 2303 | { |
2304 | struct drm_i915_private *dev_priv = dev->dev_private; | 2304 | struct drm_i915_private *dev_priv = dev->dev_private; |
2305 | 2305 | ||
2306 | I915_WRITE(GEN6_RC_CONTROL, 0); | ||
2306 | I915_WRITE(GEN6_RPNSWREQ, 1 << 31); | 2307 | I915_WRITE(GEN6_RPNSWREQ, 1 << 31); |
2307 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); | 2308 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); |
2308 | I915_WRITE(GEN6_PMIER, 0); | 2309 | I915_WRITE(GEN6_PMIER, 0); |
@@ -2332,9 +2333,11 @@ int intel_enable_rc6(const struct drm_device *dev) | |||
2332 | if (INTEL_INFO(dev)->gen == 5) | 2333 | if (INTEL_INFO(dev)->gen == 5) |
2333 | return 0; | 2334 | return 0; |
2334 | 2335 | ||
2335 | /* Sorry Haswell, no RC6 for you for now. */ | 2336 | /* On Haswell, only RC6 is available. So let's enable it by default to |
2337 | * provide better testing and coverage since the beginning. | ||
2338 | */ | ||
2336 | if (IS_HASWELL(dev)) | 2339 | if (IS_HASWELL(dev)) |
2337 | return 0; | 2340 | return INTEL_RC6_ENABLE; |
2338 | 2341 | ||
2339 | /* | 2342 | /* |
2340 | * Disable rc6 on Sandybridge | 2343 | * Disable rc6 on Sandybridge |
@@ -2347,8 +2350,9 @@ int intel_enable_rc6(const struct drm_device *dev) | |||
2347 | return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); | 2350 | return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); |
2348 | } | 2351 | } |
2349 | 2352 | ||
2350 | void gen6_enable_rps(struct drm_i915_private *dev_priv) | 2353 | static void gen6_enable_rps(struct drm_device *dev) |
2351 | { | 2354 | { |
2355 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2352 | struct intel_ring_buffer *ring; | 2356 | struct intel_ring_buffer *ring; |
2353 | u32 rp_state_cap; | 2357 | u32 rp_state_cap; |
2354 | u32 gt_perf_status; | 2358 | u32 gt_perf_status; |
@@ -2357,6 +2361,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2357 | int rc6_mode; | 2361 | int rc6_mode; |
2358 | int i; | 2362 | int i; |
2359 | 2363 | ||
2364 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
2365 | |||
2360 | /* Here begins a magic sequence of register writes to enable | 2366 | /* Here begins a magic sequence of register writes to enable |
2361 | * auto-downclocking. | 2367 | * auto-downclocking. |
2362 | * | 2368 | * |
@@ -2364,7 +2370,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2364 | * userspace... | 2370 | * userspace... |
2365 | */ | 2371 | */ |
2366 | I915_WRITE(GEN6_RC_STATE, 0); | 2372 | I915_WRITE(GEN6_RC_STATE, 0); |
2367 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
2368 | 2373 | ||
2369 | /* Clear the DBG now so we don't confuse earlier errors */ | 2374 | /* Clear the DBG now so we don't confuse earlier errors */ |
2370 | if ((gtfifodbg = I915_READ(GTFIFODBG))) { | 2375 | if ((gtfifodbg = I915_READ(GTFIFODBG))) { |
@@ -2400,20 +2405,24 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2400 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); | 2405 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); |
2401 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ | 2406 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ |
2402 | 2407 | ||
2408 | /* Check if we are enabling RC6 */ | ||
2403 | rc6_mode = intel_enable_rc6(dev_priv->dev); | 2409 | rc6_mode = intel_enable_rc6(dev_priv->dev); |
2404 | if (rc6_mode & INTEL_RC6_ENABLE) | 2410 | if (rc6_mode & INTEL_RC6_ENABLE) |
2405 | rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; | 2411 | rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; |
2406 | 2412 | ||
2407 | if (rc6_mode & INTEL_RC6p_ENABLE) | 2413 | /* We don't use those on Haswell */ |
2408 | rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; | 2414 | if (!IS_HASWELL(dev)) { |
2415 | if (rc6_mode & INTEL_RC6p_ENABLE) | ||
2416 | rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; | ||
2409 | 2417 | ||
2410 | if (rc6_mode & INTEL_RC6pp_ENABLE) | 2418 | if (rc6_mode & INTEL_RC6pp_ENABLE) |
2411 | rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; | 2419 | rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; |
2420 | } | ||
2412 | 2421 | ||
2413 | DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", | 2422 | DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", |
2414 | (rc6_mode & INTEL_RC6_ENABLE) ? "on" : "off", | 2423 | (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off", |
2415 | (rc6_mode & INTEL_RC6p_ENABLE) ? "on" : "off", | 2424 | (rc6_mask & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off", |
2416 | (rc6_mode & INTEL_RC6pp_ENABLE) ? "on" : "off"); | 2425 | (rc6_mask & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off"); |
2417 | 2426 | ||
2418 | I915_WRITE(GEN6_RC_CONTROL, | 2427 | I915_WRITE(GEN6_RC_CONTROL, |
2419 | rc6_mask | | 2428 | rc6_mask | |
@@ -2431,10 +2440,19 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2431 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | 2440 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, |
2432 | dev_priv->max_delay << 24 | | 2441 | dev_priv->max_delay << 24 | |
2433 | dev_priv->min_delay << 16); | 2442 | dev_priv->min_delay << 16); |
2434 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); | 2443 | |
2435 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); | 2444 | if (IS_HASWELL(dev)) { |
2436 | I915_WRITE(GEN6_RP_UP_EI, 100000); | 2445 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
2437 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); | 2446 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
2447 | I915_WRITE(GEN6_RP_UP_EI, 66000); | ||
2448 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); | ||
2449 | } else { | ||
2450 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); | ||
2451 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); | ||
2452 | I915_WRITE(GEN6_RP_UP_EI, 100000); | ||
2453 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); | ||
2454 | } | ||
2455 | |||
2438 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | 2456 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
2439 | I915_WRITE(GEN6_RP_CONTROL, | 2457 | I915_WRITE(GEN6_RP_CONTROL, |
2440 | GEN6_RP_MEDIA_TURBO | | 2458 | GEN6_RP_MEDIA_TURBO | |
@@ -2442,7 +2460,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2442 | GEN6_RP_MEDIA_IS_GFX | | 2460 | GEN6_RP_MEDIA_IS_GFX | |
2443 | GEN6_RP_ENABLE | | 2461 | GEN6_RP_ENABLE | |
2444 | GEN6_RP_UP_BUSY_AVG | | 2462 | GEN6_RP_UP_BUSY_AVG | |
2445 | GEN6_RP_DOWN_IDLE_CONT); | 2463 | (IS_HASWELL(dev) ? GEN7_RP_DOWN_IDLE_AVG : GEN6_RP_DOWN_IDLE_CONT)); |
2446 | 2464 | ||
2447 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | 2465 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, |
2448 | 500)) | 2466 | 500)) |
@@ -2473,14 +2491,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2473 | gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); | 2491 | gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); |
2474 | 2492 | ||
2475 | /* requires MSI enabled */ | 2493 | /* requires MSI enabled */ |
2476 | I915_WRITE(GEN6_PMIER, | 2494 | I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); |
2477 | GEN6_PM_MBOX_EVENT | | ||
2478 | GEN6_PM_THERMAL_EVENT | | ||
2479 | GEN6_PM_RP_DOWN_TIMEOUT | | ||
2480 | GEN6_PM_RP_UP_THRESHOLD | | ||
2481 | GEN6_PM_RP_DOWN_THRESHOLD | | ||
2482 | GEN6_PM_RP_UP_EI_EXPIRED | | ||
2483 | GEN6_PM_RP_DOWN_EI_EXPIRED); | ||
2484 | spin_lock_irq(&dev_priv->rps_lock); | 2495 | spin_lock_irq(&dev_priv->rps_lock); |
2485 | WARN_ON(dev_priv->pm_iir != 0); | 2496 | WARN_ON(dev_priv->pm_iir != 0); |
2486 | I915_WRITE(GEN6_PMIMR, 0); | 2497 | I915_WRITE(GEN6_PMIMR, 0); |
@@ -2489,15 +2500,17 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
2489 | I915_WRITE(GEN6_PMINTRMSK, 0); | 2500 | I915_WRITE(GEN6_PMINTRMSK, 0); |
2490 | 2501 | ||
2491 | gen6_gt_force_wake_put(dev_priv); | 2502 | gen6_gt_force_wake_put(dev_priv); |
2492 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
2493 | } | 2503 | } |
2494 | 2504 | ||
2495 | void gen6_update_ring_freq(struct drm_i915_private *dev_priv) | 2505 | static void gen6_update_ring_freq(struct drm_device *dev) |
2496 | { | 2506 | { |
2507 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2497 | int min_freq = 15; | 2508 | int min_freq = 15; |
2498 | int gpu_freq, ia_freq, max_ia_freq; | 2509 | int gpu_freq, ia_freq, max_ia_freq; |
2499 | int scaling_factor = 180; | 2510 | int scaling_factor = 180; |
2500 | 2511 | ||
2512 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
2513 | |||
2501 | max_ia_freq = cpufreq_quick_get_max(0); | 2514 | max_ia_freq = cpufreq_quick_get_max(0); |
2502 | /* | 2515 | /* |
2503 | * Default to measured freq if none found, PCU will ensure we don't go | 2516 | * Default to measured freq if none found, PCU will ensure we don't go |
@@ -2509,8 +2522,6 @@ void gen6_update_ring_freq(struct drm_i915_private *dev_priv) | |||
2509 | /* Convert from kHz to MHz */ | 2522 | /* Convert from kHz to MHz */ |
2510 | max_ia_freq /= 1000; | 2523 | max_ia_freq /= 1000; |
2511 | 2524 | ||
2512 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
2513 | |||
2514 | /* | 2525 | /* |
2515 | * For each potential GPU frequency, load a ring frequency we'd like | 2526 | * For each potential GPU frequency, load a ring frequency we'd like |
2516 | * to use for memory access. We do this by specifying the IA frequency | 2527 | * to use for memory access. We do this by specifying the IA frequency |
@@ -2541,11 +2552,9 @@ void gen6_update_ring_freq(struct drm_i915_private *dev_priv) | |||
2541 | continue; | 2552 | continue; |
2542 | } | 2553 | } |
2543 | } | 2554 | } |
2544 | |||
2545 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
2546 | } | 2555 | } |
2547 | 2556 | ||
2548 | static void ironlake_teardown_rc6(struct drm_device *dev) | 2557 | void ironlake_teardown_rc6(struct drm_device *dev) |
2549 | { | 2558 | { |
2550 | struct drm_i915_private *dev_priv = dev->dev_private; | 2559 | struct drm_i915_private *dev_priv = dev->dev_private; |
2551 | 2560 | ||
@@ -2562,7 +2571,7 @@ static void ironlake_teardown_rc6(struct drm_device *dev) | |||
2562 | } | 2571 | } |
2563 | } | 2572 | } |
2564 | 2573 | ||
2565 | void ironlake_disable_rc6(struct drm_device *dev) | 2574 | static void ironlake_disable_rc6(struct drm_device *dev) |
2566 | { | 2575 | { |
2567 | struct drm_i915_private *dev_priv = dev->dev_private; | 2576 | struct drm_i915_private *dev_priv = dev->dev_private; |
2568 | 2577 | ||
@@ -2578,8 +2587,6 @@ void ironlake_disable_rc6(struct drm_device *dev) | |||
2578 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | 2587 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); |
2579 | POSTING_READ(RSTDBYCTL); | 2588 | POSTING_READ(RSTDBYCTL); |
2580 | } | 2589 | } |
2581 | |||
2582 | ironlake_teardown_rc6(dev); | ||
2583 | } | 2590 | } |
2584 | 2591 | ||
2585 | static int ironlake_setup_rc6(struct drm_device *dev) | 2592 | static int ironlake_setup_rc6(struct drm_device *dev) |
@@ -2601,7 +2608,7 @@ static int ironlake_setup_rc6(struct drm_device *dev) | |||
2601 | return 0; | 2608 | return 0; |
2602 | } | 2609 | } |
2603 | 2610 | ||
2604 | void ironlake_enable_rc6(struct drm_device *dev) | 2611 | static void ironlake_enable_rc6(struct drm_device *dev) |
2605 | { | 2612 | { |
2606 | struct drm_i915_private *dev_priv = dev->dev_private; | 2613 | struct drm_i915_private *dev_priv = dev->dev_private; |
2607 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 2614 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
@@ -2613,12 +2620,11 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
2613 | if (!intel_enable_rc6(dev)) | 2620 | if (!intel_enable_rc6(dev)) |
2614 | return; | 2621 | return; |
2615 | 2622 | ||
2616 | mutex_lock(&dev->struct_mutex); | 2623 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
2624 | |||
2617 | ret = ironlake_setup_rc6(dev); | 2625 | ret = ironlake_setup_rc6(dev); |
2618 | if (ret) { | 2626 | if (ret) |
2619 | mutex_unlock(&dev->struct_mutex); | ||
2620 | return; | 2627 | return; |
2621 | } | ||
2622 | 2628 | ||
2623 | /* | 2629 | /* |
2624 | * GPU can automatically power down the render unit if given a page | 2630 | * GPU can automatically power down the render unit if given a page |
@@ -2627,7 +2633,6 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
2627 | ret = intel_ring_begin(ring, 6); | 2633 | ret = intel_ring_begin(ring, 6); |
2628 | if (ret) { | 2634 | if (ret) { |
2629 | ironlake_teardown_rc6(dev); | 2635 | ironlake_teardown_rc6(dev); |
2630 | mutex_unlock(&dev->struct_mutex); | ||
2631 | return; | 2636 | return; |
2632 | } | 2637 | } |
2633 | 2638 | ||
@@ -2652,13 +2657,11 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
2652 | if (ret) { | 2657 | if (ret) { |
2653 | DRM_ERROR("failed to enable ironlake power power savings\n"); | 2658 | DRM_ERROR("failed to enable ironlake power power savings\n"); |
2654 | ironlake_teardown_rc6(dev); | 2659 | ironlake_teardown_rc6(dev); |
2655 | mutex_unlock(&dev->struct_mutex); | ||
2656 | return; | 2660 | return; |
2657 | } | 2661 | } |
2658 | 2662 | ||
2659 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); | 2663 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); |
2660 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | 2664 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); |
2661 | mutex_unlock(&dev->struct_mutex); | ||
2662 | } | 2665 | } |
2663 | 2666 | ||
2664 | static unsigned long intel_pxfreq(u32 vidfreq) | 2667 | static unsigned long intel_pxfreq(u32 vidfreq) |
@@ -3154,8 +3157,7 @@ void intel_gpu_ips_teardown(void) | |||
3154 | i915_mch_dev = NULL; | 3157 | i915_mch_dev = NULL; |
3155 | spin_unlock(&mchdev_lock); | 3158 | spin_unlock(&mchdev_lock); |
3156 | } | 3159 | } |
3157 | 3160 | static void intel_init_emon(struct drm_device *dev) | |
3158 | void intel_init_emon(struct drm_device *dev) | ||
3159 | { | 3161 | { |
3160 | struct drm_i915_private *dev_priv = dev->dev_private; | 3162 | struct drm_i915_private *dev_priv = dev->dev_private; |
3161 | u32 lcfuse; | 3163 | u32 lcfuse; |
@@ -3226,6 +3228,28 @@ void intel_init_emon(struct drm_device *dev) | |||
3226 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | 3228 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); |
3227 | } | 3229 | } |
3228 | 3230 | ||
3231 | void intel_disable_gt_powersave(struct drm_device *dev) | ||
3232 | { | ||
3233 | if (IS_IRONLAKE_M(dev)) { | ||
3234 | ironlake_disable_drps(dev); | ||
3235 | ironlake_disable_rc6(dev); | ||
3236 | } else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) { | ||
3237 | gen6_disable_rps(dev); | ||
3238 | } | ||
3239 | } | ||
3240 | |||
3241 | void intel_enable_gt_powersave(struct drm_device *dev) | ||
3242 | { | ||
3243 | if (IS_IRONLAKE_M(dev)) { | ||
3244 | ironlake_enable_drps(dev); | ||
3245 | ironlake_enable_rc6(dev); | ||
3246 | intel_init_emon(dev); | ||
3247 | } else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) { | ||
3248 | gen6_enable_rps(dev); | ||
3249 | gen6_update_ring_freq(dev); | ||
3250 | } | ||
3251 | } | ||
3252 | |||
3229 | static void ironlake_init_clock_gating(struct drm_device *dev) | 3253 | static void ironlake_init_clock_gating(struct drm_device *dev) |
3230 | { | 3254 | { |
3231 | struct drm_i915_private *dev_priv = dev->dev_private; | 3255 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -3328,8 +3352,12 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
3328 | * | 3352 | * |
3329 | * According to the spec, bit 11 (RCCUNIT) must also be set, | 3353 | * According to the spec, bit 11 (RCCUNIT) must also be set, |
3330 | * but we didn't debug actual testcases to find it out. | 3354 | * but we didn't debug actual testcases to find it out. |
3355 | * | ||
3356 | * Also apply WaDisableVDSUnitClockGating and | ||
3357 | * WaDisableRCPBUnitClockGating. | ||
3331 | */ | 3358 | */ |
3332 | I915_WRITE(GEN6_UCGCTL2, | 3359 | I915_WRITE(GEN6_UCGCTL2, |
3360 | GEN7_VDSUNIT_CLOCK_GATE_DISABLE | | ||
3333 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | 3361 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | |
3334 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | 3362 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
3335 | 3363 | ||
@@ -3357,6 +3385,9 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
3357 | ILK_DPARB_CLK_GATE | | 3385 | ILK_DPARB_CLK_GATE | |
3358 | ILK_DPFD_CLK_GATE); | 3386 | ILK_DPFD_CLK_GATE); |
3359 | 3387 | ||
3388 | I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | | ||
3389 | GEN6_MBCTL_ENABLE_BOOT_FETCH); | ||
3390 | |||
3360 | for_each_pipe(pipe) { | 3391 | for_each_pipe(pipe) { |
3361 | I915_WRITE(DSPCNTR(pipe), | 3392 | I915_WRITE(DSPCNTR(pipe), |
3362 | I915_READ(DSPCNTR(pipe)) | | 3393 | I915_READ(DSPCNTR(pipe)) | |
@@ -3377,7 +3408,7 @@ static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) | |||
3377 | I915_WRITE(GEN7_FF_THREAD_MODE, reg); | 3408 | I915_WRITE(GEN7_FF_THREAD_MODE, reg); |
3378 | } | 3409 | } |
3379 | 3410 | ||
3380 | static void ivybridge_init_clock_gating(struct drm_device *dev) | 3411 | static void haswell_init_clock_gating(struct drm_device *dev) |
3381 | { | 3412 | { |
3382 | struct drm_i915_private *dev_priv = dev->dev_private; | 3413 | struct drm_i915_private *dev_priv = dev->dev_private; |
3383 | int pipe; | 3414 | int pipe; |
@@ -3427,13 +3458,24 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
3427 | /* WaDisable4x2SubspanOptimization */ | 3458 | /* WaDisable4x2SubspanOptimization */ |
3428 | I915_WRITE(CACHE_MODE_1, | 3459 | I915_WRITE(CACHE_MODE_1, |
3429 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | 3460 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
3461 | |||
3462 | /* XXX: This is a workaround for early silicon revisions and should be | ||
3463 | * removed later. | ||
3464 | */ | ||
3465 | I915_WRITE(WM_DBG, | ||
3466 | I915_READ(WM_DBG) | | ||
3467 | WM_DBG_DISALLOW_MULTIPLE_LP | | ||
3468 | WM_DBG_DISALLOW_SPRITE | | ||
3469 | WM_DBG_DISALLOW_MAXFIFO); | ||
3470 | |||
3430 | } | 3471 | } |
3431 | 3472 | ||
3432 | static void valleyview_init_clock_gating(struct drm_device *dev) | 3473 | static void ivybridge_init_clock_gating(struct drm_device *dev) |
3433 | { | 3474 | { |
3434 | struct drm_i915_private *dev_priv = dev->dev_private; | 3475 | struct drm_i915_private *dev_priv = dev->dev_private; |
3435 | int pipe; | 3476 | int pipe; |
3436 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | 3477 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; |
3478 | uint32_t snpcr; | ||
3437 | 3479 | ||
3438 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | 3480 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
3439 | 3481 | ||
@@ -3441,10 +3483,77 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
3441 | I915_WRITE(WM2_LP_ILK, 0); | 3483 | I915_WRITE(WM2_LP_ILK, 0); |
3442 | I915_WRITE(WM1_LP_ILK, 0); | 3484 | I915_WRITE(WM1_LP_ILK, 0); |
3443 | 3485 | ||
3444 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | 3486 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); |
3487 | |||
3488 | I915_WRITE(IVB_CHICKEN3, | ||
3489 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | ||
3490 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | ||
3491 | |||
3492 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | ||
3493 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | ||
3494 | GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | ||
3495 | |||
3496 | /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ | ||
3497 | I915_WRITE(GEN7_L3CNTLREG1, | ||
3498 | GEN7_WA_FOR_GEN7_L3_CONTROL); | ||
3499 | I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, | ||
3500 | GEN7_WA_L3_CHICKEN_MODE); | ||
3501 | |||
3502 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | ||
3503 | * gating disable must be set. Failure to set it results in | ||
3504 | * flickering pixels due to Z write ordering failures after | ||
3505 | * some amount of runtime in the Mesa "fire" demo, and Unigine | ||
3506 | * Sanctuary and Tropics, and apparently anything else with | ||
3507 | * alpha test or pixel discard. | ||
3508 | * | ||
3509 | * According to the spec, bit 11 (RCCUNIT) must also be set, | ||
3510 | * but we didn't debug actual testcases to find it out. | ||
3511 | * | ||
3512 | * According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
3445 | * This implements the WaDisableRCZUnitClockGating workaround. | 3513 | * This implements the WaDisableRCZUnitClockGating workaround. |
3446 | */ | 3514 | */ |
3447 | I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); | 3515 | I915_WRITE(GEN6_UCGCTL2, |
3516 | GEN6_RCZUNIT_CLOCK_GATE_DISABLE | | ||
3517 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | ||
3518 | |||
3519 | /* This is required by WaCatErrorRejectionIssue */ | ||
3520 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | ||
3521 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | ||
3522 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | ||
3523 | |||
3524 | for_each_pipe(pipe) { | ||
3525 | I915_WRITE(DSPCNTR(pipe), | ||
3526 | I915_READ(DSPCNTR(pipe)) | | ||
3527 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
3528 | intel_flush_display_plane(dev_priv, pipe); | ||
3529 | } | ||
3530 | |||
3531 | I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | | ||
3532 | GEN6_MBCTL_ENABLE_BOOT_FETCH); | ||
3533 | |||
3534 | gen7_setup_fixed_func_scheduler(dev_priv); | ||
3535 | |||
3536 | /* WaDisable4x2SubspanOptimization */ | ||
3537 | I915_WRITE(CACHE_MODE_1, | ||
3538 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | ||
3539 | |||
3540 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); | ||
3541 | snpcr &= ~GEN6_MBC_SNPCR_MASK; | ||
3542 | snpcr |= GEN6_MBC_SNPCR_MED; | ||
3543 | I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); | ||
3544 | } | ||
3545 | |||
3546 | static void valleyview_init_clock_gating(struct drm_device *dev) | ||
3547 | { | ||
3548 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3549 | int pipe; | ||
3550 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
3551 | |||
3552 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
3553 | |||
3554 | I915_WRITE(WM3_LP_ILK, 0); | ||
3555 | I915_WRITE(WM2_LP_ILK, 0); | ||
3556 | I915_WRITE(WM1_LP_ILK, 0); | ||
3448 | 3557 | ||
3449 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); | 3558 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); |
3450 | 3559 | ||
@@ -3465,6 +3574,35 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
3465 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | 3574 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
3466 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | 3575 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); |
3467 | 3576 | ||
3577 | I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | | ||
3578 | GEN6_MBCTL_ENABLE_BOOT_FETCH); | ||
3579 | |||
3580 | |||
3581 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | ||
3582 | * gating disable must be set. Failure to set it results in | ||
3583 | * flickering pixels due to Z write ordering failures after | ||
3584 | * some amount of runtime in the Mesa "fire" demo, and Unigine | ||
3585 | * Sanctuary and Tropics, and apparently anything else with | ||
3586 | * alpha test or pixel discard. | ||
3587 | * | ||
3588 | * According to the spec, bit 11 (RCCUNIT) must also be set, | ||
3589 | * but we didn't debug actual testcases to find it out. | ||
3590 | * | ||
3591 | * According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
3592 | * This implements the WaDisableRCZUnitClockGating workaround. | ||
3593 | * | ||
3594 | * Also apply WaDisableVDSUnitClockGating and | ||
3595 | * WaDisableRCPBUnitClockGating. | ||
3596 | */ | ||
3597 | I915_WRITE(GEN6_UCGCTL2, | ||
3598 | GEN7_VDSUNIT_CLOCK_GATE_DISABLE | | ||
3599 | GEN7_TDLUNIT_CLOCK_GATE_DISABLE | | ||
3600 | GEN6_RCZUNIT_CLOCK_GATE_DISABLE | | ||
3601 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | ||
3602 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | ||
3603 | |||
3604 | I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); | ||
3605 | |||
3468 | for_each_pipe(pipe) { | 3606 | for_each_pipe(pipe) { |
3469 | I915_WRITE(DSPCNTR(pipe), | 3607 | I915_WRITE(DSPCNTR(pipe), |
3470 | I915_READ(DSPCNTR(pipe)) | | 3608 | I915_READ(DSPCNTR(pipe)) | |
@@ -3474,6 +3612,19 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
3474 | 3612 | ||
3475 | I915_WRITE(CACHE_MODE_1, | 3613 | I915_WRITE(CACHE_MODE_1, |
3476 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | 3614 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
3615 | |||
3616 | /* | ||
3617 | * On ValleyView, the GUnit needs to signal the GT | ||
3618 | * when flip and other events complete. So enable | ||
3619 | * all the GUnit->GT interrupts here | ||
3620 | */ | ||
3621 | I915_WRITE(VLV_DPFLIPSTAT, PIPEB_LINE_COMPARE_INT_EN | | ||
3622 | PIPEB_HLINE_INT_EN | PIPEB_VBLANK_INT_EN | | ||
3623 | SPRITED_FLIPDONE_INT_EN | SPRITEC_FLIPDONE_INT_EN | | ||
3624 | PLANEB_FLIPDONE_INT_EN | PIPEA_LINE_COMPARE_INT_EN | | ||
3625 | PIPEA_HLINE_INT_EN | PIPEA_VBLANK_INT_EN | | ||
3626 | SPRITEB_FLIPDONE_INT_EN | SPRITEA_FLIPDONE_INT_EN | | ||
3627 | PLANEA_FLIPDONE_INT_EN); | ||
3477 | } | 3628 | } |
3478 | 3629 | ||
3479 | static void g4x_init_clock_gating(struct drm_device *dev) | 3630 | static void g4x_init_clock_gating(struct drm_device *dev) |
@@ -3681,34 +3832,6 @@ void intel_init_pm(struct drm_device *dev) | |||
3681 | 3832 | ||
3682 | /* For FIFO watermark updates */ | 3833 | /* For FIFO watermark updates */ |
3683 | if (HAS_PCH_SPLIT(dev)) { | 3834 | if (HAS_PCH_SPLIT(dev)) { |
3684 | dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; | ||
3685 | dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; | ||
3686 | |||
3687 | /* IVB configs may use multi-threaded forcewake */ | ||
3688 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { | ||
3689 | u32 ecobus; | ||
3690 | |||
3691 | /* A small trick here - if the bios hasn't configured MT forcewake, | ||
3692 | * and if the device is in RC6, then force_wake_mt_get will not wake | ||
3693 | * the device and the ECOBUS read will return zero. Which will be | ||
3694 | * (correctly) interpreted by the test below as MT forcewake being | ||
3695 | * disabled. | ||
3696 | */ | ||
3697 | mutex_lock(&dev->struct_mutex); | ||
3698 | __gen6_gt_force_wake_mt_get(dev_priv); | ||
3699 | ecobus = I915_READ_NOTRACE(ECOBUS); | ||
3700 | __gen6_gt_force_wake_mt_put(dev_priv); | ||
3701 | mutex_unlock(&dev->struct_mutex); | ||
3702 | |||
3703 | if (ecobus & FORCEWAKE_MT_ENABLE) { | ||
3704 | DRM_DEBUG_KMS("Using MT version of forcewake\n"); | ||
3705 | dev_priv->display.force_wake_get = | ||
3706 | __gen6_gt_force_wake_mt_get; | ||
3707 | dev_priv->display.force_wake_put = | ||
3708 | __gen6_gt_force_wake_mt_put; | ||
3709 | } | ||
3710 | } | ||
3711 | |||
3712 | if (HAS_PCH_IBX(dev)) | 3835 | if (HAS_PCH_IBX(dev)) |
3713 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; | 3836 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; |
3714 | else if (HAS_PCH_CPT(dev)) | 3837 | else if (HAS_PCH_CPT(dev)) |
@@ -3756,7 +3879,7 @@ void intel_init_pm(struct drm_device *dev) | |||
3756 | "Disable CxSR\n"); | 3879 | "Disable CxSR\n"); |
3757 | dev_priv->display.update_wm = NULL; | 3880 | dev_priv->display.update_wm = NULL; |
3758 | } | 3881 | } |
3759 | dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; | 3882 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; |
3760 | dev_priv->display.sanitize_pm = gen6_sanitize_pm; | 3883 | dev_priv->display.sanitize_pm = gen6_sanitize_pm; |
3761 | } else | 3884 | } else |
3762 | dev_priv->display.update_wm = NULL; | 3885 | dev_priv->display.update_wm = NULL; |
@@ -3764,8 +3887,6 @@ void intel_init_pm(struct drm_device *dev) | |||
3764 | dev_priv->display.update_wm = valleyview_update_wm; | 3887 | dev_priv->display.update_wm = valleyview_update_wm; |
3765 | dev_priv->display.init_clock_gating = | 3888 | dev_priv->display.init_clock_gating = |
3766 | valleyview_init_clock_gating; | 3889 | valleyview_init_clock_gating; |
3767 | dev_priv->display.force_wake_get = vlv_force_wake_get; | ||
3768 | dev_priv->display.force_wake_put = vlv_force_wake_put; | ||
3769 | } else if (IS_PINEVIEW(dev)) { | 3890 | } else if (IS_PINEVIEW(dev)) { |
3770 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | 3891 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
3771 | dev_priv->is_ddr3, | 3892 | dev_priv->is_ddr3, |
@@ -3811,10 +3932,196 @@ void intel_init_pm(struct drm_device *dev) | |||
3811 | else | 3932 | else |
3812 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | 3933 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
3813 | } | 3934 | } |
3935 | } | ||
3936 | |||
3937 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) | ||
3938 | { | ||
3939 | u32 gt_thread_status_mask; | ||
3940 | |||
3941 | if (IS_HASWELL(dev_priv->dev)) | ||
3942 | gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; | ||
3943 | else | ||
3944 | gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; | ||
3814 | 3945 | ||
3815 | /* We attempt to init the necessary power wells early in the initialization | 3946 | /* w/a for a sporadic read returning 0 by waiting for the GT |
3816 | * time, so the subsystems that expect power to be enabled can work. | 3947 | * thread to wake up. |
3817 | */ | 3948 | */ |
3818 | intel_init_power_wells(dev); | 3949 | if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) |
3950 | DRM_ERROR("GT thread status wait timed out\n"); | ||
3951 | } | ||
3952 | |||
3953 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | ||
3954 | { | ||
3955 | u32 forcewake_ack; | ||
3956 | |||
3957 | if (IS_HASWELL(dev_priv->dev)) | ||
3958 | forcewake_ack = FORCEWAKE_ACK_HSW; | ||
3959 | else | ||
3960 | forcewake_ack = FORCEWAKE_ACK; | ||
3961 | |||
3962 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) | ||
3963 | DRM_ERROR("Force wake wait timed out\n"); | ||
3964 | |||
3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | ||
3966 | |||
3967 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | ||
3968 | DRM_ERROR("Force wake wait timed out\n"); | ||
3969 | |||
3970 | __gen6_gt_wait_for_thread_c0(dev_priv); | ||
3971 | } | ||
3972 | |||
3973 | static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | ||
3974 | { | ||
3975 | u32 forcewake_ack; | ||
3976 | |||
3977 | if (IS_HASWELL(dev_priv->dev)) | ||
3978 | forcewake_ack = FORCEWAKE_ACK_HSW; | ||
3979 | else | ||
3980 | forcewake_ack = FORCEWAKE_MT_ACK; | ||
3981 | |||
3982 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) | ||
3983 | DRM_ERROR("Force wake wait timed out\n"); | ||
3984 | |||
3985 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); | ||
3986 | |||
3987 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | ||
3988 | DRM_ERROR("Force wake wait timed out\n"); | ||
3989 | |||
3990 | __gen6_gt_wait_for_thread_c0(dev_priv); | ||
3991 | } | ||
3992 | |||
3993 | /* | ||
3994 | * Generally this is called implicitly by the register read function. However, | ||
3995 | * if some sequence requires the GT to not power down then this function should | ||
3996 | * be called at the beginning of the sequence followed by a call to | ||
3997 | * gen6_gt_force_wake_put() at the end of the sequence. | ||
3998 | */ | ||
3999 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | ||
4000 | { | ||
4001 | unsigned long irqflags; | ||
4002 | |||
4003 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); | ||
4004 | if (dev_priv->forcewake_count++ == 0) | ||
4005 | dev_priv->gt.force_wake_get(dev_priv); | ||
4006 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
4007 | } | ||
4008 | |||
4009 | void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | ||
4010 | { | ||
4011 | u32 gtfifodbg; | ||
4012 | gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); | ||
4013 | if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, | ||
4014 | "MMIO read or write has been dropped %x\n", gtfifodbg)) | ||
4015 | I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); | ||
4016 | } | ||
4017 | |||
4018 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | ||
4019 | { | ||
4020 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | ||
4021 | /* The below doubles as a POSTING_READ */ | ||
4022 | gen6_gt_check_fifodbg(dev_priv); | ||
4023 | } | ||
4024 | |||
4025 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | ||
4026 | { | ||
4027 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); | ||
4028 | /* The below doubles as a POSTING_READ */ | ||
4029 | gen6_gt_check_fifodbg(dev_priv); | ||
4030 | } | ||
4031 | |||
4032 | /* | ||
4033 | * see gen6_gt_force_wake_get() | ||
4034 | */ | ||
4035 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | ||
4036 | { | ||
4037 | unsigned long irqflags; | ||
4038 | |||
4039 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); | ||
4040 | if (--dev_priv->forcewake_count == 0) | ||
4041 | dev_priv->gt.force_wake_put(dev_priv); | ||
4042 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
4043 | } | ||
4044 | |||
4045 | int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | ||
4046 | { | ||
4047 | int ret = 0; | ||
4048 | |||
4049 | if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { | ||
4050 | int loop = 500; | ||
4051 | u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | ||
4052 | while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { | ||
4053 | udelay(10); | ||
4054 | fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | ||
4055 | } | ||
4056 | if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) | ||
4057 | ++ret; | ||
4058 | dev_priv->gt_fifo_count = fifo; | ||
4059 | } | ||
4060 | dev_priv->gt_fifo_count--; | ||
4061 | |||
4062 | return ret; | ||
4063 | } | ||
4064 | |||
4065 | static void vlv_force_wake_get(struct drm_i915_private *dev_priv) | ||
4066 | { | ||
4067 | /* Already awake? */ | ||
4068 | if ((I915_READ(0x130094) & 0xa1) == 0xa1) | ||
4069 | return; | ||
4070 | |||
4071 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff); | ||
4072 | POSTING_READ(FORCEWAKE_VLV); | ||
4073 | |||
4074 | if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500)) | ||
4075 | DRM_ERROR("Force wake wait timed out\n"); | ||
4076 | |||
4077 | __gen6_gt_wait_for_thread_c0(dev_priv); | ||
4078 | } | ||
4079 | |||
4080 | static void vlv_force_wake_put(struct drm_i915_private *dev_priv) | ||
4081 | { | ||
4082 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000); | ||
4083 | /* FIXME: confirm VLV behavior with Punit folks */ | ||
4084 | POSTING_READ(FORCEWAKE_VLV); | ||
4085 | } | ||
4086 | |||
4087 | void intel_gt_init(struct drm_device *dev) | ||
4088 | { | ||
4089 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4090 | |||
4091 | spin_lock_init(&dev_priv->gt_lock); | ||
4092 | |||
4093 | if (IS_VALLEYVIEW(dev)) { | ||
4094 | dev_priv->gt.force_wake_get = vlv_force_wake_get; | ||
4095 | dev_priv->gt.force_wake_put = vlv_force_wake_put; | ||
4096 | } else if (INTEL_INFO(dev)->gen >= 6) { | ||
4097 | dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; | ||
4098 | dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; | ||
4099 | |||
4100 | /* IVB configs may use multi-threaded forcewake */ | ||
4101 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { | ||
4102 | u32 ecobus; | ||
4103 | |||
4104 | /* A small trick here - if the bios hasn't configured | ||
4105 | * MT forcewake, and if the device is in RC6, then | ||
4106 | * force_wake_mt_get will not wake the device and the | ||
4107 | * ECOBUS read will return zero. Which will be | ||
4108 | * (correctly) interpreted by the test below as MT | ||
4109 | * forcewake being disabled. | ||
4110 | */ | ||
4111 | mutex_lock(&dev->struct_mutex); | ||
4112 | __gen6_gt_force_wake_mt_get(dev_priv); | ||
4113 | ecobus = I915_READ_NOTRACE(ECOBUS); | ||
4114 | __gen6_gt_force_wake_mt_put(dev_priv); | ||
4115 | mutex_unlock(&dev->struct_mutex); | ||
4116 | |||
4117 | if (ecobus & FORCEWAKE_MT_ENABLE) { | ||
4118 | DRM_DEBUG_KMS("Using MT version of forcewake\n"); | ||
4119 | dev_priv->gt.force_wake_get = | ||
4120 | __gen6_gt_force_wake_mt_get; | ||
4121 | dev_priv->gt.force_wake_put = | ||
4122 | __gen6_gt_force_wake_mt_put; | ||
4123 | } | ||
4124 | } | ||
4125 | } | ||
3819 | } | 4126 | } |
3820 | 4127 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e5b84ff89ca5..bf0195a96d53 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -219,19 +219,28 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
219 | int ret; | 219 | int ret; |
220 | 220 | ||
221 | /* Force SNB workarounds for PIPE_CONTROL flushes */ | 221 | /* Force SNB workarounds for PIPE_CONTROL flushes */ |
222 | intel_emit_post_sync_nonzero_flush(ring); | 222 | ret = intel_emit_post_sync_nonzero_flush(ring); |
223 | if (ret) | ||
224 | return ret; | ||
223 | 225 | ||
224 | /* Just flush everything. Experiments have shown that reducing the | 226 | /* Just flush everything. Experiments have shown that reducing the |
225 | * number of bits based on the write domains has little performance | 227 | * number of bits based on the write domains has little performance |
226 | * impact. | 228 | * impact. |
227 | */ | 229 | */ |
228 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | 230 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; |
231 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | ||
229 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | 232 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; |
230 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | 233 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; |
231 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | 234 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; |
232 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | 235 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; |
233 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | 236 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; |
234 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | 237 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; |
238 | /* | ||
239 | * Ensure that any following seqno writes only happen when the render | ||
240 | * cache is indeed flushed (but only if the caller actually wants that). | ||
241 | */ | ||
242 | if (flush_domains) | ||
243 | flags |= PIPE_CONTROL_CS_STALL; | ||
235 | 244 | ||
236 | ret = intel_ring_begin(ring, 6); | 245 | ret = intel_ring_begin(ring, 6); |
237 | if (ret) | 246 | if (ret) |
@@ -433,11 +442,21 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
433 | */ | 442 | */ |
434 | I915_WRITE(CACHE_MODE_0, | 443 | I915_WRITE(CACHE_MODE_0, |
435 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); | 444 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); |
445 | |||
446 | /* This is not explicitly set for GEN6, so read the register. | ||
447 | * see intel_ring_mi_set_context() for why we care. | ||
448 | * TODO: consider explicitly setting the bit for GEN5 | ||
449 | */ | ||
450 | ring->itlb_before_ctx_switch = | ||
451 | !!(I915_READ(GFX_MODE) & GFX_TLB_INVALIDATE_ALWAYS); | ||
436 | } | 452 | } |
437 | 453 | ||
438 | if (INTEL_INFO(dev)->gen >= 6) | 454 | if (INTEL_INFO(dev)->gen >= 6) |
439 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); | 455 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); |
440 | 456 | ||
457 | if (IS_IVYBRIDGE(dev)) | ||
458 | I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); | ||
459 | |||
441 | return ret; | 460 | return ret; |
442 | } | 461 | } |
443 | 462 | ||
@@ -825,7 +844,11 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) | |||
825 | 844 | ||
826 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | 845 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
827 | if (ring->irq_refcount++ == 0) { | 846 | if (ring->irq_refcount++ == 0) { |
828 | I915_WRITE_IMR(ring, ~ring->irq_enable_mask); | 847 | if (IS_IVYBRIDGE(dev) && ring->id == RCS) |
848 | I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | | ||
849 | GEN6_RENDER_L3_PARITY_ERROR)); | ||
850 | else | ||
851 | I915_WRITE_IMR(ring, ~ring->irq_enable_mask); | ||
829 | dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; | 852 | dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; |
830 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 853 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
831 | POSTING_READ(GTIMR); | 854 | POSTING_READ(GTIMR); |
@@ -844,7 +867,10 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) | |||
844 | 867 | ||
845 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | 868 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
846 | if (--ring->irq_refcount == 0) { | 869 | if (--ring->irq_refcount == 0) { |
847 | I915_WRITE_IMR(ring, ~0); | 870 | if (IS_IVYBRIDGE(dev) && ring->id == RCS) |
871 | I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); | ||
872 | else | ||
873 | I915_WRITE_IMR(ring, ~0); | ||
848 | dev_priv->gt_irq_mask |= ring->irq_enable_mask; | 874 | dev_priv->gt_irq_mask |= ring->irq_enable_mask; |
849 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 875 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
850 | POSTING_READ(GTIMR); | 876 | POSTING_READ(GTIMR); |
@@ -946,6 +972,7 @@ static int init_status_page(struct intel_ring_buffer *ring) | |||
946 | ring->status_page.gfx_addr = obj->gtt_offset; | 972 | ring->status_page.gfx_addr = obj->gtt_offset; |
947 | ring->status_page.page_addr = kmap(obj->pages[0]); | 973 | ring->status_page.page_addr = kmap(obj->pages[0]); |
948 | if (ring->status_page.page_addr == NULL) { | 974 | if (ring->status_page.page_addr == NULL) { |
975 | ret = -ENOMEM; | ||
949 | goto err_unpin; | 976 | goto err_unpin; |
950 | } | 977 | } |
951 | ring->status_page.obj = obj; | 978 | ring->status_page.obj = obj; |
@@ -969,6 +996,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
969 | struct intel_ring_buffer *ring) | 996 | struct intel_ring_buffer *ring) |
970 | { | 997 | { |
971 | struct drm_i915_gem_object *obj; | 998 | struct drm_i915_gem_object *obj; |
999 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
972 | int ret; | 1000 | int ret; |
973 | 1001 | ||
974 | ring->dev = dev; | 1002 | ring->dev = dev; |
@@ -1002,8 +1030,9 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1002 | if (ret) | 1030 | if (ret) |
1003 | goto err_unpin; | 1031 | goto err_unpin; |
1004 | 1032 | ||
1005 | ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset, | 1033 | ring->virtual_start = |
1006 | ring->size); | 1034 | ioremap_wc(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset, |
1035 | ring->size); | ||
1007 | if (ring->virtual_start == NULL) { | 1036 | if (ring->virtual_start == NULL) { |
1008 | DRM_ERROR("Failed to map ringbuffer.\n"); | 1037 | DRM_ERROR("Failed to map ringbuffer.\n"); |
1009 | ret = -EINVAL; | 1038 | ret = -EINVAL; |
@@ -1089,20 +1118,9 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) | |||
1089 | 1118 | ||
1090 | static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) | 1119 | static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) |
1091 | { | 1120 | { |
1092 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
1093 | bool was_interruptible; | ||
1094 | int ret; | 1121 | int ret; |
1095 | 1122 | ||
1096 | /* XXX As we have not yet audited all the paths to check that | 1123 | ret = i915_wait_seqno(ring, seqno); |
1097 | * they are ready for ERESTARTSYS from intel_ring_begin, do not | ||
1098 | * allow us to be interruptible by a signal. | ||
1099 | */ | ||
1100 | was_interruptible = dev_priv->mm.interruptible; | ||
1101 | dev_priv->mm.interruptible = false; | ||
1102 | |||
1103 | ret = i915_wait_request(ring, seqno); | ||
1104 | |||
1105 | dev_priv->mm.interruptible = was_interruptible; | ||
1106 | if (!ret) | 1124 | if (!ret) |
1107 | i915_gem_retire_requests_ring(ring); | 1125 | i915_gem_retire_requests_ring(ring); |
1108 | 1126 | ||
@@ -1200,8 +1218,10 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
1200 | } | 1218 | } |
1201 | 1219 | ||
1202 | msleep(1); | 1220 | msleep(1); |
1203 | if (atomic_read(&dev_priv->mm.wedged)) | 1221 | |
1204 | return -EAGAIN; | 1222 | ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); |
1223 | if (ret) | ||
1224 | return ret; | ||
1205 | } while (!time_after(jiffies, end)); | 1225 | } while (!time_after(jiffies, end)); |
1206 | trace_i915_ring_wait_end(ring); | 1226 | trace_i915_ring_wait_end(ring); |
1207 | return -EBUSY; | 1227 | return -EBUSY; |
@@ -1210,12 +1230,13 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
1210 | int intel_ring_begin(struct intel_ring_buffer *ring, | 1230 | int intel_ring_begin(struct intel_ring_buffer *ring, |
1211 | int num_dwords) | 1231 | int num_dwords) |
1212 | { | 1232 | { |
1213 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 1233 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1214 | int n = 4*num_dwords; | 1234 | int n = 4*num_dwords; |
1215 | int ret; | 1235 | int ret; |
1216 | 1236 | ||
1217 | if (unlikely(atomic_read(&dev_priv->mm.wedged))) | 1237 | ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); |
1218 | return -EIO; | 1238 | if (ret) |
1239 | return ret; | ||
1219 | 1240 | ||
1220 | if (unlikely(ring->tail + n > ring->effective_size)) { | 1241 | if (unlikely(ring->tail + n > ring->effective_size)) { |
1221 | ret = intel_wrap_ring_buffer(ring); | 1242 | ret = intel_wrap_ring_buffer(ring); |
@@ -1250,20 +1271,31 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, | |||
1250 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1271 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1251 | 1272 | ||
1252 | /* Every tail move must follow the sequence below */ | 1273 | /* Every tail move must follow the sequence below */ |
1274 | |||
1275 | /* Disable notification that the ring is IDLE. The GT | ||
1276 | * will then assume that it is busy and bring it out of rc6. | ||
1277 | */ | ||
1253 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 1278 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
1254 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | | 1279 | _MASKED_BIT_ENABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); |
1255 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE); | ||
1256 | I915_WRITE(GEN6_BSD_RNCID, 0x0); | ||
1257 | 1280 | ||
1281 | /* Clear the context id. Here be magic! */ | ||
1282 | I915_WRITE64(GEN6_BSD_RNCID, 0x0); | ||
1283 | |||
1284 | /* Wait for the ring not to be idle, i.e. for it to wake up. */ | ||
1258 | if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & | 1285 | if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & |
1259 | GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0, | 1286 | GEN6_BSD_SLEEP_INDICATOR) == 0, |
1260 | 50)) | 1287 | 50)) |
1261 | DRM_ERROR("timed out waiting for IDLE Indicator\n"); | 1288 | DRM_ERROR("timed out waiting for the BSD ring to wake up\n"); |
1262 | 1289 | ||
1290 | /* Now that the ring is fully powered up, update the tail */ | ||
1263 | I915_WRITE_TAIL(ring, value); | 1291 | I915_WRITE_TAIL(ring, value); |
1292 | POSTING_READ(RING_TAIL(ring->mmio_base)); | ||
1293 | |||
1294 | /* Let the ring send IDLE messages to the GT again, | ||
1295 | * and so let it sleep to conserve power when idle. | ||
1296 | */ | ||
1264 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 1297 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
1265 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | | 1298 | _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); |
1266 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); | ||
1267 | } | 1299 | } |
1268 | 1300 | ||
1269 | static int gen6_ring_flush(struct intel_ring_buffer *ring, | 1301 | static int gen6_ring_flush(struct intel_ring_buffer *ring, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 55d3da26bae7..1d3c81fdad92 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -113,9 +113,17 @@ struct intel_ring_buffer { | |||
113 | * Do we have some not yet emitted requests outstanding? | 113 | * Do we have some not yet emitted requests outstanding? |
114 | */ | 114 | */ |
115 | u32 outstanding_lazy_request; | 115 | u32 outstanding_lazy_request; |
116 | bool gpu_caches_dirty; | ||
116 | 117 | ||
117 | wait_queue_head_t irq_queue; | 118 | wait_queue_head_t irq_queue; |
118 | 119 | ||
120 | /** | ||
121 | * Do an explicit TLB flush before MI_SET_CONTEXT | ||
122 | */ | ||
123 | bool itlb_before_ctx_switch; | ||
124 | struct i915_hw_context *default_context; | ||
125 | struct drm_i915_gem_object *last_context_obj; | ||
126 | |||
119 | void *private; | 127 | void *private; |
120 | }; | 128 | }; |
121 | 129 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index b6a9d45fc3c6..26a6a4d0d078 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -140,9 +140,6 @@ struct intel_sdvo { | |||
140 | 140 | ||
141 | /* DDC bus used by this SDVO encoder */ | 141 | /* DDC bus used by this SDVO encoder */ |
142 | uint8_t ddc_bus; | 142 | uint8_t ddc_bus; |
143 | |||
144 | /* Input timings for adjusted_mode */ | ||
145 | struct intel_sdvo_dtd input_dtd; | ||
146 | }; | 143 | }; |
147 | 144 | ||
148 | struct intel_sdvo_connector { | 145 | struct intel_sdvo_connector { |
@@ -938,7 +935,7 @@ static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | |||
938 | 935 | ||
939 | static bool | 936 | static bool |
940 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, | 937 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
941 | struct drm_display_mode *mode) | 938 | const struct drm_display_mode *mode) |
942 | { | 939 | { |
943 | struct intel_sdvo_dtd output_dtd; | 940 | struct intel_sdvo_dtd output_dtd; |
944 | 941 | ||
@@ -953,11 +950,15 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, | |||
953 | return true; | 950 | return true; |
954 | } | 951 | } |
955 | 952 | ||
953 | /* Asks the sdvo controller for the preferred input mode given the output mode. | ||
954 | * Unfortunately we have to set up the full output mode to do that. */ | ||
956 | static bool | 955 | static bool |
957 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | 956 | intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, |
958 | struct drm_display_mode *mode, | 957 | const struct drm_display_mode *mode, |
959 | struct drm_display_mode *adjusted_mode) | 958 | struct drm_display_mode *adjusted_mode) |
960 | { | 959 | { |
960 | struct intel_sdvo_dtd input_dtd; | ||
961 | |||
961 | /* Reset the input timing to the screen. Assume always input 0. */ | 962 | /* Reset the input timing to the screen. Assume always input 0. */ |
962 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 963 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
963 | return false; | 964 | return false; |
@@ -969,16 +970,16 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | |||
969 | return false; | 970 | return false; |
970 | 971 | ||
971 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, | 972 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
972 | &intel_sdvo->input_dtd)) | 973 | &input_dtd)) |
973 | return false; | 974 | return false; |
974 | 975 | ||
975 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); | 976 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
976 | 977 | ||
977 | return true; | 978 | return true; |
978 | } | 979 | } |
979 | 980 | ||
980 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 981 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
981 | struct drm_display_mode *mode, | 982 | const struct drm_display_mode *mode, |
982 | struct drm_display_mode *adjusted_mode) | 983 | struct drm_display_mode *adjusted_mode) |
983 | { | 984 | { |
984 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 985 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
@@ -993,17 +994,17 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
993 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | 994 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
994 | return false; | 995 | return false; |
995 | 996 | ||
996 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 997 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
997 | mode, | 998 | mode, |
998 | adjusted_mode); | 999 | adjusted_mode); |
999 | } else if (intel_sdvo->is_lvds) { | 1000 | } else if (intel_sdvo->is_lvds) { |
1000 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, | 1001 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1001 | intel_sdvo->sdvo_lvds_fixed_mode)) | 1002 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1002 | return false; | 1003 | return false; |
1003 | 1004 | ||
1004 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 1005 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
1005 | mode, | 1006 | mode, |
1006 | adjusted_mode); | 1007 | adjusted_mode); |
1007 | } | 1008 | } |
1008 | 1009 | ||
1009 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1010 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
@@ -1057,7 +1058,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1057 | intel_sdvo->sdvo_lvds_fixed_mode); | 1058 | intel_sdvo->sdvo_lvds_fixed_mode); |
1058 | else | 1059 | else |
1059 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1060 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1060 | (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); | 1061 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
1062 | DRM_INFO("Setting output timings on %s failed\n", | ||
1063 | SDVO_NAME(intel_sdvo)); | ||
1061 | 1064 | ||
1062 | /* Set the input timing to the screen. Assume always input 0. */ | 1065 | /* Set the input timing to the screen. Assume always input 0. */ |
1063 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1066 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
@@ -1079,7 +1082,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1079 | * adjusted_mode. | 1082 | * adjusted_mode. |
1080 | */ | 1083 | */ |
1081 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1084 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1082 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1085 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1086 | DRM_INFO("Setting input timings on %s failed\n", | ||
1087 | SDVO_NAME(intel_sdvo)); | ||
1083 | 1088 | ||
1084 | switch (pixel_multiplier) { | 1089 | switch (pixel_multiplier) { |
1085 | default: | 1090 | default: |
@@ -1376,7 +1381,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1376 | 1381 | ||
1377 | /* add 30ms delay when the output type might be TV */ | 1382 | /* add 30ms delay when the output type might be TV */ |
1378 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) | 1383 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) |
1379 | mdelay(30); | 1384 | msleep(30); |
1380 | 1385 | ||
1381 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) | 1386 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1382 | return connector_status_unknown; | 1387 | return connector_status_unknown; |
@@ -2521,6 +2526,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2521 | struct drm_i915_private *dev_priv = dev->dev_private; | 2526 | struct drm_i915_private *dev_priv = dev->dev_private; |
2522 | struct intel_encoder *intel_encoder; | 2527 | struct intel_encoder *intel_encoder; |
2523 | struct intel_sdvo *intel_sdvo; | 2528 | struct intel_sdvo *intel_sdvo; |
2529 | u32 hotplug_mask; | ||
2524 | int i; | 2530 | int i; |
2525 | 2531 | ||
2526 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); | 2532 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
@@ -2552,10 +2558,18 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2552 | } | 2558 | } |
2553 | } | 2559 | } |
2554 | 2560 | ||
2555 | if (intel_sdvo->is_sdvob) | 2561 | hotplug_mask = 0; |
2556 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2562 | if (IS_G4X(dev)) { |
2557 | else | 2563 | hotplug_mask = intel_sdvo->is_sdvob ? |
2558 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2564 | SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X; |
2565 | } else if (IS_GEN4(dev)) { | ||
2566 | hotplug_mask = intel_sdvo->is_sdvob ? | ||
2567 | SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965; | ||
2568 | } else { | ||
2569 | hotplug_mask = intel_sdvo->is_sdvob ? | ||
2570 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; | ||
2571 | } | ||
2572 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2559 | 2573 | ||
2560 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2574 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2561 | 2575 | ||
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 2a20fb0781d7..cc8df4de2d92 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -56,6 +56,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
56 | sprctl &= ~SPRITE_PIXFORMAT_MASK; | 56 | sprctl &= ~SPRITE_PIXFORMAT_MASK; |
57 | sprctl &= ~SPRITE_RGB_ORDER_RGBX; | 57 | sprctl &= ~SPRITE_RGB_ORDER_RGBX; |
58 | sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; | 58 | sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; |
59 | sprctl &= ~SPRITE_TILED; | ||
59 | 60 | ||
60 | switch (fb->pixel_format) { | 61 | switch (fb->pixel_format) { |
61 | case DRM_FORMAT_XBGR8888: | 62 | case DRM_FORMAT_XBGR8888: |
@@ -84,7 +85,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
84 | break; | 85 | break; |
85 | default: | 86 | default: |
86 | DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); | 87 | DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); |
87 | sprctl |= DVS_FORMAT_RGBX888; | 88 | sprctl |= SPRITE_FORMAT_RGBX888; |
88 | pixel_size = 4; | 89 | pixel_size = 4; |
89 | break; | 90 | break; |
90 | } | 91 | } |
@@ -233,6 +234,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
233 | dvscntr &= ~DVS_PIXFORMAT_MASK; | 234 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
234 | dvscntr &= ~DVS_RGB_ORDER_XBGR; | 235 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
235 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; | 236 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
237 | dvscntr &= ~DVS_TILED; | ||
236 | 238 | ||
237 | switch (fb->pixel_format) { | 239 | switch (fb->pixel_format) { |
238 | case DRM_FORMAT_XBGR8888: | 240 | case DRM_FORMAT_XBGR8888: |
@@ -326,6 +328,12 @@ intel_enable_primary(struct drm_crtc *crtc) | |||
326 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 328 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
327 | int reg = DSPCNTR(intel_crtc->plane); | 329 | int reg = DSPCNTR(intel_crtc->plane); |
328 | 330 | ||
331 | if (!intel_crtc->primary_disabled) | ||
332 | return; | ||
333 | |||
334 | intel_crtc->primary_disabled = false; | ||
335 | intel_update_fbc(dev); | ||
336 | |||
329 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); | 337 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
330 | } | 338 | } |
331 | 339 | ||
@@ -337,7 +345,13 @@ intel_disable_primary(struct drm_crtc *crtc) | |||
337 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 345 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
338 | int reg = DSPCNTR(intel_crtc->plane); | 346 | int reg = DSPCNTR(intel_crtc->plane); |
339 | 347 | ||
348 | if (intel_crtc->primary_disabled) | ||
349 | return; | ||
350 | |||
340 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); | 351 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
352 | |||
353 | intel_crtc->primary_disabled = true; | ||
354 | intel_update_fbc(dev); | ||
341 | } | 355 | } |
342 | 356 | ||
343 | static int | 357 | static int |
@@ -485,18 +499,14 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
485 | * Be sure to re-enable the primary before the sprite is no longer | 499 | * Be sure to re-enable the primary before the sprite is no longer |
486 | * covering it fully. | 500 | * covering it fully. |
487 | */ | 501 | */ |
488 | if (!disable_primary && intel_plane->primary_disabled) { | 502 | if (!disable_primary) |
489 | intel_enable_primary(crtc); | 503 | intel_enable_primary(crtc); |
490 | intel_plane->primary_disabled = false; | ||
491 | } | ||
492 | 504 | ||
493 | intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, | 505 | intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, |
494 | crtc_w, crtc_h, x, y, src_w, src_h); | 506 | crtc_w, crtc_h, x, y, src_w, src_h); |
495 | 507 | ||
496 | if (disable_primary) { | 508 | if (disable_primary) |
497 | intel_disable_primary(crtc); | 509 | intel_disable_primary(crtc); |
498 | intel_plane->primary_disabled = true; | ||
499 | } | ||
500 | 510 | ||
501 | /* Unpin old obj after new one is active to avoid ugliness */ | 511 | /* Unpin old obj after new one is active to avoid ugliness */ |
502 | if (old_obj) { | 512 | if (old_obj) { |
@@ -527,11 +537,8 @@ intel_disable_plane(struct drm_plane *plane) | |||
527 | struct intel_plane *intel_plane = to_intel_plane(plane); | 537 | struct intel_plane *intel_plane = to_intel_plane(plane); |
528 | int ret = 0; | 538 | int ret = 0; |
529 | 539 | ||
530 | if (intel_plane->primary_disabled) { | 540 | if (plane->crtc) |
531 | intel_enable_primary(plane->crtc); | 541 | intel_enable_primary(plane->crtc); |
532 | intel_plane->primary_disabled = false; | ||
533 | } | ||
534 | |||
535 | intel_plane->disable_plane(plane); | 542 | intel_plane->disable_plane(plane); |
536 | 543 | ||
537 | if (!intel_plane->obj) | 544 | if (!intel_plane->obj) |
@@ -685,6 +692,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) | |||
685 | break; | 692 | break; |
686 | 693 | ||
687 | default: | 694 | default: |
695 | kfree(intel_plane); | ||
688 | return -ENODEV; | 696 | return -ENODEV; |
689 | } | 697 | } |
690 | 698 | ||
@@ -699,4 +707,3 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) | |||
699 | 707 | ||
700 | return ret; | 708 | return ret; |
701 | } | 709 | } |
702 | |||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index a233a51fd7e6..befce6c49704 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -891,24 +891,21 @@ intel_tv_mode_valid(struct drm_connector *connector, | |||
891 | 891 | ||
892 | 892 | ||
893 | static bool | 893 | static bool |
894 | intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 894 | intel_tv_mode_fixup(struct drm_encoder *encoder, |
895 | const struct drm_display_mode *mode, | ||
895 | struct drm_display_mode *adjusted_mode) | 896 | struct drm_display_mode *adjusted_mode) |
896 | { | 897 | { |
897 | struct drm_device *dev = encoder->dev; | 898 | struct drm_device *dev = encoder->dev; |
898 | struct drm_mode_config *drm_config = &dev->mode_config; | ||
899 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | 899 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
900 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 900 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
901 | struct drm_encoder *other_encoder; | 901 | struct intel_encoder *other_encoder; |
902 | 902 | ||
903 | if (!tv_mode) | 903 | if (!tv_mode) |
904 | return false; | 904 | return false; |
905 | 905 | ||
906 | /* FIXME: lock encoder list */ | 906 | for_each_encoder_on_crtc(dev, encoder->crtc, other_encoder) |
907 | list_for_each_entry(other_encoder, &drm_config->encoder_list, head) { | 907 | if (&other_encoder->base != encoder) |
908 | if (other_encoder != encoder && | ||
909 | other_encoder->crtc == encoder->crtc) | ||
910 | return false; | 908 | return false; |
911 | } | ||
912 | 909 | ||
913 | adjusted_mode->clock = tv_mode->clock; | 910 | adjusted_mode->clock = tv_mode->clock; |
914 | return true; | 911 | return true; |
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index f9a925d58819..b1bb46de3f5a 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c | |||
@@ -75,7 +75,6 @@ static struct drm_driver driver = { | |||
75 | .irq_postinstall = mga_driver_irq_postinstall, | 75 | .irq_postinstall = mga_driver_irq_postinstall, |
76 | .irq_uninstall = mga_driver_irq_uninstall, | 76 | .irq_uninstall = mga_driver_irq_uninstall, |
77 | .irq_handler = mga_driver_irq_handler, | 77 | .irq_handler = mga_driver_irq_handler, |
78 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
79 | .ioctls = mga_ioctls, | 78 | .ioctls = mga_ioctls, |
80 | .dma_ioctl = mga_dma_buffers, | 79 | .dma_ioctl = mga_dma_buffers, |
81 | .fops = &mga_driver_fops, | 80 | .fops = &mga_driver_fops, |
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 93e832d6c328..ea1024d79974 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c | |||
@@ -47,6 +47,9 @@ static void mgag200_kick_out_firmware_fb(struct pci_dev *pdev) | |||
47 | bool primary = false; | 47 | bool primary = false; |
48 | 48 | ||
49 | ap = alloc_apertures(1); | 49 | ap = alloc_apertures(1); |
50 | if (!ap) | ||
51 | return; | ||
52 | |||
50 | ap->ranges[0].base = pci_resource_start(pdev, 0); | 53 | ap->ranges[0].base = pci_resource_start(pdev, 0); |
51 | ap->ranges[0].size = pci_resource_len(pdev, 0); | 54 | ap->ranges[0].size = pci_resource_len(pdev, 0); |
52 | 55 | ||
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index d303061b251e..a4d7c500c97b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -78,8 +78,8 @@ static inline void mga_wait_busy(struct mga_device *mdev) | |||
78 | * to just pass that straight through, so this does nothing | 78 | * to just pass that straight through, so this does nothing |
79 | */ | 79 | */ |
80 | static bool mga_crtc_mode_fixup(struct drm_crtc *crtc, | 80 | static bool mga_crtc_mode_fixup(struct drm_crtc *crtc, |
81 | struct drm_display_mode *mode, | 81 | const struct drm_display_mode *mode, |
82 | struct drm_display_mode *adjusted_mode) | 82 | struct drm_display_mode *adjusted_mode) |
83 | { | 83 | { |
84 | return true; | 84 | return true; |
85 | } | 85 | } |
@@ -1322,8 +1322,8 @@ void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
1322 | * to handle any encoder-specific limitations | 1322 | * to handle any encoder-specific limitations |
1323 | */ | 1323 | */ |
1324 | static bool mga_encoder_mode_fixup(struct drm_encoder *encoder, | 1324 | static bool mga_encoder_mode_fixup(struct drm_encoder *encoder, |
1325 | struct drm_display_mode *mode, | 1325 | const struct drm_display_mode *mode, |
1326 | struct drm_display_mode *adjusted_mode) | 1326 | struct drm_display_mode *adjusted_mode) |
1327 | { | 1327 | { |
1328 | return true; | 1328 | return true; |
1329 | } | 1329 | } |
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index fe5267d06ab5..1cece6a78f39 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | 6 | nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ |
7 | nouveau_object.o nouveau_irq.o nouveau_notifier.o \ | 7 | nouveau_gpuobj.o nouveau_irq.o nouveau_notifier.o \ |
8 | nouveau_sgdma.o nouveau_dma.o nouveau_util.o \ | 8 | nouveau_sgdma.o nouveau_dma.o nouveau_util.o \ |
9 | nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ | 9 | nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ |
10 | nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ | 10 | nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ |
@@ -12,6 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
12 | nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o \ | 12 | nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o \ |
13 | nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \ | 13 | nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \ |
14 | nouveau_mm.o nouveau_vm.o nouveau_mxm.o nouveau_gpio.o \ | 14 | nouveau_mm.o nouveau_vm.o nouveau_mxm.o nouveau_gpio.o \ |
15 | nouveau_abi16.o \ | ||
15 | nv04_timer.o \ | 16 | nv04_timer.o \ |
16 | nv04_mc.o nv40_mc.o nv50_mc.o \ | 17 | nv04_mc.o nv40_mc.o nv50_mc.o \ |
17 | nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \ | 18 | nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c new file mode 100644 index 000000000000..ff23d88880e5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include "drmP.h" | ||
25 | |||
26 | #include "nouveau_drv.h" | ||
27 | #include "nouveau_dma.h" | ||
28 | #include "nouveau_abi16.h" | ||
29 | #include "nouveau_ramht.h" | ||
30 | #include "nouveau_software.h" | ||
31 | |||
32 | int | ||
33 | nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) | ||
34 | { | ||
35 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
36 | struct drm_nouveau_getparam *getparam = data; | ||
37 | |||
38 | switch (getparam->param) { | ||
39 | case NOUVEAU_GETPARAM_CHIPSET_ID: | ||
40 | getparam->value = dev_priv->chipset; | ||
41 | break; | ||
42 | case NOUVEAU_GETPARAM_PCI_VENDOR: | ||
43 | getparam->value = dev->pci_vendor; | ||
44 | break; | ||
45 | case NOUVEAU_GETPARAM_PCI_DEVICE: | ||
46 | getparam->value = dev->pci_device; | ||
47 | break; | ||
48 | case NOUVEAU_GETPARAM_BUS_TYPE: | ||
49 | if (drm_pci_device_is_agp(dev)) | ||
50 | getparam->value = 0; | ||
51 | else | ||
52 | if (!pci_is_pcie(dev->pdev)) | ||
53 | getparam->value = 1; | ||
54 | else | ||
55 | getparam->value = 2; | ||
56 | break; | ||
57 | case NOUVEAU_GETPARAM_FB_SIZE: | ||
58 | getparam->value = dev_priv->fb_available_size; | ||
59 | break; | ||
60 | case NOUVEAU_GETPARAM_AGP_SIZE: | ||
61 | getparam->value = dev_priv->gart_info.aper_size; | ||
62 | break; | ||
63 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: | ||
64 | getparam->value = 0; /* deprecated */ | ||
65 | break; | ||
66 | case NOUVEAU_GETPARAM_PTIMER_TIME: | ||
67 | getparam->value = dev_priv->engine.timer.read(dev); | ||
68 | break; | ||
69 | case NOUVEAU_GETPARAM_HAS_BO_USAGE: | ||
70 | getparam->value = 1; | ||
71 | break; | ||
72 | case NOUVEAU_GETPARAM_HAS_PAGEFLIP: | ||
73 | getparam->value = 1; | ||
74 | break; | ||
75 | case NOUVEAU_GETPARAM_GRAPH_UNITS: | ||
76 | /* NV40 and NV50 versions are quite different, but register | ||
77 | * address is the same. User is supposed to know the card | ||
78 | * family anyway... */ | ||
79 | if (dev_priv->chipset >= 0x40) { | ||
80 | getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS); | ||
81 | break; | ||
82 | } | ||
83 | /* FALLTHRU */ | ||
84 | default: | ||
85 | NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | int | ||
93 | nouveau_abi16_ioctl_setparam(ABI16_IOCTL_ARGS) | ||
94 | { | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | int | ||
99 | nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) | ||
100 | { | ||
101 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
102 | struct drm_nouveau_channel_alloc *init = data; | ||
103 | struct nouveau_channel *chan; | ||
104 | int ret; | ||
105 | |||
106 | if (!dev_priv->eng[NVOBJ_ENGINE_GR]) | ||
107 | return -ENODEV; | ||
108 | |||
109 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) | ||
110 | return -EINVAL; | ||
111 | |||
112 | ret = nouveau_channel_alloc(dev, &chan, file_priv, | ||
113 | init->fb_ctxdma_handle, | ||
114 | init->tt_ctxdma_handle); | ||
115 | if (ret) | ||
116 | return ret; | ||
117 | init->channel = chan->id; | ||
118 | |||
119 | if (nouveau_vram_pushbuf == 0) { | ||
120 | if (chan->dma.ib_max) | ||
121 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | | ||
122 | NOUVEAU_GEM_DOMAIN_GART; | ||
123 | else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM) | ||
124 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; | ||
125 | else | ||
126 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; | ||
127 | } else { | ||
128 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; | ||
129 | } | ||
130 | |||
131 | if (dev_priv->card_type < NV_C0) { | ||
132 | init->subchan[0].handle = 0x00000000; | ||
133 | init->subchan[0].grclass = 0x0000; | ||
134 | init->subchan[1].handle = NvSw; | ||
135 | init->subchan[1].grclass = NV_SW; | ||
136 | init->nr_subchan = 2; | ||
137 | } | ||
138 | |||
139 | /* Named memory object area */ | ||
140 | ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, | ||
141 | &init->notifier_handle); | ||
142 | |||
143 | if (ret == 0) | ||
144 | atomic_inc(&chan->users); /* userspace reference */ | ||
145 | nouveau_channel_put(&chan); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | int | ||
150 | nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) | ||
151 | { | ||
152 | struct drm_nouveau_channel_free *req = data; | ||
153 | struct nouveau_channel *chan; | ||
154 | |||
155 | chan = nouveau_channel_get(file_priv, req->channel); | ||
156 | if (IS_ERR(chan)) | ||
157 | return PTR_ERR(chan); | ||
158 | |||
159 | list_del(&chan->list); | ||
160 | atomic_dec(&chan->users); | ||
161 | nouveau_channel_put(&chan); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | int | ||
166 | nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) | ||
167 | { | ||
168 | struct drm_nouveau_grobj_alloc *init = data; | ||
169 | struct nouveau_channel *chan; | ||
170 | int ret; | ||
171 | |||
172 | if (init->handle == ~0) | ||
173 | return -EINVAL; | ||
174 | |||
175 | /* compatibility with userspace that assumes 506e for all chipsets */ | ||
176 | if (init->class == 0x506e) { | ||
177 | init->class = nouveau_software_class(dev); | ||
178 | if (init->class == 0x906e) | ||
179 | return 0; | ||
180 | } else | ||
181 | if (init->class == 0x906e) { | ||
182 | NV_ERROR(dev, "906e not supported yet\n"); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | chan = nouveau_channel_get(file_priv, init->channel); | ||
187 | if (IS_ERR(chan)) | ||
188 | return PTR_ERR(chan); | ||
189 | |||
190 | if (nouveau_ramht_find(chan, init->handle)) { | ||
191 | ret = -EEXIST; | ||
192 | goto out; | ||
193 | } | ||
194 | |||
195 | ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class); | ||
196 | if (ret) { | ||
197 | NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", | ||
198 | ret, init->channel, init->handle); | ||
199 | } | ||
200 | |||
201 | out: | ||
202 | nouveau_channel_put(&chan); | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | int | ||
207 | nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) | ||
208 | { | ||
209 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
210 | struct drm_nouveau_notifierobj_alloc *na = data; | ||
211 | struct nouveau_channel *chan; | ||
212 | int ret; | ||
213 | |||
214 | /* completely unnecessary for these chipsets... */ | ||
215 | if (unlikely(dev_priv->card_type >= NV_C0)) | ||
216 | return -EINVAL; | ||
217 | |||
218 | chan = nouveau_channel_get(file_priv, na->channel); | ||
219 | if (IS_ERR(chan)) | ||
220 | return PTR_ERR(chan); | ||
221 | |||
222 | ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, | ||
223 | &na->offset); | ||
224 | nouveau_channel_put(&chan); | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | int | ||
229 | nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) | ||
230 | { | ||
231 | struct drm_nouveau_gpuobj_free *objfree = data; | ||
232 | struct nouveau_channel *chan; | ||
233 | int ret; | ||
234 | |||
235 | chan = nouveau_channel_get(file_priv, objfree->channel); | ||
236 | if (IS_ERR(chan)) | ||
237 | return PTR_ERR(chan); | ||
238 | |||
239 | /* Synchronize with the user channel */ | ||
240 | nouveau_channel_idle(chan); | ||
241 | |||
242 | ret = nouveau_ramht_remove(chan, objfree->handle); | ||
243 | nouveau_channel_put(&chan); | ||
244 | return ret; | ||
245 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h new file mode 100644 index 000000000000..e6328b008a8c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h | |||
@@ -0,0 +1,83 @@ | |||
1 | #ifndef __NOUVEAU_ABI16_H__ | ||
2 | #define __NOUVEAU_ABI16_H__ | ||
3 | |||
4 | #define ABI16_IOCTL_ARGS \ | ||
5 | struct drm_device *dev, void *data, struct drm_file *file_priv | ||
6 | int nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS); | ||
7 | int nouveau_abi16_ioctl_setparam(ABI16_IOCTL_ARGS); | ||
8 | int nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS); | ||
9 | int nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS); | ||
10 | int nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS); | ||
11 | int nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS); | ||
12 | int nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS); | ||
13 | |||
14 | struct drm_nouveau_channel_alloc { | ||
15 | uint32_t fb_ctxdma_handle; | ||
16 | uint32_t tt_ctxdma_handle; | ||
17 | |||
18 | int channel; | ||
19 | uint32_t pushbuf_domains; | ||
20 | |||
21 | /* Notifier memory */ | ||
22 | uint32_t notifier_handle; | ||
23 | |||
24 | /* DRM-enforced subchannel assignments */ | ||
25 | struct { | ||
26 | uint32_t handle; | ||
27 | uint32_t grclass; | ||
28 | } subchan[8]; | ||
29 | uint32_t nr_subchan; | ||
30 | }; | ||
31 | |||
32 | struct drm_nouveau_channel_free { | ||
33 | int channel; | ||
34 | }; | ||
35 | |||
36 | struct drm_nouveau_grobj_alloc { | ||
37 | int channel; | ||
38 | uint32_t handle; | ||
39 | int class; | ||
40 | }; | ||
41 | |||
42 | struct drm_nouveau_notifierobj_alloc { | ||
43 | uint32_t channel; | ||
44 | uint32_t handle; | ||
45 | uint32_t size; | ||
46 | uint32_t offset; | ||
47 | }; | ||
48 | |||
49 | struct drm_nouveau_gpuobj_free { | ||
50 | int channel; | ||
51 | uint32_t handle; | ||
52 | }; | ||
53 | |||
54 | #define NOUVEAU_GETPARAM_PCI_VENDOR 3 | ||
55 | #define NOUVEAU_GETPARAM_PCI_DEVICE 4 | ||
56 | #define NOUVEAU_GETPARAM_BUS_TYPE 5 | ||
57 | #define NOUVEAU_GETPARAM_FB_SIZE 8 | ||
58 | #define NOUVEAU_GETPARAM_AGP_SIZE 9 | ||
59 | #define NOUVEAU_GETPARAM_CHIPSET_ID 11 | ||
60 | #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 | ||
61 | #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 | ||
62 | #define NOUVEAU_GETPARAM_PTIMER_TIME 14 | ||
63 | #define NOUVEAU_GETPARAM_HAS_BO_USAGE 15 | ||
64 | #define NOUVEAU_GETPARAM_HAS_PAGEFLIP 16 | ||
65 | struct drm_nouveau_getparam { | ||
66 | uint64_t param; | ||
67 | uint64_t value; | ||
68 | }; | ||
69 | |||
70 | struct drm_nouveau_setparam { | ||
71 | uint64_t param; | ||
72 | uint64_t value; | ||
73 | }; | ||
74 | |||
75 | #define DRM_IOCTL_NOUVEAU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GETPARAM, struct drm_nouveau_getparam) | ||
76 | #define DRM_IOCTL_NOUVEAU_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SETPARAM, struct drm_nouveau_setparam) | ||
77 | #define DRM_IOCTL_NOUVEAU_CHANNEL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_ALLOC, struct drm_nouveau_channel_alloc) | ||
78 | #define DRM_IOCTL_NOUVEAU_CHANNEL_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_FREE, struct drm_nouveau_channel_free) | ||
79 | #define DRM_IOCTL_NOUVEAU_GROBJ_ALLOC DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GROBJ_ALLOC, struct drm_nouveau_grobj_alloc) | ||
80 | #define DRM_IOCTL_NOUVEAU_NOTIFIEROBJ_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, struct drm_nouveau_notifierobj_alloc) | ||
81 | #define DRM_IOCTL_NOUVEAU_GPUOBJ_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GPUOBJ_FREE, struct drm_nouveau_gpuobj_free) | ||
82 | |||
83 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 2f11e16a81a9..a0a3fe3c016b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -6091,6 +6091,18 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | |||
6091 | } | 6091 | } |
6092 | } | 6092 | } |
6093 | 6093 | ||
6094 | /* fdo#50830: connector indices for VGA and DVI-I are backwards */ | ||
6095 | if (nv_match_device(dev, 0x0421, 0x3842, 0xc793)) { | ||
6096 | if (idx == 0 && *conn == 0x02000300) | ||
6097 | *conn = 0x02011300; | ||
6098 | else | ||
6099 | if (idx == 1 && *conn == 0x04011310) | ||
6100 | *conn = 0x04000310; | ||
6101 | else | ||
6102 | if (idx == 2 && *conn == 0x02011312) | ||
6103 | *conn = 0x02000312; | ||
6104 | } | ||
6105 | |||
6094 | return true; | 6106 | return true; |
6095 | } | 6107 | } |
6096 | 6108 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 629d8a2df5bd..debd90225a88 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -395,98 +395,3 @@ nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) | |||
395 | nouveau_channel_put(&chan); | 395 | nouveau_channel_put(&chan); |
396 | } | 396 | } |
397 | } | 397 | } |
398 | |||
399 | |||
400 | /*********************************** | ||
401 | * ioctls wrapping the functions | ||
402 | ***********************************/ | ||
403 | |||
404 | static int | ||
405 | nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, | ||
406 | struct drm_file *file_priv) | ||
407 | { | ||
408 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
409 | struct drm_nouveau_channel_alloc *init = data; | ||
410 | struct nouveau_channel *chan; | ||
411 | int ret; | ||
412 | |||
413 | if (!dev_priv->eng[NVOBJ_ENGINE_GR]) | ||
414 | return -ENODEV; | ||
415 | |||
416 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) | ||
417 | return -EINVAL; | ||
418 | |||
419 | ret = nouveau_channel_alloc(dev, &chan, file_priv, | ||
420 | init->fb_ctxdma_handle, | ||
421 | init->tt_ctxdma_handle); | ||
422 | if (ret) | ||
423 | return ret; | ||
424 | init->channel = chan->id; | ||
425 | |||
426 | if (nouveau_vram_pushbuf == 0) { | ||
427 | if (chan->dma.ib_max) | ||
428 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | | ||
429 | NOUVEAU_GEM_DOMAIN_GART; | ||
430 | else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM) | ||
431 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; | ||
432 | else | ||
433 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; | ||
434 | } else { | ||
435 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; | ||
436 | } | ||
437 | |||
438 | if (dev_priv->card_type < NV_C0) { | ||
439 | init->subchan[0].handle = 0x00000000; | ||
440 | init->subchan[0].grclass = 0x0000; | ||
441 | init->subchan[1].handle = NvSw; | ||
442 | init->subchan[1].grclass = NV_SW; | ||
443 | init->nr_subchan = 2; | ||
444 | } | ||
445 | |||
446 | /* Named memory object area */ | ||
447 | ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, | ||
448 | &init->notifier_handle); | ||
449 | |||
450 | if (ret == 0) | ||
451 | atomic_inc(&chan->users); /* userspace reference */ | ||
452 | nouveau_channel_put(&chan); | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static int | ||
457 | nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | ||
458 | struct drm_file *file_priv) | ||
459 | { | ||
460 | struct drm_nouveau_channel_free *req = data; | ||
461 | struct nouveau_channel *chan; | ||
462 | |||
463 | chan = nouveau_channel_get(file_priv, req->channel); | ||
464 | if (IS_ERR(chan)) | ||
465 | return PTR_ERR(chan); | ||
466 | |||
467 | list_del(&chan->list); | ||
468 | atomic_dec(&chan->users); | ||
469 | nouveau_channel_put(&chan); | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | /*********************************** | ||
474 | * finally, the ioctl table | ||
475 | ***********************************/ | ||
476 | |||
477 | struct drm_ioctl_desc nouveau_ioctls[] = { | ||
478 | DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH), | ||
479 | DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
480 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_UNLOCKED|DRM_AUTH), | ||
481 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_UNLOCKED|DRM_AUTH), | ||
482 | DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH), | ||
483 | DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_UNLOCKED|DRM_AUTH), | ||
484 | DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH), | ||
485 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH), | ||
486 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH), | ||
487 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH), | ||
488 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH), | ||
489 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH), | ||
490 | }; | ||
491 | |||
492 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index cad254c8e387..9a36f5f39b06 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "drm.h" | 29 | #include "drm.h" |
30 | #include "drm_crtc_helper.h" | 30 | #include "drm_crtc_helper.h" |
31 | #include "nouveau_drv.h" | 31 | #include "nouveau_drv.h" |
32 | #include "nouveau_abi16.h" | ||
32 | #include "nouveau_hw.h" | 33 | #include "nouveau_hw.h" |
33 | #include "nouveau_fb.h" | 34 | #include "nouveau_fb.h" |
34 | #include "nouveau_fbcon.h" | 35 | #include "nouveau_fbcon.h" |
@@ -384,6 +385,21 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
384 | return 0; | 385 | return 0; |
385 | } | 386 | } |
386 | 387 | ||
388 | static struct drm_ioctl_desc nouveau_ioctls[] = { | ||
389 | DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_abi16_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH), | ||
390 | DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_abi16_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
391 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_abi16_ioctl_channel_alloc, DRM_UNLOCKED|DRM_AUTH), | ||
392 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_abi16_ioctl_channel_free, DRM_UNLOCKED|DRM_AUTH), | ||
393 | DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_abi16_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH), | ||
394 | DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_UNLOCKED|DRM_AUTH), | ||
395 | DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH), | ||
396 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH), | ||
397 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH), | ||
398 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH), | ||
399 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH), | ||
400 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH), | ||
401 | }; | ||
402 | |||
387 | static const struct file_operations nouveau_driver_fops = { | 403 | static const struct file_operations nouveau_driver_fops = { |
388 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
389 | .open = drm_open, | 405 | .open = drm_open, |
@@ -422,7 +438,6 @@ static struct drm_driver driver = { | |||
422 | .get_vblank_counter = drm_vblank_count, | 438 | .get_vblank_counter = drm_vblank_count, |
423 | .enable_vblank = nouveau_vblank_enable, | 439 | .enable_vblank = nouveau_vblank_enable, |
424 | .disable_vblank = nouveau_vblank_disable, | 440 | .disable_vblank = nouveau_vblank_disable, |
425 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
426 | .ioctls = nouveau_ioctls, | 441 | .ioctls = nouveau_ioctls, |
427 | .fops = &nouveau_driver_fops, | 442 | .fops = &nouveau_driver_fops, |
428 | 443 | ||
@@ -463,7 +478,7 @@ static struct pci_driver nouveau_pci_driver = { | |||
463 | 478 | ||
464 | static int __init nouveau_init(void) | 479 | static int __init nouveau_init(void) |
465 | { | 480 | { |
466 | driver.num_ioctls = nouveau_max_ioctl; | 481 | driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls); |
467 | 482 | ||
468 | if (nouveau_modeset == -1) { | 483 | if (nouveau_modeset == -1) { |
469 | #ifdef CONFIG_VGA_CONSOLE | 484 | #ifdef CONFIG_VGA_CONSOLE |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 8613cb23808c..4f2cc95ce264 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -689,8 +689,6 @@ struct drm_nouveau_private { | |||
689 | void (*irq_handler[32])(struct drm_device *); | 689 | void (*irq_handler[32])(struct drm_device *); |
690 | bool msi_enabled; | 690 | bool msi_enabled; |
691 | 691 | ||
692 | struct list_head vbl_waiting; | ||
693 | |||
694 | struct { | 692 | struct { |
695 | struct drm_global_reference mem_global_ref; | 693 | struct drm_global_reference mem_global_ref; |
696 | struct ttm_bo_global_ref bo_global_ref; | 694 | struct ttm_bo_global_ref bo_global_ref; |
@@ -872,10 +870,6 @@ extern int nouveau_load(struct drm_device *, unsigned long flags); | |||
872 | extern int nouveau_firstopen(struct drm_device *); | 870 | extern int nouveau_firstopen(struct drm_device *); |
873 | extern void nouveau_lastclose(struct drm_device *); | 871 | extern void nouveau_lastclose(struct drm_device *); |
874 | extern int nouveau_unload(struct drm_device *); | 872 | extern int nouveau_unload(struct drm_device *); |
875 | extern int nouveau_ioctl_getparam(struct drm_device *, void *data, | ||
876 | struct drm_file *); | ||
877 | extern int nouveau_ioctl_setparam(struct drm_device *, void *data, | ||
878 | struct drm_file *); | ||
879 | extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, | 873 | extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, |
880 | uint32_t reg, uint32_t mask, uint32_t val); | 874 | uint32_t reg, uint32_t mask, uint32_t val); |
881 | extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, | 875 | extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, |
@@ -914,15 +908,8 @@ extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); | |||
914 | extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, | 908 | extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, |
915 | int cout, uint32_t start, uint32_t end, | 909 | int cout, uint32_t start, uint32_t end, |
916 | uint32_t *offset); | 910 | uint32_t *offset); |
917 | extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *); | ||
918 | extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, | ||
919 | struct drm_file *); | ||
920 | extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, | ||
921 | struct drm_file *); | ||
922 | 911 | ||
923 | /* nouveau_channel.c */ | 912 | /* nouveau_channel.c */ |
924 | extern struct drm_ioctl_desc nouveau_ioctls[]; | ||
925 | extern int nouveau_max_ioctl; | ||
926 | extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *); | 913 | extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *); |
927 | extern int nouveau_channel_alloc(struct drm_device *dev, | 914 | extern int nouveau_channel_alloc(struct drm_device *dev, |
928 | struct nouveau_channel **chan, | 915 | struct nouveau_channel **chan, |
@@ -938,7 +925,7 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan, | |||
938 | struct nouveau_channel **pchan); | 925 | struct nouveau_channel **pchan); |
939 | extern int nouveau_channel_idle(struct nouveau_channel *chan); | 926 | extern int nouveau_channel_idle(struct nouveau_channel *chan); |
940 | 927 | ||
941 | /* nouveau_object.c */ | 928 | /* nouveau_gpuobj.c */ |
942 | #define NVOBJ_ENGINE_ADD(d, e, p) do { \ | 929 | #define NVOBJ_ENGINE_ADD(d, e, p) do { \ |
943 | struct drm_nouveau_private *dev_priv = (d)->dev_private; \ | 930 | struct drm_nouveau_private *dev_priv = (d)->dev_private; \ |
944 | dev_priv->eng[NVOBJ_ENGINE_##e] = (p); \ | 931 | dev_priv->eng[NVOBJ_ENGINE_##e] = (p); \ |
@@ -993,10 +980,6 @@ extern int nv50_gpuobj_dma_new(struct nouveau_channel *, int class, u64 base, | |||
993 | extern void nv50_gpuobj_dma_init(struct nouveau_gpuobj *, u32 offset, | 980 | extern void nv50_gpuobj_dma_init(struct nouveau_gpuobj *, u32 offset, |
994 | int class, u64 base, u64 size, int target, | 981 | int class, u64 base, u64 size, int target, |
995 | int access, u32 type, u32 comp); | 982 | int access, u32 type, u32 comp); |
996 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, | ||
997 | struct drm_file *); | ||
998 | extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, | ||
999 | struct drm_file *); | ||
1000 | 983 | ||
1001 | /* nouveau_irq.c */ | 984 | /* nouveau_irq.c */ |
1002 | extern int nouveau_irq_init(struct drm_device *); | 985 | extern int nouveau_irq_init(struct drm_device *); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 30f542316944..af7cfb825716 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -207,8 +207,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
207 | struct nouveau_bo *nvbo = NULL; | 207 | struct nouveau_bo *nvbo = NULL; |
208 | int ret = 0; | 208 | int ret = 0; |
209 | 209 | ||
210 | if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) | 210 | dev_priv->ttm.bdev.dev_mapping = dev->dev_mapping; |
211 | dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; | ||
212 | 211 | ||
213 | if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) { | 212 | if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) { |
214 | NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags); | 213 | NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags); |
@@ -342,6 +341,7 @@ retry: | |||
342 | if (nvbo->reserved_by && nvbo->reserved_by == file_priv) { | 341 | if (nvbo->reserved_by && nvbo->reserved_by == file_priv) { |
343 | NV_ERROR(dev, "multiple instances of buffer %d on " | 342 | NV_ERROR(dev, "multiple instances of buffer %d on " |
344 | "validation list\n", b->handle); | 343 | "validation list\n", b->handle); |
344 | drm_gem_object_unreference_unlocked(gem); | ||
345 | validate_fini(op, NULL); | 345 | validate_fini(op, NULL); |
346 | return -EINVAL; | 346 | return -EINVAL; |
347 | } | 347 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c index b190cc01c820..bd79fedb7054 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c | |||
@@ -758,66 +758,6 @@ nouveau_gpuobj_resume(struct drm_device *dev) | |||
758 | dev_priv->engine.instmem.flush(dev); | 758 | dev_priv->engine.instmem.flush(dev); |
759 | } | 759 | } |
760 | 760 | ||
761 | int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, | ||
762 | struct drm_file *file_priv) | ||
763 | { | ||
764 | struct drm_nouveau_grobj_alloc *init = data; | ||
765 | struct nouveau_channel *chan; | ||
766 | int ret; | ||
767 | |||
768 | if (init->handle == ~0) | ||
769 | return -EINVAL; | ||
770 | |||
771 | /* compatibility with userspace that assumes 506e for all chipsets */ | ||
772 | if (init->class == 0x506e) { | ||
773 | init->class = nouveau_software_class(dev); | ||
774 | if (init->class == 0x906e) | ||
775 | return 0; | ||
776 | } else | ||
777 | if (init->class == 0x906e) { | ||
778 | NV_ERROR(dev, "906e not supported yet\n"); | ||
779 | return -EINVAL; | ||
780 | } | ||
781 | |||
782 | chan = nouveau_channel_get(file_priv, init->channel); | ||
783 | if (IS_ERR(chan)) | ||
784 | return PTR_ERR(chan); | ||
785 | |||
786 | if (nouveau_ramht_find(chan, init->handle)) { | ||
787 | ret = -EEXIST; | ||
788 | goto out; | ||
789 | } | ||
790 | |||
791 | ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class); | ||
792 | if (ret) { | ||
793 | NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", | ||
794 | ret, init->channel, init->handle); | ||
795 | } | ||
796 | |||
797 | out: | ||
798 | nouveau_channel_put(&chan); | ||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, | ||
803 | struct drm_file *file_priv) | ||
804 | { | ||
805 | struct drm_nouveau_gpuobj_free *objfree = data; | ||
806 | struct nouveau_channel *chan; | ||
807 | int ret; | ||
808 | |||
809 | chan = nouveau_channel_get(file_priv, objfree->channel); | ||
810 | if (IS_ERR(chan)) | ||
811 | return PTR_ERR(chan); | ||
812 | |||
813 | /* Synchronize with the user channel */ | ||
814 | nouveau_channel_idle(chan); | ||
815 | |||
816 | ret = nouveau_ramht_remove(chan, objfree->handle); | ||
817 | nouveau_channel_put(&chan); | ||
818 | return ret; | ||
819 | } | ||
820 | |||
821 | u32 | 761 | u32 |
822 | nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) | 762 | nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) |
823 | { | 763 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 868c7fd74854..b2c2937531a8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -41,12 +41,8 @@ | |||
41 | void | 41 | void |
42 | nouveau_irq_preinstall(struct drm_device *dev) | 42 | nouveau_irq_preinstall(struct drm_device *dev) |
43 | { | 43 | { |
44 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
45 | |||
46 | /* Master disable */ | 44 | /* Master disable */ |
47 | nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); | 45 | nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); |
48 | |||
49 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); | ||
50 | } | 46 | } |
51 | 47 | ||
52 | int | 48 | int |
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 2ef883c4bbc1..69c93b864519 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -161,44 +161,3 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
161 | *b_offset = mem->start; | 161 | *b_offset = mem->start; |
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | |||
165 | int | ||
166 | nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) | ||
167 | { | ||
168 | if (!nobj || nobj->dtor != nouveau_notifier_gpuobj_dtor) | ||
169 | return -EINVAL; | ||
170 | |||
171 | if (poffset) { | ||
172 | struct drm_mm_node *mem = nobj->priv; | ||
173 | |||
174 | if (*poffset >= mem->size) | ||
175 | return false; | ||
176 | |||
177 | *poffset += mem->start; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | int | ||
184 | nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, | ||
185 | struct drm_file *file_priv) | ||
186 | { | ||
187 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
188 | struct drm_nouveau_notifierobj_alloc *na = data; | ||
189 | struct nouveau_channel *chan; | ||
190 | int ret; | ||
191 | |||
192 | /* completely unnecessary for these chipsets... */ | ||
193 | if (unlikely(dev_priv->card_type >= NV_C0)) | ||
194 | return -EINVAL; | ||
195 | |||
196 | chan = nouveau_channel_get(file_priv, na->channel); | ||
197 | if (IS_ERR(chan)) | ||
198 | return PTR_ERR(chan); | ||
199 | |||
200 | ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, | ||
201 | &na->offset); | ||
202 | nouveau_channel_put(&chan); | ||
203 | return ret; | ||
204 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_software.h b/drivers/gpu/drm/nouveau/nouveau_software.h index e60bc6ce9003..709e5ac680ec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_software.h +++ b/drivers/gpu/drm/nouveau/nouveau_software.h | |||
@@ -4,13 +4,15 @@ | |||
4 | struct nouveau_software_priv { | 4 | struct nouveau_software_priv { |
5 | struct nouveau_exec_engine base; | 5 | struct nouveau_exec_engine base; |
6 | struct list_head vblank; | 6 | struct list_head vblank; |
7 | spinlock_t peephole_lock; | ||
7 | }; | 8 | }; |
8 | 9 | ||
9 | struct nouveau_software_chan { | 10 | struct nouveau_software_chan { |
10 | struct list_head flip; | 11 | struct list_head flip; |
11 | struct { | 12 | struct { |
12 | struct list_head list; | 13 | struct list_head list; |
13 | struct nouveau_bo *bo; | 14 | u32 channel; |
15 | u32 ctxdma; | ||
14 | u32 offset; | 16 | u32 offset; |
15 | u32 value; | 17 | u32 value; |
16 | u32 head; | 18 | u32 head; |
@@ -18,32 +20,17 @@ struct nouveau_software_chan { | |||
18 | }; | 20 | }; |
19 | 21 | ||
20 | static inline void | 22 | static inline void |
21 | nouveau_software_vblank(struct drm_device *dev, int crtc) | ||
22 | { | ||
23 | struct nouveau_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW); | ||
24 | struct nouveau_software_chan *pch, *tmp; | ||
25 | |||
26 | list_for_each_entry_safe(pch, tmp, &psw->vblank, vblank.list) { | ||
27 | if (pch->vblank.head != crtc) | ||
28 | continue; | ||
29 | |||
30 | nouveau_bo_wr32(pch->vblank.bo, pch->vblank.offset, | ||
31 | pch->vblank.value); | ||
32 | list_del(&pch->vblank.list); | ||
33 | drm_vblank_put(dev, crtc); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | static inline void | ||
38 | nouveau_software_context_new(struct nouveau_software_chan *pch) | 23 | nouveau_software_context_new(struct nouveau_software_chan *pch) |
39 | { | 24 | { |
40 | INIT_LIST_HEAD(&pch->flip); | 25 | INIT_LIST_HEAD(&pch->flip); |
26 | INIT_LIST_HEAD(&pch->vblank.list); | ||
41 | } | 27 | } |
42 | 28 | ||
43 | static inline void | 29 | static inline void |
44 | nouveau_software_create(struct nouveau_software_priv *psw) | 30 | nouveau_software_create(struct nouveau_software_priv *psw) |
45 | { | 31 | { |
46 | INIT_LIST_HEAD(&psw->vblank); | 32 | INIT_LIST_HEAD(&psw->vblank); |
33 | spin_lock_init(&psw->peephole_lock); | ||
47 | } | 34 | } |
48 | 35 | ||
49 | static inline u16 | 36 | static inline u16 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 19706f0532ea..1cdfd6e757ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -1234,80 +1234,6 @@ int nouveau_unload(struct drm_device *dev) | |||
1234 | return 0; | 1234 | return 0; |
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | ||
1238 | struct drm_file *file_priv) | ||
1239 | { | ||
1240 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1241 | struct drm_nouveau_getparam *getparam = data; | ||
1242 | |||
1243 | switch (getparam->param) { | ||
1244 | case NOUVEAU_GETPARAM_CHIPSET_ID: | ||
1245 | getparam->value = dev_priv->chipset; | ||
1246 | break; | ||
1247 | case NOUVEAU_GETPARAM_PCI_VENDOR: | ||
1248 | getparam->value = dev->pci_vendor; | ||
1249 | break; | ||
1250 | case NOUVEAU_GETPARAM_PCI_DEVICE: | ||
1251 | getparam->value = dev->pci_device; | ||
1252 | break; | ||
1253 | case NOUVEAU_GETPARAM_BUS_TYPE: | ||
1254 | if (drm_pci_device_is_agp(dev)) | ||
1255 | getparam->value = NV_AGP; | ||
1256 | else if (pci_is_pcie(dev->pdev)) | ||
1257 | getparam->value = NV_PCIE; | ||
1258 | else | ||
1259 | getparam->value = NV_PCI; | ||
1260 | break; | ||
1261 | case NOUVEAU_GETPARAM_FB_SIZE: | ||
1262 | getparam->value = dev_priv->fb_available_size; | ||
1263 | break; | ||
1264 | case NOUVEAU_GETPARAM_AGP_SIZE: | ||
1265 | getparam->value = dev_priv->gart_info.aper_size; | ||
1266 | break; | ||
1267 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: | ||
1268 | getparam->value = 0; /* deprecated */ | ||
1269 | break; | ||
1270 | case NOUVEAU_GETPARAM_PTIMER_TIME: | ||
1271 | getparam->value = dev_priv->engine.timer.read(dev); | ||
1272 | break; | ||
1273 | case NOUVEAU_GETPARAM_HAS_BO_USAGE: | ||
1274 | getparam->value = 1; | ||
1275 | break; | ||
1276 | case NOUVEAU_GETPARAM_HAS_PAGEFLIP: | ||
1277 | getparam->value = 1; | ||
1278 | break; | ||
1279 | case NOUVEAU_GETPARAM_GRAPH_UNITS: | ||
1280 | /* NV40 and NV50 versions are quite different, but register | ||
1281 | * address is the same. User is supposed to know the card | ||
1282 | * family anyway... */ | ||
1283 | if (dev_priv->chipset >= 0x40) { | ||
1284 | getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS); | ||
1285 | break; | ||
1286 | } | ||
1287 | /* FALLTHRU */ | ||
1288 | default: | ||
1289 | NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param); | ||
1290 | return -EINVAL; | ||
1291 | } | ||
1292 | |||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | int | ||
1297 | nouveau_ioctl_setparam(struct drm_device *dev, void *data, | ||
1298 | struct drm_file *file_priv) | ||
1299 | { | ||
1300 | struct drm_nouveau_setparam *setparam = data; | ||
1301 | |||
1302 | switch (setparam->param) { | ||
1303 | default: | ||
1304 | NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param); | ||
1305 | return -EINVAL; | ||
1306 | } | ||
1307 | |||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | /* Wait until (value(reg) & mask) == val, up until timeout has hit */ | 1237 | /* Wait until (value(reg) & mask) == val, up until timeout has hit */ |
1312 | bool | 1238 | bool |
1313 | nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, | 1239 | nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, |
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 4c31c63e5528..43accc11102f 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
@@ -215,7 +215,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
215 | } | 215 | } |
216 | 216 | ||
217 | static bool | 217 | static bool |
218 | nv_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, | 218 | nv_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, |
219 | struct drm_display_mode *adjusted_mode) | 219 | struct drm_display_mode *adjusted_mode) |
220 | { | 220 | { |
221 | return true; | 221 | return true; |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 8300266ffaea..38f19479417c 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -332,7 +332,7 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
332 | } | 332 | } |
333 | 333 | ||
334 | static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, | 334 | static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, |
335 | struct drm_display_mode *mode, | 335 | const struct drm_display_mode *mode, |
336 | struct drm_display_mode *adjusted_mode) | 336 | struct drm_display_mode *adjusted_mode) |
337 | { | 337 | { |
338 | if (nv04_dac_in_use(encoder)) | 338 | if (nv04_dac_in_use(encoder)) |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 2258746016f8..c2675623b7cd 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -179,7 +179,7 @@ static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder) | |||
179 | } | 179 | } |
180 | 180 | ||
181 | static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, | 181 | static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, |
182 | struct drm_display_mode *mode, | 182 | const struct drm_display_mode *mode, |
183 | struct drm_display_mode *adjusted_mode) | 183 | struct drm_display_mode *adjusted_mode) |
184 | { | 184 | { |
185 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 185 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 696d7e7dc2a0..67be5db021f5 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -338,7 +338,7 @@ static int nv17_tv_mode_valid(struct drm_encoder *encoder, | |||
338 | } | 338 | } |
339 | 339 | ||
340 | static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, | 340 | static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, |
341 | struct drm_display_mode *mode, | 341 | const struct drm_display_mode *mode, |
342 | struct drm_display_mode *adjusted_mode) | 342 | struct drm_display_mode *adjusted_mode) |
343 | { | 343 | { |
344 | struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); | 344 | struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 97a477b3d52d..22cebd5dd694 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -527,7 +527,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) | |||
527 | } | 527 | } |
528 | 528 | ||
529 | static bool | 529 | static bool |
530 | nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, | 530 | nv50_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, |
531 | struct drm_display_mode *adjusted_mode) | 531 | struct drm_display_mode *adjusted_mode) |
532 | { | 532 | { |
533 | return true; | 533 | return true; |
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index eb216a446b89..2c36a6b92c53 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c | |||
@@ -175,7 +175,8 @@ nv50_dac_restore(struct drm_encoder *encoder) | |||
175 | } | 175 | } |
176 | 176 | ||
177 | static bool | 177 | static bool |
178 | nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 178 | nv50_dac_mode_fixup(struct drm_encoder *encoder, |
179 | const struct drm_display_mode *mode, | ||
179 | struct drm_display_mode *adjusted_mode) | 180 | struct drm_display_mode *adjusted_mode) |
180 | { | 181 | { |
181 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 182 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 5c41612723b4..b244d9968c5d 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -646,7 +646,30 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, | |||
646 | static void | 646 | static void |
647 | nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) | 647 | nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) |
648 | { | 648 | { |
649 | nouveau_software_vblank(dev, crtc); | 649 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
650 | struct nouveau_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW); | ||
651 | struct nouveau_software_chan *pch, *tmp; | ||
652 | |||
653 | list_for_each_entry_safe(pch, tmp, &psw->vblank, vblank.list) { | ||
654 | if (pch->vblank.head != crtc) | ||
655 | continue; | ||
656 | |||
657 | spin_lock(&psw->peephole_lock); | ||
658 | nv_wr32(dev, 0x001704, pch->vblank.channel); | ||
659 | nv_wr32(dev, 0x001710, 0x80000000 | pch->vblank.ctxdma); | ||
660 | if (dev_priv->chipset == 0x50) { | ||
661 | nv_wr32(dev, 0x001570, pch->vblank.offset); | ||
662 | nv_wr32(dev, 0x001574, pch->vblank.value); | ||
663 | } else { | ||
664 | nv_wr32(dev, 0x060010, pch->vblank.offset); | ||
665 | nv_wr32(dev, 0x060014, pch->vblank.value); | ||
666 | } | ||
667 | spin_unlock(&psw->peephole_lock); | ||
668 | |||
669 | list_del(&pch->vblank.list); | ||
670 | drm_vblank_put(dev, crtc); | ||
671 | } | ||
672 | |||
650 | drm_handle_vblank(dev, crtc); | 673 | drm_handle_vblank(dev, crtc); |
651 | } | 674 | } |
652 | 675 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index d9cc2f2638d6..437608d1dfe7 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -299,7 +299,7 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = { | |||
299 | 299 | ||
300 | /* There must be a *lot* of these. Will take some time to gather them up. */ | 300 | /* There must be a *lot* of these. Will take some time to gather them up. */ |
301 | struct nouveau_enum nv50_data_error_names[] = { | 301 | struct nouveau_enum nv50_data_error_names[] = { |
302 | { 0x00000003, "INVALID_QUERY_OR_TEXTURE", NULL }, | 302 | { 0x00000003, "INVALID_OPERATION", NULL }, |
303 | { 0x00000004, "INVALID_VALUE", NULL }, | 303 | { 0x00000004, "INVALID_VALUE", NULL }, |
304 | { 0x00000005, "INVALID_ENUM", NULL }, | 304 | { 0x00000005, "INVALID_ENUM", NULL }, |
305 | { 0x00000008, "INVALID_OBJECT", NULL }, | 305 | { 0x00000008, "INVALID_OBJECT", NULL }, |
diff --git a/drivers/gpu/drm/nouveau/nv50_software.c b/drivers/gpu/drm/nouveau/nv50_software.c index 114d2517d4a8..df554d9dacb8 100644 --- a/drivers/gpu/drm/nouveau/nv50_software.c +++ b/drivers/gpu/drm/nouveau/nv50_software.c | |||
@@ -36,9 +36,6 @@ struct nv50_software_priv { | |||
36 | 36 | ||
37 | struct nv50_software_chan { | 37 | struct nv50_software_chan { |
38 | struct nouveau_software_chan base; | 38 | struct nouveau_software_chan base; |
39 | struct { | ||
40 | struct nouveau_gpuobj *object; | ||
41 | } vblank; | ||
42 | }; | 39 | }; |
43 | 40 | ||
44 | static int | 41 | static int |
@@ -51,11 +48,7 @@ mthd_dma_vblsem(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) | |||
51 | if (!gpuobj) | 48 | if (!gpuobj) |
52 | return -ENOENT; | 49 | return -ENOENT; |
53 | 50 | ||
54 | if (nouveau_notifier_offset(gpuobj, NULL)) | 51 | pch->base.vblank.ctxdma = gpuobj->cinst >> 4; |
55 | return -EINVAL; | ||
56 | |||
57 | pch->vblank.object = gpuobj; | ||
58 | pch->base.vblank.offset = ~0; | ||
59 | return 0; | 52 | return 0; |
60 | } | 53 | } |
61 | 54 | ||
@@ -63,11 +56,7 @@ static int | |||
63 | mthd_vblsem_offset(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) | 56 | mthd_vblsem_offset(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) |
64 | { | 57 | { |
65 | struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; | 58 | struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; |
66 | 59 | pch->base.vblank.offset = data; | |
67 | if (nouveau_notifier_offset(pch->vblank.object, &data)) | ||
68 | return -ERANGE; | ||
69 | |||
70 | pch->base.vblank.offset = data >> 2; | ||
71 | return 0; | 60 | return 0; |
72 | } | 61 | } |
73 | 62 | ||
@@ -86,7 +75,7 @@ mthd_vblsem_release(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) | |||
86 | struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; | 75 | struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; |
87 | struct drm_device *dev = chan->dev; | 76 | struct drm_device *dev = chan->dev; |
88 | 77 | ||
89 | if (!pch->vblank.object || pch->base.vblank.offset == ~0 || data > 1) | 78 | if (data > 1) |
90 | return -EINVAL; | 79 | return -EINVAL; |
91 | 80 | ||
92 | drm_vblank_get(dev, data); | 81 | drm_vblank_get(dev, data); |
@@ -116,7 +105,7 @@ nv50_software_context_new(struct nouveau_channel *chan, int engine) | |||
116 | return -ENOMEM; | 105 | return -ENOMEM; |
117 | 106 | ||
118 | nouveau_software_context_new(&pch->base); | 107 | nouveau_software_context_new(&pch->base); |
119 | pch->base.vblank.bo = chan->notifier_bo; | 108 | pch->base.vblank.channel = chan->ramin->vinst >> 12; |
120 | chan->engctx[engine] = pch; | 109 | chan->engctx[engine] = pch; |
121 | 110 | ||
122 | /* dma objects for display sync channel semaphore blocks */ | 111 | /* dma objects for display sync channel semaphore blocks */ |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index a9514eaa74c1..93240bde891b 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -327,7 +327,8 @@ nv50_sor_restore(struct drm_encoder *encoder) | |||
327 | } | 327 | } |
328 | 328 | ||
329 | static bool | 329 | static bool |
330 | nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 330 | nv50_sor_mode_fixup(struct drm_encoder *encoder, |
331 | const struct drm_display_mode *mode, | ||
331 | struct drm_display_mode *adjusted_mode) | 332 | struct drm_display_mode *adjusted_mode) |
332 | { | 333 | { |
333 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 334 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index edece9c616eb..bbfcc73b6708 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c | |||
@@ -117,18 +117,30 @@ nv84_crypt_tlb_flush(struct drm_device *dev, int engine) | |||
117 | nv50_vm_flush_engine(dev, 0x0a); | 117 | nv50_vm_flush_engine(dev, 0x0a); |
118 | } | 118 | } |
119 | 119 | ||
120 | static struct nouveau_bitfield nv84_crypt_intr[] = { | ||
121 | { 0x00000001, "INVALID_STATE" }, | ||
122 | { 0x00000002, "ILLEGAL_MTHD" }, | ||
123 | { 0x00000004, "ILLEGAL_CLASS" }, | ||
124 | { 0x00000080, "QUERY" }, | ||
125 | { 0x00000100, "FAULT" }, | ||
126 | {} | ||
127 | }; | ||
128 | |||
120 | static void | 129 | static void |
121 | nv84_crypt_isr(struct drm_device *dev) | 130 | nv84_crypt_isr(struct drm_device *dev) |
122 | { | 131 | { |
123 | u32 stat = nv_rd32(dev, 0x102130); | 132 | u32 stat = nv_rd32(dev, 0x102130); |
124 | u32 mthd = nv_rd32(dev, 0x102190); | 133 | u32 mthd = nv_rd32(dev, 0x102190); |
125 | u32 data = nv_rd32(dev, 0x102194); | 134 | u32 data = nv_rd32(dev, 0x102194); |
126 | u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff; | 135 | u64 inst = (u64)(nv_rd32(dev, 0x102188) & 0x7fffffff) << 12; |
127 | int show = nouveau_ratelimit(); | 136 | int show = nouveau_ratelimit(); |
137 | int chid = nv50_graph_isr_chid(dev, inst); | ||
128 | 138 | ||
129 | if (show) { | 139 | if (show) { |
130 | NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n", | 140 | NV_INFO(dev, "PCRYPT:"); |
131 | stat, mthd, data, inst); | 141 | nouveau_bitfield_print(nv84_crypt_intr, stat); |
142 | printk(KERN_CONT " ch %d (0x%010llx) mthd 0x%04x data 0x%08x\n", | ||
143 | chid, inst, mthd, data); | ||
132 | } | 144 | } |
133 | 145 | ||
134 | nv_wr32(dev, 0x102130, stat); | 146 | nv_wr32(dev, 0x102130, stat); |
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc b/drivers/gpu/drm/nouveau/nva3_copy.fuc index abc36626fef0..219850d53286 100644 --- a/drivers/gpu/drm/nouveau/nva3_copy.fuc +++ b/drivers/gpu/drm/nouveau/nva3_copy.fuc | |||
@@ -119,9 +119,9 @@ dispatch_dma: | |||
119 | // mthd 0x030c-0x0340, various stuff | 119 | // mthd 0x030c-0x0340, various stuff |
120 | .b16 0xc3 14 | 120 | .b16 0xc3 14 |
121 | .b32 #ctx_src_address_high ~0x000000ff | 121 | .b32 #ctx_src_address_high ~0x000000ff |
122 | .b32 #ctx_src_address_low ~0xfffffff0 | 122 | .b32 #ctx_src_address_low ~0xffffffff |
123 | .b32 #ctx_dst_address_high ~0x000000ff | 123 | .b32 #ctx_dst_address_high ~0x000000ff |
124 | .b32 #ctx_dst_address_low ~0xfffffff0 | 124 | .b32 #ctx_dst_address_low ~0xffffffff |
125 | .b32 #ctx_src_pitch ~0x0007ffff | 125 | .b32 #ctx_src_pitch ~0x0007ffff |
126 | .b32 #ctx_dst_pitch ~0x0007ffff | 126 | .b32 #ctx_dst_pitch ~0x0007ffff |
127 | .b32 #ctx_xcnt ~0x0000ffff | 127 | .b32 #ctx_xcnt ~0x0000ffff |
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h b/drivers/gpu/drm/nouveau/nva3_copy.fuc.h index 1f33fbdc00be..37d6de3c9d61 100644 --- a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h +++ b/drivers/gpu/drm/nouveau/nva3_copy.fuc.h | |||
@@ -1,37 +1,72 @@ | |||
1 | uint32_t nva3_pcopy_data[] = { | 1 | u32 nva3_pcopy_data[] = { |
2 | /* 0x0000: ctx_object */ | ||
2 | 0x00000000, | 3 | 0x00000000, |
4 | /* 0x0004: ctx_dma */ | ||
5 | /* 0x0004: ctx_dma_query */ | ||
3 | 0x00000000, | 6 | 0x00000000, |
7 | /* 0x0008: ctx_dma_src */ | ||
4 | 0x00000000, | 8 | 0x00000000, |
9 | /* 0x000c: ctx_dma_dst */ | ||
5 | 0x00000000, | 10 | 0x00000000, |
11 | /* 0x0010: ctx_query_address_high */ | ||
6 | 0x00000000, | 12 | 0x00000000, |
13 | /* 0x0014: ctx_query_address_low */ | ||
7 | 0x00000000, | 14 | 0x00000000, |
15 | /* 0x0018: ctx_query_counter */ | ||
8 | 0x00000000, | 16 | 0x00000000, |
17 | /* 0x001c: ctx_src_address_high */ | ||
9 | 0x00000000, | 18 | 0x00000000, |
19 | /* 0x0020: ctx_src_address_low */ | ||
10 | 0x00000000, | 20 | 0x00000000, |
21 | /* 0x0024: ctx_src_pitch */ | ||
11 | 0x00000000, | 22 | 0x00000000, |
23 | /* 0x0028: ctx_src_tile_mode */ | ||
12 | 0x00000000, | 24 | 0x00000000, |
25 | /* 0x002c: ctx_src_xsize */ | ||
13 | 0x00000000, | 26 | 0x00000000, |
27 | /* 0x0030: ctx_src_ysize */ | ||
14 | 0x00000000, | 28 | 0x00000000, |
29 | /* 0x0034: ctx_src_zsize */ | ||
15 | 0x00000000, | 30 | 0x00000000, |
31 | /* 0x0038: ctx_src_zoff */ | ||
16 | 0x00000000, | 32 | 0x00000000, |
33 | /* 0x003c: ctx_src_xoff */ | ||
17 | 0x00000000, | 34 | 0x00000000, |
35 | /* 0x0040: ctx_src_yoff */ | ||
18 | 0x00000000, | 36 | 0x00000000, |
37 | /* 0x0044: ctx_src_cpp */ | ||
19 | 0x00000000, | 38 | 0x00000000, |
39 | /* 0x0048: ctx_dst_address_high */ | ||
20 | 0x00000000, | 40 | 0x00000000, |
41 | /* 0x004c: ctx_dst_address_low */ | ||
21 | 0x00000000, | 42 | 0x00000000, |
43 | /* 0x0050: ctx_dst_pitch */ | ||
22 | 0x00000000, | 44 | 0x00000000, |
45 | /* 0x0054: ctx_dst_tile_mode */ | ||
23 | 0x00000000, | 46 | 0x00000000, |
47 | /* 0x0058: ctx_dst_xsize */ | ||
24 | 0x00000000, | 48 | 0x00000000, |
49 | /* 0x005c: ctx_dst_ysize */ | ||
25 | 0x00000000, | 50 | 0x00000000, |
51 | /* 0x0060: ctx_dst_zsize */ | ||
26 | 0x00000000, | 52 | 0x00000000, |
53 | /* 0x0064: ctx_dst_zoff */ | ||
27 | 0x00000000, | 54 | 0x00000000, |
55 | /* 0x0068: ctx_dst_xoff */ | ||
28 | 0x00000000, | 56 | 0x00000000, |
57 | /* 0x006c: ctx_dst_yoff */ | ||
29 | 0x00000000, | 58 | 0x00000000, |
59 | /* 0x0070: ctx_dst_cpp */ | ||
30 | 0x00000000, | 60 | 0x00000000, |
61 | /* 0x0074: ctx_format */ | ||
31 | 0x00000000, | 62 | 0x00000000, |
63 | /* 0x0078: ctx_swz_const0 */ | ||
32 | 0x00000000, | 64 | 0x00000000, |
65 | /* 0x007c: ctx_swz_const1 */ | ||
33 | 0x00000000, | 66 | 0x00000000, |
67 | /* 0x0080: ctx_xcnt */ | ||
34 | 0x00000000, | 68 | 0x00000000, |
69 | /* 0x0084: ctx_ycnt */ | ||
35 | 0x00000000, | 70 | 0x00000000, |
36 | 0x00000000, | 71 | 0x00000000, |
37 | 0x00000000, | 72 | 0x00000000, |
@@ -63,6 +98,7 @@ uint32_t nva3_pcopy_data[] = { | |||
63 | 0x00000000, | 98 | 0x00000000, |
64 | 0x00000000, | 99 | 0x00000000, |
65 | 0x00000000, | 100 | 0x00000000, |
101 | /* 0x0100: dispatch_table */ | ||
66 | 0x00010000, | 102 | 0x00010000, |
67 | 0x00000000, | 103 | 0x00000000, |
68 | 0x00000000, | 104 | 0x00000000, |
@@ -73,6 +109,7 @@ uint32_t nva3_pcopy_data[] = { | |||
73 | 0x00010162, | 109 | 0x00010162, |
74 | 0x00000000, | 110 | 0x00000000, |
75 | 0x00030060, | 111 | 0x00030060, |
112 | /* 0x0128: dispatch_dma */ | ||
76 | 0x00010170, | 113 | 0x00010170, |
77 | 0x00000000, | 114 | 0x00000000, |
78 | 0x00010170, | 115 | 0x00010170, |
@@ -118,11 +155,11 @@ uint32_t nva3_pcopy_data[] = { | |||
118 | 0x0000001c, | 155 | 0x0000001c, |
119 | 0xffffff00, | 156 | 0xffffff00, |
120 | 0x00000020, | 157 | 0x00000020, |
121 | 0x0000000f, | 158 | 0x00000000, |
122 | 0x00000048, | 159 | 0x00000048, |
123 | 0xffffff00, | 160 | 0xffffff00, |
124 | 0x0000004c, | 161 | 0x0000004c, |
125 | 0x0000000f, | 162 | 0x00000000, |
126 | 0x00000024, | 163 | 0x00000024, |
127 | 0xfff80000, | 164 | 0xfff80000, |
128 | 0x00000050, | 165 | 0x00000050, |
@@ -146,7 +183,8 @@ uint32_t nva3_pcopy_data[] = { | |||
146 | 0x00000800, | 183 | 0x00000800, |
147 | }; | 184 | }; |
148 | 185 | ||
149 | uint32_t nva3_pcopy_code[] = { | 186 | u32 nva3_pcopy_code[] = { |
187 | /* 0x0000: main */ | ||
150 | 0x04fe04bd, | 188 | 0x04fe04bd, |
151 | 0x3517f000, | 189 | 0x3517f000, |
152 | 0xf10010fe, | 190 | 0xf10010fe, |
@@ -158,23 +196,31 @@ uint32_t nva3_pcopy_code[] = { | |||
158 | 0x17f11031, | 196 | 0x17f11031, |
159 | 0x27f01200, | 197 | 0x27f01200, |
160 | 0x0012d003, | 198 | 0x0012d003, |
199 | /* 0x002f: spin */ | ||
161 | 0xf40031f4, | 200 | 0xf40031f4, |
162 | 0x0ef40028, | 201 | 0x0ef40028, |
202 | /* 0x0035: ih */ | ||
163 | 0x8001cffd, | 203 | 0x8001cffd, |
164 | 0xf40812c4, | 204 | 0xf40812c4, |
165 | 0x21f4060b, | 205 | 0x21f4060b, |
206 | /* 0x0041: ih_no_chsw */ | ||
166 | 0x0412c472, | 207 | 0x0412c472, |
167 | 0xf4060bf4, | 208 | 0xf4060bf4, |
209 | /* 0x004a: ih_no_cmd */ | ||
168 | 0x11c4c321, | 210 | 0x11c4c321, |
169 | 0x4001d00c, | 211 | 0x4001d00c, |
212 | /* 0x0052: swctx */ | ||
170 | 0x47f101f8, | 213 | 0x47f101f8, |
171 | 0x4bfe7700, | 214 | 0x4bfe7700, |
172 | 0x0007fe00, | 215 | 0x0007fe00, |
173 | 0xf00204b9, | 216 | 0xf00204b9, |
174 | 0x01f40643, | 217 | 0x01f40643, |
175 | 0x0604fa09, | 218 | 0x0604fa09, |
219 | /* 0x006b: swctx_load */ | ||
176 | 0xfa060ef4, | 220 | 0xfa060ef4, |
221 | /* 0x006e: swctx_done */ | ||
177 | 0x03f80504, | 222 | 0x03f80504, |
223 | /* 0x0072: chsw */ | ||
178 | 0x27f100f8, | 224 | 0x27f100f8, |
179 | 0x23cf1400, | 225 | 0x23cf1400, |
180 | 0x1e3fc800, | 226 | 0x1e3fc800, |
@@ -183,18 +229,22 @@ uint32_t nva3_pcopy_code[] = { | |||
183 | 0x1e3af052, | 229 | 0x1e3af052, |
184 | 0xf00023d0, | 230 | 0xf00023d0, |
185 | 0x24d00147, | 231 | 0x24d00147, |
232 | /* 0x0093: chsw_no_unload */ | ||
186 | 0xcf00f880, | 233 | 0xcf00f880, |
187 | 0x3dc84023, | 234 | 0x3dc84023, |
188 | 0x220bf41e, | 235 | 0x220bf41e, |
189 | 0xf40131f4, | 236 | 0xf40131f4, |
190 | 0x57f05221, | 237 | 0x57f05221, |
191 | 0x0367f004, | 238 | 0x0367f004, |
239 | /* 0x00a8: chsw_load_ctx_dma */ | ||
192 | 0xa07856bc, | 240 | 0xa07856bc, |
193 | 0xb6018068, | 241 | 0xb6018068, |
194 | 0x87d00884, | 242 | 0x87d00884, |
195 | 0x0162b600, | 243 | 0x0162b600, |
244 | /* 0x00bb: chsw_finish_load */ | ||
196 | 0xf0f018f4, | 245 | 0xf0f018f4, |
197 | 0x23d00237, | 246 | 0x23d00237, |
247 | /* 0x00c3: dispatch */ | ||
198 | 0xf100f880, | 248 | 0xf100f880, |
199 | 0xcf190037, | 249 | 0xcf190037, |
200 | 0x33cf4032, | 250 | 0x33cf4032, |
@@ -202,6 +252,7 @@ uint32_t nva3_pcopy_code[] = { | |||
202 | 0x1024b607, | 252 | 0x1024b607, |
203 | 0x010057f1, | 253 | 0x010057f1, |
204 | 0x74bd64bd, | 254 | 0x74bd64bd, |
255 | /* 0x00dc: dispatch_loop */ | ||
205 | 0x58005658, | 256 | 0x58005658, |
206 | 0x50b60157, | 257 | 0x50b60157, |
207 | 0x0446b804, | 258 | 0x0446b804, |
@@ -211,6 +262,7 @@ uint32_t nva3_pcopy_code[] = { | |||
211 | 0xb60276bb, | 262 | 0xb60276bb, |
212 | 0x57bb0374, | 263 | 0x57bb0374, |
213 | 0xdf0ef400, | 264 | 0xdf0ef400, |
265 | /* 0x0100: dispatch_valid_mthd */ | ||
214 | 0xb60246bb, | 266 | 0xb60246bb, |
215 | 0x45bb0344, | 267 | 0x45bb0344, |
216 | 0x01459800, | 268 | 0x01459800, |
@@ -220,31 +272,41 @@ uint32_t nva3_pcopy_code[] = { | |||
220 | 0xb0014658, | 272 | 0xb0014658, |
221 | 0x1bf40064, | 273 | 0x1bf40064, |
222 | 0x00538009, | 274 | 0x00538009, |
275 | /* 0x0127: dispatch_cmd */ | ||
223 | 0xf4300ef4, | 276 | 0xf4300ef4, |
224 | 0x55f90132, | 277 | 0x55f90132, |
225 | 0xf40c01f4, | 278 | 0xf40c01f4, |
279 | /* 0x0132: dispatch_invalid_bitfield */ | ||
226 | 0x25f0250e, | 280 | 0x25f0250e, |
281 | /* 0x0135: dispatch_illegal_mthd */ | ||
227 | 0x0125f002, | 282 | 0x0125f002, |
283 | /* 0x0138: dispatch_error */ | ||
228 | 0x100047f1, | 284 | 0x100047f1, |
229 | 0xd00042d0, | 285 | 0xd00042d0, |
230 | 0x27f04043, | 286 | 0x27f04043, |
231 | 0x0002d040, | 287 | 0x0002d040, |
288 | /* 0x0148: hostirq_wait */ | ||
232 | 0xf08002cf, | 289 | 0xf08002cf, |
233 | 0x24b04024, | 290 | 0x24b04024, |
234 | 0xf71bf400, | 291 | 0xf71bf400, |
292 | /* 0x0154: dispatch_done */ | ||
235 | 0x1d0027f1, | 293 | 0x1d0027f1, |
236 | 0xd00137f0, | 294 | 0xd00137f0, |
237 | 0x00f80023, | 295 | 0x00f80023, |
296 | /* 0x0160: cmd_nop */ | ||
297 | /* 0x0162: cmd_pm_trigger */ | ||
238 | 0x27f100f8, | 298 | 0x27f100f8, |
239 | 0x34bd2200, | 299 | 0x34bd2200, |
240 | 0xd00233f0, | 300 | 0xd00233f0, |
241 | 0x00f80023, | 301 | 0x00f80023, |
302 | /* 0x0170: cmd_dma */ | ||
242 | 0x012842b7, | 303 | 0x012842b7, |
243 | 0xf00145b6, | 304 | 0xf00145b6, |
244 | 0x43801e39, | 305 | 0x43801e39, |
245 | 0x0040b701, | 306 | 0x0040b701, |
246 | 0x0644b606, | 307 | 0x0644b606, |
247 | 0xf80043d0, | 308 | 0xf80043d0, |
309 | /* 0x0189: cmd_exec_set_format */ | ||
248 | 0xf030f400, | 310 | 0xf030f400, |
249 | 0xb00001b0, | 311 | 0xb00001b0, |
250 | 0x01b00101, | 312 | 0x01b00101, |
@@ -256,20 +318,26 @@ uint32_t nva3_pcopy_code[] = { | |||
256 | 0x70b63847, | 318 | 0x70b63847, |
257 | 0x0232f401, | 319 | 0x0232f401, |
258 | 0x94bd84bd, | 320 | 0x94bd84bd, |
321 | /* 0x01b4: ncomp_loop */ | ||
259 | 0xb60f4ac4, | 322 | 0xb60f4ac4, |
260 | 0xb4bd0445, | 323 | 0xb4bd0445, |
324 | /* 0x01bc: bpc_loop */ | ||
261 | 0xf404a430, | 325 | 0xf404a430, |
262 | 0xa5ff0f18, | 326 | 0xa5ff0f18, |
263 | 0x00cbbbc0, | 327 | 0x00cbbbc0, |
264 | 0xf40231f4, | 328 | 0xf40231f4, |
329 | /* 0x01ce: cmp_c0 */ | ||
265 | 0x1bf4220e, | 330 | 0x1bf4220e, |
266 | 0x10c7f00c, | 331 | 0x10c7f00c, |
267 | 0xf400cbbb, | 332 | 0xf400cbbb, |
333 | /* 0x01da: cmp_c1 */ | ||
268 | 0xa430160e, | 334 | 0xa430160e, |
269 | 0x0c18f406, | 335 | 0x0c18f406, |
270 | 0xbb14c7f0, | 336 | 0xbb14c7f0, |
271 | 0x0ef400cb, | 337 | 0x0ef400cb, |
338 | /* 0x01e9: cmp_zero */ | ||
272 | 0x80c7f107, | 339 | 0x80c7f107, |
340 | /* 0x01ed: bpc_next */ | ||
273 | 0x01c83800, | 341 | 0x01c83800, |
274 | 0xb60180b6, | 342 | 0xb60180b6, |
275 | 0xb5b801b0, | 343 | 0xb5b801b0, |
@@ -280,6 +348,7 @@ uint32_t nva3_pcopy_code[] = { | |||
280 | 0x98110680, | 348 | 0x98110680, |
281 | 0x68fd2008, | 349 | 0x68fd2008, |
282 | 0x0502f400, | 350 | 0x0502f400, |
351 | /* 0x0216: dst_xcnt */ | ||
283 | 0x75fd64bd, | 352 | 0x75fd64bd, |
284 | 0x1c078000, | 353 | 0x1c078000, |
285 | 0xf10078fd, | 354 | 0xf10078fd, |
@@ -304,6 +373,7 @@ uint32_t nva3_pcopy_code[] = { | |||
304 | 0x980056d0, | 373 | 0x980056d0, |
305 | 0x56d01f06, | 374 | 0x56d01f06, |
306 | 0x1030f440, | 375 | 0x1030f440, |
376 | /* 0x0276: cmd_exec_set_surface_tiled */ | ||
307 | 0x579800f8, | 377 | 0x579800f8, |
308 | 0x6879c70a, | 378 | 0x6879c70a, |
309 | 0xb66478c7, | 379 | 0xb66478c7, |
@@ -311,9 +381,11 @@ uint32_t nva3_pcopy_code[] = { | |||
311 | 0x0e76b060, | 381 | 0x0e76b060, |
312 | 0xf0091bf4, | 382 | 0xf0091bf4, |
313 | 0x0ef40477, | 383 | 0x0ef40477, |
384 | /* 0x0291: xtile64 */ | ||
314 | 0x027cf00f, | 385 | 0x027cf00f, |
315 | 0xfd1170b6, | 386 | 0xfd1170b6, |
316 | 0x77f00947, | 387 | 0x77f00947, |
388 | /* 0x029d: xtileok */ | ||
317 | 0x0f5a9806, | 389 | 0x0f5a9806, |
318 | 0xfd115b98, | 390 | 0xfd115b98, |
319 | 0xb7f000ab, | 391 | 0xb7f000ab, |
@@ -371,6 +443,7 @@ uint32_t nva3_pcopy_code[] = { | |||
371 | 0x67d00600, | 443 | 0x67d00600, |
372 | 0x0060b700, | 444 | 0x0060b700, |
373 | 0x0068d004, | 445 | 0x0068d004, |
446 | /* 0x0382: cmd_exec_set_surface_linear */ | ||
374 | 0x6cf000f8, | 447 | 0x6cf000f8, |
375 | 0x0260b702, | 448 | 0x0260b702, |
376 | 0x0864b602, | 449 | 0x0864b602, |
@@ -381,13 +454,16 @@ uint32_t nva3_pcopy_code[] = { | |||
381 | 0xb70067d0, | 454 | 0xb70067d0, |
382 | 0x98040060, | 455 | 0x98040060, |
383 | 0x67d00957, | 456 | 0x67d00957, |
457 | /* 0x03ab: cmd_exec_wait */ | ||
384 | 0xf900f800, | 458 | 0xf900f800, |
385 | 0xf110f900, | 459 | 0xf110f900, |
386 | 0xb6080007, | 460 | 0xb6080007, |
461 | /* 0x03b6: loop */ | ||
387 | 0x01cf0604, | 462 | 0x01cf0604, |
388 | 0x0114f000, | 463 | 0x0114f000, |
389 | 0xfcfa1bf4, | 464 | 0xfcfa1bf4, |
390 | 0xf800fc10, | 465 | 0xf800fc10, |
466 | /* 0x03c5: cmd_exec_query */ | ||
391 | 0x0d34c800, | 467 | 0x0d34c800, |
392 | 0xf5701bf4, | 468 | 0xf5701bf4, |
393 | 0xf103ab21, | 469 | 0xf103ab21, |
@@ -417,6 +493,7 @@ uint32_t nva3_pcopy_code[] = { | |||
417 | 0x47f10153, | 493 | 0x47f10153, |
418 | 0x44b60800, | 494 | 0x44b60800, |
419 | 0x0045d006, | 495 | 0x0045d006, |
496 | /* 0x0438: query_counter */ | ||
420 | 0x03ab21f5, | 497 | 0x03ab21f5, |
421 | 0x080c47f1, | 498 | 0x080c47f1, |
422 | 0x980644b6, | 499 | 0x980644b6, |
@@ -439,11 +516,13 @@ uint32_t nva3_pcopy_code[] = { | |||
439 | 0x47f10153, | 516 | 0x47f10153, |
440 | 0x44b60800, | 517 | 0x44b60800, |
441 | 0x0045d006, | 518 | 0x0045d006, |
519 | /* 0x0492: cmd_exec */ | ||
442 | 0x21f500f8, | 520 | 0x21f500f8, |
443 | 0x3fc803ab, | 521 | 0x3fc803ab, |
444 | 0x0e0bf400, | 522 | 0x0e0bf400, |
445 | 0x018921f5, | 523 | 0x018921f5, |
446 | 0x020047f1, | 524 | 0x020047f1, |
525 | /* 0x04a7: cmd_exec_no_format */ | ||
447 | 0xf11e0ef4, | 526 | 0xf11e0ef4, |
448 | 0xb6081067, | 527 | 0xb6081067, |
449 | 0x77f00664, | 528 | 0x77f00664, |
@@ -451,19 +530,24 @@ uint32_t nva3_pcopy_code[] = { | |||
451 | 0x981c0780, | 530 | 0x981c0780, |
452 | 0x67d02007, | 531 | 0x67d02007, |
453 | 0x4067d000, | 532 | 0x4067d000, |
533 | /* 0x04c2: cmd_exec_init_src_surface */ | ||
454 | 0x32f444bd, | 534 | 0x32f444bd, |
455 | 0xc854bd02, | 535 | 0xc854bd02, |
456 | 0x0bf4043f, | 536 | 0x0bf4043f, |
457 | 0x8221f50a, | 537 | 0x8221f50a, |
458 | 0x0a0ef403, | 538 | 0x0a0ef403, |
539 | /* 0x04d4: src_tiled */ | ||
459 | 0x027621f5, | 540 | 0x027621f5, |
541 | /* 0x04db: cmd_exec_init_dst_surface */ | ||
460 | 0xf40749f0, | 542 | 0xf40749f0, |
461 | 0x57f00231, | 543 | 0x57f00231, |
462 | 0x083fc82c, | 544 | 0x083fc82c, |
463 | 0xf50a0bf4, | 545 | 0xf50a0bf4, |
464 | 0xf4038221, | 546 | 0xf4038221, |
547 | /* 0x04ee: dst_tiled */ | ||
465 | 0x21f50a0e, | 548 | 0x21f50a0e, |
466 | 0x49f00276, | 549 | 0x49f00276, |
550 | /* 0x04f5: cmd_exec_kick */ | ||
467 | 0x0057f108, | 551 | 0x0057f108, |
468 | 0x0654b608, | 552 | 0x0654b608, |
469 | 0xd0210698, | 553 | 0xd0210698, |
@@ -473,6 +557,8 @@ uint32_t nva3_pcopy_code[] = { | |||
473 | 0xc80054d0, | 557 | 0xc80054d0, |
474 | 0x0bf40c3f, | 558 | 0x0bf40c3f, |
475 | 0xc521f507, | 559 | 0xc521f507, |
560 | /* 0x0519: cmd_exec_done */ | ||
561 | /* 0x051b: cmd_wrcache_flush */ | ||
476 | 0xf100f803, | 562 | 0xf100f803, |
477 | 0xbd220027, | 563 | 0xbd220027, |
478 | 0x0133f034, | 564 | 0x0133f034, |
diff --git a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h b/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h index a8d17458ced1..cd879f31bb38 100644 --- a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h +++ b/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h | |||
@@ -1,34 +1,65 @@ | |||
1 | uint32_t nvc0_pcopy_data[] = { | 1 | u32 nvc0_pcopy_data[] = { |
2 | /* 0x0000: ctx_object */ | ||
2 | 0x00000000, | 3 | 0x00000000, |
4 | /* 0x0004: ctx_query_address_high */ | ||
3 | 0x00000000, | 5 | 0x00000000, |
6 | /* 0x0008: ctx_query_address_low */ | ||
4 | 0x00000000, | 7 | 0x00000000, |
8 | /* 0x000c: ctx_query_counter */ | ||
5 | 0x00000000, | 9 | 0x00000000, |
10 | /* 0x0010: ctx_src_address_high */ | ||
6 | 0x00000000, | 11 | 0x00000000, |
12 | /* 0x0014: ctx_src_address_low */ | ||
7 | 0x00000000, | 13 | 0x00000000, |
14 | /* 0x0018: ctx_src_pitch */ | ||
8 | 0x00000000, | 15 | 0x00000000, |
16 | /* 0x001c: ctx_src_tile_mode */ | ||
9 | 0x00000000, | 17 | 0x00000000, |
18 | /* 0x0020: ctx_src_xsize */ | ||
10 | 0x00000000, | 19 | 0x00000000, |
20 | /* 0x0024: ctx_src_ysize */ | ||
11 | 0x00000000, | 21 | 0x00000000, |
22 | /* 0x0028: ctx_src_zsize */ | ||
12 | 0x00000000, | 23 | 0x00000000, |
24 | /* 0x002c: ctx_src_zoff */ | ||
13 | 0x00000000, | 25 | 0x00000000, |
26 | /* 0x0030: ctx_src_xoff */ | ||
14 | 0x00000000, | 27 | 0x00000000, |
28 | /* 0x0034: ctx_src_yoff */ | ||
15 | 0x00000000, | 29 | 0x00000000, |
30 | /* 0x0038: ctx_src_cpp */ | ||
16 | 0x00000000, | 31 | 0x00000000, |
32 | /* 0x003c: ctx_dst_address_high */ | ||
17 | 0x00000000, | 33 | 0x00000000, |
34 | /* 0x0040: ctx_dst_address_low */ | ||
18 | 0x00000000, | 35 | 0x00000000, |
36 | /* 0x0044: ctx_dst_pitch */ | ||
19 | 0x00000000, | 37 | 0x00000000, |
38 | /* 0x0048: ctx_dst_tile_mode */ | ||
20 | 0x00000000, | 39 | 0x00000000, |
40 | /* 0x004c: ctx_dst_xsize */ | ||
21 | 0x00000000, | 41 | 0x00000000, |
42 | /* 0x0050: ctx_dst_ysize */ | ||
22 | 0x00000000, | 43 | 0x00000000, |
44 | /* 0x0054: ctx_dst_zsize */ | ||
23 | 0x00000000, | 45 | 0x00000000, |
46 | /* 0x0058: ctx_dst_zoff */ | ||
24 | 0x00000000, | 47 | 0x00000000, |
48 | /* 0x005c: ctx_dst_xoff */ | ||
25 | 0x00000000, | 49 | 0x00000000, |
50 | /* 0x0060: ctx_dst_yoff */ | ||
26 | 0x00000000, | 51 | 0x00000000, |
52 | /* 0x0064: ctx_dst_cpp */ | ||
27 | 0x00000000, | 53 | 0x00000000, |
54 | /* 0x0068: ctx_format */ | ||
28 | 0x00000000, | 55 | 0x00000000, |
56 | /* 0x006c: ctx_swz_const0 */ | ||
29 | 0x00000000, | 57 | 0x00000000, |
58 | /* 0x0070: ctx_swz_const1 */ | ||
30 | 0x00000000, | 59 | 0x00000000, |
60 | /* 0x0074: ctx_xcnt */ | ||
31 | 0x00000000, | 61 | 0x00000000, |
62 | /* 0x0078: ctx_ycnt */ | ||
32 | 0x00000000, | 63 | 0x00000000, |
33 | 0x00000000, | 64 | 0x00000000, |
34 | 0x00000000, | 65 | 0x00000000, |
@@ -63,6 +94,7 @@ uint32_t nvc0_pcopy_data[] = { | |||
63 | 0x00000000, | 94 | 0x00000000, |
64 | 0x00000000, | 95 | 0x00000000, |
65 | 0x00000000, | 96 | 0x00000000, |
97 | /* 0x0100: dispatch_table */ | ||
66 | 0x00010000, | 98 | 0x00010000, |
67 | 0x00000000, | 99 | 0x00000000, |
68 | 0x00000000, | 100 | 0x00000000, |
@@ -111,11 +143,11 @@ uint32_t nvc0_pcopy_data[] = { | |||
111 | 0x00000010, | 143 | 0x00000010, |
112 | 0xffffff00, | 144 | 0xffffff00, |
113 | 0x00000014, | 145 | 0x00000014, |
114 | 0x0000000f, | 146 | 0x00000000, |
115 | 0x0000003c, | 147 | 0x0000003c, |
116 | 0xffffff00, | 148 | 0xffffff00, |
117 | 0x00000040, | 149 | 0x00000040, |
118 | 0x0000000f, | 150 | 0x00000000, |
119 | 0x00000018, | 151 | 0x00000018, |
120 | 0xfff80000, | 152 | 0xfff80000, |
121 | 0x00000044, | 153 | 0x00000044, |
@@ -139,7 +171,8 @@ uint32_t nvc0_pcopy_data[] = { | |||
139 | 0x00000800, | 171 | 0x00000800, |
140 | }; | 172 | }; |
141 | 173 | ||
142 | uint32_t nvc0_pcopy_code[] = { | 174 | u32 nvc0_pcopy_code[] = { |
175 | /* 0x0000: main */ | ||
143 | 0x04fe04bd, | 176 | 0x04fe04bd, |
144 | 0x3517f000, | 177 | 0x3517f000, |
145 | 0xf10010fe, | 178 | 0xf10010fe, |
@@ -151,15 +184,20 @@ uint32_t nvc0_pcopy_code[] = { | |||
151 | 0x17f11031, | 184 | 0x17f11031, |
152 | 0x27f01200, | 185 | 0x27f01200, |
153 | 0x0012d003, | 186 | 0x0012d003, |
187 | /* 0x002f: spin */ | ||
154 | 0xf40031f4, | 188 | 0xf40031f4, |
155 | 0x0ef40028, | 189 | 0x0ef40028, |
190 | /* 0x0035: ih */ | ||
156 | 0x8001cffd, | 191 | 0x8001cffd, |
157 | 0xf40812c4, | 192 | 0xf40812c4, |
158 | 0x21f4060b, | 193 | 0x21f4060b, |
194 | /* 0x0041: ih_no_chsw */ | ||
159 | 0x0412c4ca, | 195 | 0x0412c4ca, |
160 | 0xf5070bf4, | 196 | 0xf5070bf4, |
197 | /* 0x004b: ih_no_cmd */ | ||
161 | 0xc4010221, | 198 | 0xc4010221, |
162 | 0x01d00c11, | 199 | 0x01d00c11, |
200 | /* 0x0053: swctx */ | ||
163 | 0xf101f840, | 201 | 0xf101f840, |
164 | 0xfe770047, | 202 | 0xfe770047, |
165 | 0x47f1004b, | 203 | 0x47f1004b, |
@@ -188,8 +226,11 @@ uint32_t nvc0_pcopy_code[] = { | |||
188 | 0xf00204b9, | 226 | 0xf00204b9, |
189 | 0x01f40643, | 227 | 0x01f40643, |
190 | 0x0604fa09, | 228 | 0x0604fa09, |
229 | /* 0x00c3: swctx_load */ | ||
191 | 0xfa060ef4, | 230 | 0xfa060ef4, |
231 | /* 0x00c6: swctx_done */ | ||
192 | 0x03f80504, | 232 | 0x03f80504, |
233 | /* 0x00ca: chsw */ | ||
193 | 0x27f100f8, | 234 | 0x27f100f8, |
194 | 0x23cf1400, | 235 | 0x23cf1400, |
195 | 0x1e3fc800, | 236 | 0x1e3fc800, |
@@ -198,18 +239,22 @@ uint32_t nvc0_pcopy_code[] = { | |||
198 | 0x1e3af053, | 239 | 0x1e3af053, |
199 | 0xf00023d0, | 240 | 0xf00023d0, |
200 | 0x24d00147, | 241 | 0x24d00147, |
242 | /* 0x00eb: chsw_no_unload */ | ||
201 | 0xcf00f880, | 243 | 0xcf00f880, |
202 | 0x3dc84023, | 244 | 0x3dc84023, |
203 | 0x090bf41e, | 245 | 0x090bf41e, |
204 | 0xf40131f4, | 246 | 0xf40131f4, |
247 | /* 0x00fa: chsw_finish_load */ | ||
205 | 0x37f05321, | 248 | 0x37f05321, |
206 | 0x8023d002, | 249 | 0x8023d002, |
250 | /* 0x0102: dispatch */ | ||
207 | 0x37f100f8, | 251 | 0x37f100f8, |
208 | 0x32cf1900, | 252 | 0x32cf1900, |
209 | 0x0033cf40, | 253 | 0x0033cf40, |
210 | 0x07ff24e4, | 254 | 0x07ff24e4, |
211 | 0xf11024b6, | 255 | 0xf11024b6, |
212 | 0xbd010057, | 256 | 0xbd010057, |
257 | /* 0x011b: dispatch_loop */ | ||
213 | 0x5874bd64, | 258 | 0x5874bd64, |
214 | 0x57580056, | 259 | 0x57580056, |
215 | 0x0450b601, | 260 | 0x0450b601, |
@@ -219,6 +264,7 @@ uint32_t nvc0_pcopy_code[] = { | |||
219 | 0xbb0f08f4, | 264 | 0xbb0f08f4, |
220 | 0x74b60276, | 265 | 0x74b60276, |
221 | 0x0057bb03, | 266 | 0x0057bb03, |
267 | /* 0x013f: dispatch_valid_mthd */ | ||
222 | 0xbbdf0ef4, | 268 | 0xbbdf0ef4, |
223 | 0x44b60246, | 269 | 0x44b60246, |
224 | 0x0045bb03, | 270 | 0x0045bb03, |
@@ -229,24 +275,33 @@ uint32_t nvc0_pcopy_code[] = { | |||
229 | 0x64b00146, | 275 | 0x64b00146, |
230 | 0x091bf400, | 276 | 0x091bf400, |
231 | 0xf4005380, | 277 | 0xf4005380, |
278 | /* 0x0166: dispatch_cmd */ | ||
232 | 0x32f4300e, | 279 | 0x32f4300e, |
233 | 0xf455f901, | 280 | 0xf455f901, |
234 | 0x0ef40c01, | 281 | 0x0ef40c01, |
282 | /* 0x0171: dispatch_invalid_bitfield */ | ||
235 | 0x0225f025, | 283 | 0x0225f025, |
284 | /* 0x0174: dispatch_illegal_mthd */ | ||
285 | /* 0x0177: dispatch_error */ | ||
236 | 0xf10125f0, | 286 | 0xf10125f0, |
237 | 0xd0100047, | 287 | 0xd0100047, |
238 | 0x43d00042, | 288 | 0x43d00042, |
239 | 0x4027f040, | 289 | 0x4027f040, |
290 | /* 0x0187: hostirq_wait */ | ||
240 | 0xcf0002d0, | 291 | 0xcf0002d0, |
241 | 0x24f08002, | 292 | 0x24f08002, |
242 | 0x0024b040, | 293 | 0x0024b040, |
294 | /* 0x0193: dispatch_done */ | ||
243 | 0xf1f71bf4, | 295 | 0xf1f71bf4, |
244 | 0xf01d0027, | 296 | 0xf01d0027, |
245 | 0x23d00137, | 297 | 0x23d00137, |
298 | /* 0x019f: cmd_nop */ | ||
246 | 0xf800f800, | 299 | 0xf800f800, |
300 | /* 0x01a1: cmd_pm_trigger */ | ||
247 | 0x0027f100, | 301 | 0x0027f100, |
248 | 0xf034bd22, | 302 | 0xf034bd22, |
249 | 0x23d00233, | 303 | 0x23d00233, |
304 | /* 0x01af: cmd_exec_set_format */ | ||
250 | 0xf400f800, | 305 | 0xf400f800, |
251 | 0x01b0f030, | 306 | 0x01b0f030, |
252 | 0x0101b000, | 307 | 0x0101b000, |
@@ -258,20 +313,26 @@ uint32_t nvc0_pcopy_code[] = { | |||
258 | 0x3847c701, | 313 | 0x3847c701, |
259 | 0xf40170b6, | 314 | 0xf40170b6, |
260 | 0x84bd0232, | 315 | 0x84bd0232, |
316 | /* 0x01da: ncomp_loop */ | ||
261 | 0x4ac494bd, | 317 | 0x4ac494bd, |
262 | 0x0445b60f, | 318 | 0x0445b60f, |
319 | /* 0x01e2: bpc_loop */ | ||
263 | 0xa430b4bd, | 320 | 0xa430b4bd, |
264 | 0x0f18f404, | 321 | 0x0f18f404, |
265 | 0xbbc0a5ff, | 322 | 0xbbc0a5ff, |
266 | 0x31f400cb, | 323 | 0x31f400cb, |
267 | 0x220ef402, | 324 | 0x220ef402, |
325 | /* 0x01f4: cmp_c0 */ | ||
268 | 0xf00c1bf4, | 326 | 0xf00c1bf4, |
269 | 0xcbbb10c7, | 327 | 0xcbbb10c7, |
270 | 0x160ef400, | 328 | 0x160ef400, |
329 | /* 0x0200: cmp_c1 */ | ||
271 | 0xf406a430, | 330 | 0xf406a430, |
272 | 0xc7f00c18, | 331 | 0xc7f00c18, |
273 | 0x00cbbb14, | 332 | 0x00cbbb14, |
333 | /* 0x020f: cmp_zero */ | ||
274 | 0xf1070ef4, | 334 | 0xf1070ef4, |
335 | /* 0x0213: bpc_next */ | ||
275 | 0x380080c7, | 336 | 0x380080c7, |
276 | 0x80b601c8, | 337 | 0x80b601c8, |
277 | 0x01b0b601, | 338 | 0x01b0b601, |
@@ -283,6 +344,7 @@ uint32_t nvc0_pcopy_code[] = { | |||
283 | 0x1d08980e, | 344 | 0x1d08980e, |
284 | 0xf40068fd, | 345 | 0xf40068fd, |
285 | 0x64bd0502, | 346 | 0x64bd0502, |
347 | /* 0x023c: dst_xcnt */ | ||
286 | 0x800075fd, | 348 | 0x800075fd, |
287 | 0x78fd1907, | 349 | 0x78fd1907, |
288 | 0x1057f100, | 350 | 0x1057f100, |
@@ -307,15 +369,18 @@ uint32_t nvc0_pcopy_code[] = { | |||
307 | 0x1c069800, | 369 | 0x1c069800, |
308 | 0xf44056d0, | 370 | 0xf44056d0, |
309 | 0x00f81030, | 371 | 0x00f81030, |
372 | /* 0x029c: cmd_exec_set_surface_tiled */ | ||
310 | 0xc7075798, | 373 | 0xc7075798, |
311 | 0x78c76879, | 374 | 0x78c76879, |
312 | 0x0380b664, | 375 | 0x0380b664, |
313 | 0xb06077c7, | 376 | 0xb06077c7, |
314 | 0x1bf40e76, | 377 | 0x1bf40e76, |
315 | 0x0477f009, | 378 | 0x0477f009, |
379 | /* 0x02b7: xtile64 */ | ||
316 | 0xf00f0ef4, | 380 | 0xf00f0ef4, |
317 | 0x70b6027c, | 381 | 0x70b6027c, |
318 | 0x0947fd11, | 382 | 0x0947fd11, |
383 | /* 0x02c3: xtileok */ | ||
319 | 0x980677f0, | 384 | 0x980677f0, |
320 | 0x5b980c5a, | 385 | 0x5b980c5a, |
321 | 0x00abfd0e, | 386 | 0x00abfd0e, |
@@ -374,6 +439,7 @@ uint32_t nvc0_pcopy_code[] = { | |||
374 | 0xb70067d0, | 439 | 0xb70067d0, |
375 | 0xd0040060, | 440 | 0xd0040060, |
376 | 0x00f80068, | 441 | 0x00f80068, |
442 | /* 0x03a8: cmd_exec_set_surface_linear */ | ||
377 | 0xb7026cf0, | 443 | 0xb7026cf0, |
378 | 0xb6020260, | 444 | 0xb6020260, |
379 | 0x57980864, | 445 | 0x57980864, |
@@ -384,12 +450,15 @@ uint32_t nvc0_pcopy_code[] = { | |||
384 | 0x0060b700, | 450 | 0x0060b700, |
385 | 0x06579804, | 451 | 0x06579804, |
386 | 0xf80067d0, | 452 | 0xf80067d0, |
453 | /* 0x03d1: cmd_exec_wait */ | ||
387 | 0xf900f900, | 454 | 0xf900f900, |
388 | 0x0007f110, | 455 | 0x0007f110, |
389 | 0x0604b608, | 456 | 0x0604b608, |
457 | /* 0x03dc: loop */ | ||
390 | 0xf00001cf, | 458 | 0xf00001cf, |
391 | 0x1bf40114, | 459 | 0x1bf40114, |
392 | 0xfc10fcfa, | 460 | 0xfc10fcfa, |
461 | /* 0x03eb: cmd_exec_query */ | ||
393 | 0xc800f800, | 462 | 0xc800f800, |
394 | 0x1bf40d34, | 463 | 0x1bf40d34, |
395 | 0xd121f570, | 464 | 0xd121f570, |
@@ -419,6 +488,7 @@ uint32_t nvc0_pcopy_code[] = { | |||
419 | 0x0153f026, | 488 | 0x0153f026, |
420 | 0x080047f1, | 489 | 0x080047f1, |
421 | 0xd00644b6, | 490 | 0xd00644b6, |
491 | /* 0x045e: query_counter */ | ||
422 | 0x21f50045, | 492 | 0x21f50045, |
423 | 0x47f103d1, | 493 | 0x47f103d1, |
424 | 0x44b6080c, | 494 | 0x44b6080c, |
@@ -442,11 +512,13 @@ uint32_t nvc0_pcopy_code[] = { | |||
442 | 0x080047f1, | 512 | 0x080047f1, |
443 | 0xd00644b6, | 513 | 0xd00644b6, |
444 | 0x00f80045, | 514 | 0x00f80045, |
515 | /* 0x04b8: cmd_exec */ | ||
445 | 0x03d121f5, | 516 | 0x03d121f5, |
446 | 0xf4003fc8, | 517 | 0xf4003fc8, |
447 | 0x21f50e0b, | 518 | 0x21f50e0b, |
448 | 0x47f101af, | 519 | 0x47f101af, |
449 | 0x0ef40200, | 520 | 0x0ef40200, |
521 | /* 0x04cd: cmd_exec_no_format */ | ||
450 | 0x1067f11e, | 522 | 0x1067f11e, |
451 | 0x0664b608, | 523 | 0x0664b608, |
452 | 0x800177f0, | 524 | 0x800177f0, |
@@ -454,18 +526,23 @@ uint32_t nvc0_pcopy_code[] = { | |||
454 | 0x1d079819, | 526 | 0x1d079819, |
455 | 0xd00067d0, | 527 | 0xd00067d0, |
456 | 0x44bd4067, | 528 | 0x44bd4067, |
529 | /* 0x04e8: cmd_exec_init_src_surface */ | ||
457 | 0xbd0232f4, | 530 | 0xbd0232f4, |
458 | 0x043fc854, | 531 | 0x043fc854, |
459 | 0xf50a0bf4, | 532 | 0xf50a0bf4, |
460 | 0xf403a821, | 533 | 0xf403a821, |
534 | /* 0x04fa: src_tiled */ | ||
461 | 0x21f50a0e, | 535 | 0x21f50a0e, |
462 | 0x49f0029c, | 536 | 0x49f0029c, |
537 | /* 0x0501: cmd_exec_init_dst_surface */ | ||
463 | 0x0231f407, | 538 | 0x0231f407, |
464 | 0xc82c57f0, | 539 | 0xc82c57f0, |
465 | 0x0bf4083f, | 540 | 0x0bf4083f, |
466 | 0xa821f50a, | 541 | 0xa821f50a, |
467 | 0x0a0ef403, | 542 | 0x0a0ef403, |
543 | /* 0x0514: dst_tiled */ | ||
468 | 0x029c21f5, | 544 | 0x029c21f5, |
545 | /* 0x051b: cmd_exec_kick */ | ||
469 | 0xf10849f0, | 546 | 0xf10849f0, |
470 | 0xb6080057, | 547 | 0xb6080057, |
471 | 0x06980654, | 548 | 0x06980654, |
@@ -475,7 +552,9 @@ uint32_t nvc0_pcopy_code[] = { | |||
475 | 0x54d00546, | 552 | 0x54d00546, |
476 | 0x0c3fc800, | 553 | 0x0c3fc800, |
477 | 0xf5070bf4, | 554 | 0xf5070bf4, |
555 | /* 0x053f: cmd_exec_done */ | ||
478 | 0xf803eb21, | 556 | 0xf803eb21, |
557 | /* 0x0541: cmd_wrcache_flush */ | ||
479 | 0x0027f100, | 558 | 0x0027f100, |
480 | 0xf034bd22, | 559 | 0xf034bd22, |
481 | 0x23d00133, | 560 | 0x23d00133, |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index c486d3ce3c2c..d0d60e1e7f95 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -607,7 +607,7 @@ nvd0_crtc_commit(struct drm_crtc *crtc) | |||
607 | } | 607 | } |
608 | 608 | ||
609 | static bool | 609 | static bool |
610 | nvd0_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, | 610 | nvd0_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, |
611 | struct drm_display_mode *adjusted_mode) | 611 | struct drm_display_mode *adjusted_mode) |
612 | { | 612 | { |
613 | return true; | 613 | return true; |
@@ -938,7 +938,8 @@ nvd0_dac_dpms(struct drm_encoder *encoder, int mode) | |||
938 | } | 938 | } |
939 | 939 | ||
940 | static bool | 940 | static bool |
941 | nvd0_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 941 | nvd0_dac_mode_fixup(struct drm_encoder *encoder, |
942 | const struct drm_display_mode *mode, | ||
942 | struct drm_display_mode *adjusted_mode) | 943 | struct drm_display_mode *adjusted_mode) |
943 | { | 944 | { |
944 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 945 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
@@ -1377,7 +1378,8 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode) | |||
1377 | } | 1378 | } |
1378 | 1379 | ||
1379 | static bool | 1380 | static bool |
1380 | nvd0_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 1381 | nvd0_sor_mode_fixup(struct drm_encoder *encoder, |
1382 | const struct drm_display_mode *mode, | ||
1381 | struct drm_display_mode *adjusted_mode) | 1383 | struct drm_display_mode *adjusted_mode) |
1382 | { | 1384 | { |
1383 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1385 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 88718fad5d6d..2666a5308ab9 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -71,7 +71,6 @@ static struct drm_driver driver = { | |||
71 | .irq_postinstall = r128_driver_irq_postinstall, | 71 | .irq_postinstall = r128_driver_irq_postinstall, |
72 | .irq_uninstall = r128_driver_irq_uninstall, | 72 | .irq_uninstall = r128_driver_irq_uninstall, |
73 | .irq_handler = r128_driver_irq_handler, | 73 | .irq_handler = r128_driver_irq_handler, |
74 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
75 | .ioctls = r128_ioctls, | 74 | .ioctls = r128_ioctls, |
76 | .dma_ioctl = r128_cce_buffers, | 75 | .dma_ioctl = r128_cce_buffers, |
77 | .fops = &r128_driver_fops, | 76 | .fops = &r128_driver_fops, |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 3904d7964a4b..9e6f76fec527 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -457,22 +457,18 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, | |||
457 | switch (pll_id) { | 457 | switch (pll_id) { |
458 | case ATOM_PPLL1: | 458 | case ATOM_PPLL1: |
459 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; | 459 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; |
460 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); | ||
461 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); | ||
462 | break; | 460 | break; |
463 | case ATOM_PPLL2: | 461 | case ATOM_PPLL2: |
464 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; | 462 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; |
465 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); | ||
466 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); | ||
467 | break; | 463 | break; |
468 | case ATOM_DCPLL: | 464 | case ATOM_DCPLL: |
469 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; | 465 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; |
470 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(0); | ||
471 | args.v3.usSpreadSpectrumStep = cpu_to_le16(0); | ||
472 | break; | 466 | break; |
473 | case ATOM_PPLL_INVALID: | 467 | case ATOM_PPLL_INVALID: |
474 | return; | 468 | return; |
475 | } | 469 | } |
470 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); | ||
471 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); | ||
476 | args.v3.ucEnable = enable; | 472 | args.v3.ucEnable = enable; |
477 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev)) | 473 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev)) |
478 | args.v3.ucEnable = ATOM_DISABLE; | 474 | args.v3.ucEnable = ATOM_DISABLE; |
@@ -482,22 +478,18 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, | |||
482 | switch (pll_id) { | 478 | switch (pll_id) { |
483 | case ATOM_PPLL1: | 479 | case ATOM_PPLL1: |
484 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; | 480 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; |
485 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); | ||
486 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); | ||
487 | break; | 481 | break; |
488 | case ATOM_PPLL2: | 482 | case ATOM_PPLL2: |
489 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; | 483 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; |
490 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); | ||
491 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); | ||
492 | break; | 484 | break; |
493 | case ATOM_DCPLL: | 485 | case ATOM_DCPLL: |
494 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; | 486 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; |
495 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(0); | ||
496 | args.v2.usSpreadSpectrumStep = cpu_to_le16(0); | ||
497 | break; | 487 | break; |
498 | case ATOM_PPLL_INVALID: | 488 | case ATOM_PPLL_INVALID: |
499 | return; | 489 | return; |
500 | } | 490 | } |
491 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); | ||
492 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); | ||
501 | args.v2.ucEnable = enable; | 493 | args.v2.ucEnable = enable; |
502 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev)) | 494 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev)) |
503 | args.v2.ucEnable = ATOM_DISABLE; | 495 | args.v2.ucEnable = ATOM_DISABLE; |
@@ -1539,7 +1531,11 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1539 | * crtc virtual pixel clock. | 1531 | * crtc virtual pixel clock. |
1540 | */ | 1532 | */ |
1541 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
1542 | if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) | 1534 | if (ASIC_IS_DCE5(rdev)) |
1535 | return ATOM_DCPLL; | ||
1536 | else if (ASIC_IS_DCE6(rdev)) | ||
1537 | return ATOM_PPLL0; | ||
1538 | else if (rdev->clock.dp_extclk) | ||
1543 | return ATOM_PPLL_INVALID; | 1539 | return ATOM_PPLL_INVALID; |
1544 | } | 1540 | } |
1545 | } | 1541 | } |
@@ -1628,7 +1624,7 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1628 | } | 1624 | } |
1629 | 1625 | ||
1630 | static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | 1626 | static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, |
1631 | struct drm_display_mode *mode, | 1627 | const struct drm_display_mode *mode, |
1632 | struct drm_display_mode *adjusted_mode) | 1628 | struct drm_display_mode *adjusted_mode) |
1633 | { | 1629 | { |
1634 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 1630 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 5131b3b0f7d2..7712cf5ab33b 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -22,6 +22,7 @@ | |||
22 | * | 22 | * |
23 | * Authors: Dave Airlie | 23 | * Authors: Dave Airlie |
24 | * Alex Deucher | 24 | * Alex Deucher |
25 | * Jerome Glisse | ||
25 | */ | 26 | */ |
26 | #include "drmP.h" | 27 | #include "drmP.h" |
27 | #include "radeon_drm.h" | 28 | #include "radeon_drm.h" |
@@ -608,7 +609,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
608 | } | 609 | } |
609 | 610 | ||
610 | void radeon_dp_set_link_config(struct drm_connector *connector, | 611 | void radeon_dp_set_link_config(struct drm_connector *connector, |
611 | struct drm_display_mode *mode) | 612 | const struct drm_display_mode *mode) |
612 | { | 613 | { |
613 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 614 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
614 | struct radeon_connector_atom_dig *dig_connector; | 615 | struct radeon_connector_atom_dig *dig_connector; |
@@ -654,7 +655,6 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, | |||
654 | ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, | 655 | ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, |
655 | link_status, DP_LINK_STATUS_SIZE, 100); | 656 | link_status, DP_LINK_STATUS_SIZE, 100); |
656 | if (ret <= 0) { | 657 | if (ret <= 0) { |
657 | DRM_ERROR("displayport link status failed\n"); | ||
658 | return false; | 658 | return false; |
659 | } | 659 | } |
660 | 660 | ||
@@ -833,8 +833,10 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) | |||
833 | else | 833 | else |
834 | mdelay(dp_info->rd_interval * 4); | 834 | mdelay(dp_info->rd_interval * 4); |
835 | 835 | ||
836 | if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) | 836 | if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { |
837 | DRM_ERROR("displayport link status failed\n"); | ||
837 | break; | 838 | break; |
839 | } | ||
838 | 840 | ||
839 | if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) { | 841 | if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) { |
840 | clock_recovery = true; | 842 | clock_recovery = true; |
@@ -896,8 +898,10 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) | |||
896 | else | 898 | else |
897 | mdelay(dp_info->rd_interval * 4); | 899 | mdelay(dp_info->rd_interval * 4); |
898 | 900 | ||
899 | if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) | 901 | if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { |
902 | DRM_ERROR("displayport link status failed\n"); | ||
900 | break; | 903 | break; |
904 | } | ||
901 | 905 | ||
902 | if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { | 906 | if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { |
903 | channel_eq = true; | 907 | channel_eq = true; |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 486ccdf4aacd..f9bc27fe269a 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -58,7 +58,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 60 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
61 | struct drm_display_mode *mode, | 61 | const struct drm_display_mode *mode, |
62 | struct drm_display_mode *adjusted_mode) | 62 | struct drm_display_mode *adjusted_mode) |
63 | { | 63 | { |
64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
@@ -1392,10 +1392,18 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1392 | case DRM_MODE_DPMS_ON: | 1392 | case DRM_MODE_DPMS_ON: |
1393 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1393 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
1394 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || | 1394 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || |
1395 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | 1395 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
1396 | if (ASIC_IS_DCE6(rdev)) { | ||
1397 | /* It seems we need to call ATOM_ENCODER_CMD_SETUP again | ||
1398 | * before reenabling encoder on DPMS ON, otherwise we never | ||
1399 | * get picture | ||
1400 | */ | ||
1401 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1402 | } | ||
1396 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1403 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1397 | else | 1404 | } else { |
1398 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1405 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1406 | } | ||
1399 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1407 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1400 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1408 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
1401 | atombios_set_edp_panel_power(connector, | 1409 | atombios_set_edp_panel_power(connector, |
@@ -2234,7 +2242,7 @@ radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) | |||
2234 | } | 2242 | } |
2235 | 2243 | ||
2236 | static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, | 2244 | static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, |
2237 | struct drm_display_mode *mode, | 2245 | const struct drm_display_mode *mode, |
2238 | struct drm_display_mode *adjusted_mode) | 2246 | struct drm_display_mode *adjusted_mode) |
2239 | { | 2247 | { |
2240 | return true; | 2248 | return true; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 7fb3d2e0434c..e585a3b947eb 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -99,6 +99,14 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | /** | ||
103 | * dce4_wait_for_vblank - vblank wait asic callback. | ||
104 | * | ||
105 | * @rdev: radeon_device pointer | ||
106 | * @crtc: crtc to wait for vblank on | ||
107 | * | ||
108 | * Wait for vblank on the requested crtc (evergreen+). | ||
109 | */ | ||
102 | void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) | 110 | void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) |
103 | { | 111 | { |
104 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | 112 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; |
@@ -118,18 +126,49 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) | |||
118 | } | 126 | } |
119 | } | 127 | } |
120 | 128 | ||
129 | /** | ||
130 | * radeon_irq_kms_pflip_irq_get - pre-pageflip callback. | ||
131 | * | ||
132 | * @rdev: radeon_device pointer | ||
133 | * @crtc: crtc to prepare for pageflip on | ||
134 | * | ||
135 | * Pre-pageflip callback (evergreen+). | ||
136 | * Enables the pageflip irq (vblank irq). | ||
137 | */ | ||
121 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) | 138 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) |
122 | { | 139 | { |
123 | /* enable the pflip int */ | 140 | /* enable the pflip int */ |
124 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | 141 | radeon_irq_kms_pflip_irq_get(rdev, crtc); |
125 | } | 142 | } |
126 | 143 | ||
144 | /** | ||
145 | * evergreen_post_page_flip - pos-pageflip callback. | ||
146 | * | ||
147 | * @rdev: radeon_device pointer | ||
148 | * @crtc: crtc to cleanup pageflip on | ||
149 | * | ||
150 | * Post-pageflip callback (evergreen+). | ||
151 | * Disables the pageflip irq (vblank irq). | ||
152 | */ | ||
127 | void evergreen_post_page_flip(struct radeon_device *rdev, int crtc) | 153 | void evergreen_post_page_flip(struct radeon_device *rdev, int crtc) |
128 | { | 154 | { |
129 | /* disable the pflip int */ | 155 | /* disable the pflip int */ |
130 | radeon_irq_kms_pflip_irq_put(rdev, crtc); | 156 | radeon_irq_kms_pflip_irq_put(rdev, crtc); |
131 | } | 157 | } |
132 | 158 | ||
159 | /** | ||
160 | * evergreen_page_flip - pageflip callback. | ||
161 | * | ||
162 | * @rdev: radeon_device pointer | ||
163 | * @crtc_id: crtc to cleanup pageflip on | ||
164 | * @crtc_base: new address of the crtc (GPU MC address) | ||
165 | * | ||
166 | * Does the actual pageflip (evergreen+). | ||
167 | * During vblank we take the crtc lock and wait for the update_pending | ||
168 | * bit to go high, when it does, we release the lock, and allow the | ||
169 | * double buffered update to take place. | ||
170 | * Returns the current update pending status. | ||
171 | */ | ||
133 | u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | 172 | u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
134 | { | 173 | { |
135 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 174 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
@@ -214,6 +253,15 @@ int sumo_get_temp(struct radeon_device *rdev) | |||
214 | return actual_temp * 1000; | 253 | return actual_temp * 1000; |
215 | } | 254 | } |
216 | 255 | ||
256 | /** | ||
257 | * sumo_pm_init_profile - Initialize power profiles callback. | ||
258 | * | ||
259 | * @rdev: radeon_device pointer | ||
260 | * | ||
261 | * Initialize the power states used in profile mode | ||
262 | * (sumo, trinity, SI). | ||
263 | * Used for profile mode only. | ||
264 | */ | ||
217 | void sumo_pm_init_profile(struct radeon_device *rdev) | 265 | void sumo_pm_init_profile(struct radeon_device *rdev) |
218 | { | 266 | { |
219 | int idx; | 267 | int idx; |
@@ -265,6 +313,14 @@ void sumo_pm_init_profile(struct radeon_device *rdev) | |||
265 | rdev->pm.power_state[idx].num_clock_modes - 1; | 313 | rdev->pm.power_state[idx].num_clock_modes - 1; |
266 | } | 314 | } |
267 | 315 | ||
316 | /** | ||
317 | * evergreen_pm_misc - set additional pm hw parameters callback. | ||
318 | * | ||
319 | * @rdev: radeon_device pointer | ||
320 | * | ||
321 | * Set non-clock parameters associated with a power state | ||
322 | * (voltage, etc.) (evergreen+). | ||
323 | */ | ||
268 | void evergreen_pm_misc(struct radeon_device *rdev) | 324 | void evergreen_pm_misc(struct radeon_device *rdev) |
269 | { | 325 | { |
270 | int req_ps_idx = rdev->pm.requested_power_state_index; | 326 | int req_ps_idx = rdev->pm.requested_power_state_index; |
@@ -292,6 +348,13 @@ void evergreen_pm_misc(struct radeon_device *rdev) | |||
292 | } | 348 | } |
293 | } | 349 | } |
294 | 350 | ||
351 | /** | ||
352 | * evergreen_pm_prepare - pre-power state change callback. | ||
353 | * | ||
354 | * @rdev: radeon_device pointer | ||
355 | * | ||
356 | * Prepare for a power state change (evergreen+). | ||
357 | */ | ||
295 | void evergreen_pm_prepare(struct radeon_device *rdev) | 358 | void evergreen_pm_prepare(struct radeon_device *rdev) |
296 | { | 359 | { |
297 | struct drm_device *ddev = rdev->ddev; | 360 | struct drm_device *ddev = rdev->ddev; |
@@ -310,6 +373,13 @@ void evergreen_pm_prepare(struct radeon_device *rdev) | |||
310 | } | 373 | } |
311 | } | 374 | } |
312 | 375 | ||
376 | /** | ||
377 | * evergreen_pm_finish - post-power state change callback. | ||
378 | * | ||
379 | * @rdev: radeon_device pointer | ||
380 | * | ||
381 | * Clean up after a power state change (evergreen+). | ||
382 | */ | ||
313 | void evergreen_pm_finish(struct radeon_device *rdev) | 383 | void evergreen_pm_finish(struct radeon_device *rdev) |
314 | { | 384 | { |
315 | struct drm_device *ddev = rdev->ddev; | 385 | struct drm_device *ddev = rdev->ddev; |
@@ -328,6 +398,15 @@ void evergreen_pm_finish(struct radeon_device *rdev) | |||
328 | } | 398 | } |
329 | } | 399 | } |
330 | 400 | ||
401 | /** | ||
402 | * evergreen_hpd_sense - hpd sense callback. | ||
403 | * | ||
404 | * @rdev: radeon_device pointer | ||
405 | * @hpd: hpd (hotplug detect) pin | ||
406 | * | ||
407 | * Checks if a digital monitor is connected (evergreen+). | ||
408 | * Returns true if connected, false if not connected. | ||
409 | */ | ||
331 | bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | 410 | bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
332 | { | 411 | { |
333 | bool connected = false; | 412 | bool connected = false; |
@@ -364,6 +443,14 @@ bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | |||
364 | return connected; | 443 | return connected; |
365 | } | 444 | } |
366 | 445 | ||
446 | /** | ||
447 | * evergreen_hpd_set_polarity - hpd set polarity callback. | ||
448 | * | ||
449 | * @rdev: radeon_device pointer | ||
450 | * @hpd: hpd (hotplug detect) pin | ||
451 | * | ||
452 | * Set the polarity of the hpd pin (evergreen+). | ||
453 | */ | ||
367 | void evergreen_hpd_set_polarity(struct radeon_device *rdev, | 454 | void evergreen_hpd_set_polarity(struct radeon_device *rdev, |
368 | enum radeon_hpd_id hpd) | 455 | enum radeon_hpd_id hpd) |
369 | { | 456 | { |
@@ -424,10 +511,19 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev, | |||
424 | } | 511 | } |
425 | } | 512 | } |
426 | 513 | ||
514 | /** | ||
515 | * evergreen_hpd_init - hpd setup callback. | ||
516 | * | ||
517 | * @rdev: radeon_device pointer | ||
518 | * | ||
519 | * Setup the hpd pins used by the card (evergreen+). | ||
520 | * Enable the pin, set the polarity, and enable the hpd interrupts. | ||
521 | */ | ||
427 | void evergreen_hpd_init(struct radeon_device *rdev) | 522 | void evergreen_hpd_init(struct radeon_device *rdev) |
428 | { | 523 | { |
429 | struct drm_device *dev = rdev->ddev; | 524 | struct drm_device *dev = rdev->ddev; |
430 | struct drm_connector *connector; | 525 | struct drm_connector *connector; |
526 | unsigned enabled = 0; | ||
431 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | | 527 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | |
432 | DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN; | 528 | DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN; |
433 | 529 | ||
@@ -436,73 +532,72 @@ void evergreen_hpd_init(struct radeon_device *rdev) | |||
436 | switch (radeon_connector->hpd.hpd) { | 532 | switch (radeon_connector->hpd.hpd) { |
437 | case RADEON_HPD_1: | 533 | case RADEON_HPD_1: |
438 | WREG32(DC_HPD1_CONTROL, tmp); | 534 | WREG32(DC_HPD1_CONTROL, tmp); |
439 | rdev->irq.hpd[0] = true; | ||
440 | break; | 535 | break; |
441 | case RADEON_HPD_2: | 536 | case RADEON_HPD_2: |
442 | WREG32(DC_HPD2_CONTROL, tmp); | 537 | WREG32(DC_HPD2_CONTROL, tmp); |
443 | rdev->irq.hpd[1] = true; | ||
444 | break; | 538 | break; |
445 | case RADEON_HPD_3: | 539 | case RADEON_HPD_3: |
446 | WREG32(DC_HPD3_CONTROL, tmp); | 540 | WREG32(DC_HPD3_CONTROL, tmp); |
447 | rdev->irq.hpd[2] = true; | ||
448 | break; | 541 | break; |
449 | case RADEON_HPD_4: | 542 | case RADEON_HPD_4: |
450 | WREG32(DC_HPD4_CONTROL, tmp); | 543 | WREG32(DC_HPD4_CONTROL, tmp); |
451 | rdev->irq.hpd[3] = true; | ||
452 | break; | 544 | break; |
453 | case RADEON_HPD_5: | 545 | case RADEON_HPD_5: |
454 | WREG32(DC_HPD5_CONTROL, tmp); | 546 | WREG32(DC_HPD5_CONTROL, tmp); |
455 | rdev->irq.hpd[4] = true; | ||
456 | break; | 547 | break; |
457 | case RADEON_HPD_6: | 548 | case RADEON_HPD_6: |
458 | WREG32(DC_HPD6_CONTROL, tmp); | 549 | WREG32(DC_HPD6_CONTROL, tmp); |
459 | rdev->irq.hpd[5] = true; | ||
460 | break; | 550 | break; |
461 | default: | 551 | default: |
462 | break; | 552 | break; |
463 | } | 553 | } |
464 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 554 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
555 | enabled |= 1 << radeon_connector->hpd.hpd; | ||
465 | } | 556 | } |
466 | if (rdev->irq.installed) | 557 | radeon_irq_kms_enable_hpd(rdev, enabled); |
467 | evergreen_irq_set(rdev); | ||
468 | } | 558 | } |
469 | 559 | ||
560 | /** | ||
561 | * evergreen_hpd_fini - hpd tear down callback. | ||
562 | * | ||
563 | * @rdev: radeon_device pointer | ||
564 | * | ||
565 | * Tear down the hpd pins used by the card (evergreen+). | ||
566 | * Disable the hpd interrupts. | ||
567 | */ | ||
470 | void evergreen_hpd_fini(struct radeon_device *rdev) | 568 | void evergreen_hpd_fini(struct radeon_device *rdev) |
471 | { | 569 | { |
472 | struct drm_device *dev = rdev->ddev; | 570 | struct drm_device *dev = rdev->ddev; |
473 | struct drm_connector *connector; | 571 | struct drm_connector *connector; |
572 | unsigned disabled = 0; | ||
474 | 573 | ||
475 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 574 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
476 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 575 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
477 | switch (radeon_connector->hpd.hpd) { | 576 | switch (radeon_connector->hpd.hpd) { |
478 | case RADEON_HPD_1: | 577 | case RADEON_HPD_1: |
479 | WREG32(DC_HPD1_CONTROL, 0); | 578 | WREG32(DC_HPD1_CONTROL, 0); |
480 | rdev->irq.hpd[0] = false; | ||
481 | break; | 579 | break; |
482 | case RADEON_HPD_2: | 580 | case RADEON_HPD_2: |
483 | WREG32(DC_HPD2_CONTROL, 0); | 581 | WREG32(DC_HPD2_CONTROL, 0); |
484 | rdev->irq.hpd[1] = false; | ||
485 | break; | 582 | break; |
486 | case RADEON_HPD_3: | 583 | case RADEON_HPD_3: |
487 | WREG32(DC_HPD3_CONTROL, 0); | 584 | WREG32(DC_HPD3_CONTROL, 0); |
488 | rdev->irq.hpd[2] = false; | ||
489 | break; | 585 | break; |
490 | case RADEON_HPD_4: | 586 | case RADEON_HPD_4: |
491 | WREG32(DC_HPD4_CONTROL, 0); | 587 | WREG32(DC_HPD4_CONTROL, 0); |
492 | rdev->irq.hpd[3] = false; | ||
493 | break; | 588 | break; |
494 | case RADEON_HPD_5: | 589 | case RADEON_HPD_5: |
495 | WREG32(DC_HPD5_CONTROL, 0); | 590 | WREG32(DC_HPD5_CONTROL, 0); |
496 | rdev->irq.hpd[4] = false; | ||
497 | break; | 591 | break; |
498 | case RADEON_HPD_6: | 592 | case RADEON_HPD_6: |
499 | WREG32(DC_HPD6_CONTROL, 0); | 593 | WREG32(DC_HPD6_CONTROL, 0); |
500 | rdev->irq.hpd[5] = false; | ||
501 | break; | 594 | break; |
502 | default: | 595 | default: |
503 | break; | 596 | break; |
504 | } | 597 | } |
598 | disabled |= 1 << radeon_connector->hpd.hpd; | ||
505 | } | 599 | } |
600 | radeon_irq_kms_disable_hpd(rdev, disabled); | ||
506 | } | 601 | } |
507 | 602 | ||
508 | /* watermark setup */ | 603 | /* watermark setup */ |
@@ -933,6 +1028,14 @@ static void evergreen_program_watermarks(struct radeon_device *rdev, | |||
933 | 1028 | ||
934 | } | 1029 | } |
935 | 1030 | ||
1031 | /** | ||
1032 | * evergreen_bandwidth_update - update display watermarks callback. | ||
1033 | * | ||
1034 | * @rdev: radeon_device pointer | ||
1035 | * | ||
1036 | * Update the display watermarks based on the requested mode(s) | ||
1037 | * (evergreen+). | ||
1038 | */ | ||
936 | void evergreen_bandwidth_update(struct radeon_device *rdev) | 1039 | void evergreen_bandwidth_update(struct radeon_device *rdev) |
937 | { | 1040 | { |
938 | struct drm_display_mode *mode0 = NULL; | 1041 | struct drm_display_mode *mode0 = NULL; |
@@ -956,6 +1059,15 @@ void evergreen_bandwidth_update(struct radeon_device *rdev) | |||
956 | } | 1059 | } |
957 | } | 1060 | } |
958 | 1061 | ||
1062 | /** | ||
1063 | * evergreen_mc_wait_for_idle - wait for MC idle callback. | ||
1064 | * | ||
1065 | * @rdev: radeon_device pointer | ||
1066 | * | ||
1067 | * Wait for the MC (memory controller) to be idle. | ||
1068 | * (evergreen+). | ||
1069 | * Returns 0 if the MC is idle, -1 if not. | ||
1070 | */ | ||
959 | int evergreen_mc_wait_for_idle(struct radeon_device *rdev) | 1071 | int evergreen_mc_wait_for_idle(struct radeon_device *rdev) |
960 | { | 1072 | { |
961 | unsigned i; | 1073 | unsigned i; |
@@ -1371,12 +1483,28 @@ void evergreen_mc_program(struct radeon_device *rdev) | |||
1371 | */ | 1483 | */ |
1372 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 1484 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
1373 | { | 1485 | { |
1374 | struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; | 1486 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
1487 | u32 next_rptr; | ||
1375 | 1488 | ||
1376 | /* set to DX10/11 mode */ | 1489 | /* set to DX10/11 mode */ |
1377 | radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); | 1490 | radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); |
1378 | radeon_ring_write(ring, 1); | 1491 | radeon_ring_write(ring, 1); |
1379 | /* FIXME: implement */ | 1492 | |
1493 | if (ring->rptr_save_reg) { | ||
1494 | next_rptr = ring->wptr + 3 + 4; | ||
1495 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1496 | radeon_ring_write(ring, ((ring->rptr_save_reg - | ||
1497 | PACKET3_SET_CONFIG_REG_START) >> 2)); | ||
1498 | radeon_ring_write(ring, next_rptr); | ||
1499 | } else if (rdev->wb.enabled) { | ||
1500 | next_rptr = ring->wptr + 5 + 4; | ||
1501 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3)); | ||
1502 | radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
1503 | radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18)); | ||
1504 | radeon_ring_write(ring, next_rptr); | ||
1505 | radeon_ring_write(ring, 0); | ||
1506 | } | ||
1507 | |||
1380 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 1508 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
1381 | radeon_ring_write(ring, | 1509 | radeon_ring_write(ring, |
1382 | #ifdef __BIG_ENDIAN | 1510 | #ifdef __BIG_ENDIAN |
@@ -2188,6 +2316,14 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2188 | RREG32(GRBM_STATUS_SE1)); | 2316 | RREG32(GRBM_STATUS_SE1)); |
2189 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2317 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2190 | RREG32(SRBM_STATUS)); | 2318 | RREG32(SRBM_STATUS)); |
2319 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | ||
2320 | RREG32(CP_STALLED_STAT1)); | ||
2321 | dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", | ||
2322 | RREG32(CP_STALLED_STAT2)); | ||
2323 | dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", | ||
2324 | RREG32(CP_BUSY_STAT)); | ||
2325 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | ||
2326 | RREG32(CP_STAT)); | ||
2191 | evergreen_mc_stop(rdev, &save); | 2327 | evergreen_mc_stop(rdev, &save); |
2192 | if (evergreen_mc_wait_for_idle(rdev)) { | 2328 | if (evergreen_mc_wait_for_idle(rdev)) { |
2193 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | 2329 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); |
@@ -2225,6 +2361,14 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2225 | RREG32(GRBM_STATUS_SE1)); | 2361 | RREG32(GRBM_STATUS_SE1)); |
2226 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2362 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2227 | RREG32(SRBM_STATUS)); | 2363 | RREG32(SRBM_STATUS)); |
2364 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | ||
2365 | RREG32(CP_STALLED_STAT1)); | ||
2366 | dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", | ||
2367 | RREG32(CP_STALLED_STAT2)); | ||
2368 | dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", | ||
2369 | RREG32(CP_BUSY_STAT)); | ||
2370 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | ||
2371 | RREG32(CP_STAT)); | ||
2228 | evergreen_mc_resume(rdev, &save); | 2372 | evergreen_mc_resume(rdev, &save); |
2229 | return 0; | 2373 | return 0; |
2230 | } | 2374 | } |
@@ -2348,20 +2492,20 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2348 | 2492 | ||
2349 | if (rdev->family >= CHIP_CAYMAN) { | 2493 | if (rdev->family >= CHIP_CAYMAN) { |
2350 | /* enable CP interrupts on all rings */ | 2494 | /* enable CP interrupts on all rings */ |
2351 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 2495 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
2352 | DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); | 2496 | DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); |
2353 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 2497 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
2354 | } | 2498 | } |
2355 | if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) { | 2499 | if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) { |
2356 | DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); | 2500 | DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); |
2357 | cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; | 2501 | cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; |
2358 | } | 2502 | } |
2359 | if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) { | 2503 | if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) { |
2360 | DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); | 2504 | DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); |
2361 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; | 2505 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; |
2362 | } | 2506 | } |
2363 | } else { | 2507 | } else { |
2364 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 2508 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
2365 | DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); | 2509 | DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); |
2366 | cp_int_cntl |= RB_INT_ENABLE; | 2510 | cp_int_cntl |= RB_INT_ENABLE; |
2367 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 2511 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
@@ -2369,32 +2513,32 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2369 | } | 2513 | } |
2370 | 2514 | ||
2371 | if (rdev->irq.crtc_vblank_int[0] || | 2515 | if (rdev->irq.crtc_vblank_int[0] || |
2372 | rdev->irq.pflip[0]) { | 2516 | atomic_read(&rdev->irq.pflip[0])) { |
2373 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 2517 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
2374 | crtc1 |= VBLANK_INT_MASK; | 2518 | crtc1 |= VBLANK_INT_MASK; |
2375 | } | 2519 | } |
2376 | if (rdev->irq.crtc_vblank_int[1] || | 2520 | if (rdev->irq.crtc_vblank_int[1] || |
2377 | rdev->irq.pflip[1]) { | 2521 | atomic_read(&rdev->irq.pflip[1])) { |
2378 | DRM_DEBUG("evergreen_irq_set: vblank 1\n"); | 2522 | DRM_DEBUG("evergreen_irq_set: vblank 1\n"); |
2379 | crtc2 |= VBLANK_INT_MASK; | 2523 | crtc2 |= VBLANK_INT_MASK; |
2380 | } | 2524 | } |
2381 | if (rdev->irq.crtc_vblank_int[2] || | 2525 | if (rdev->irq.crtc_vblank_int[2] || |
2382 | rdev->irq.pflip[2]) { | 2526 | atomic_read(&rdev->irq.pflip[2])) { |
2383 | DRM_DEBUG("evergreen_irq_set: vblank 2\n"); | 2527 | DRM_DEBUG("evergreen_irq_set: vblank 2\n"); |
2384 | crtc3 |= VBLANK_INT_MASK; | 2528 | crtc3 |= VBLANK_INT_MASK; |
2385 | } | 2529 | } |
2386 | if (rdev->irq.crtc_vblank_int[3] || | 2530 | if (rdev->irq.crtc_vblank_int[3] || |
2387 | rdev->irq.pflip[3]) { | 2531 | atomic_read(&rdev->irq.pflip[3])) { |
2388 | DRM_DEBUG("evergreen_irq_set: vblank 3\n"); | 2532 | DRM_DEBUG("evergreen_irq_set: vblank 3\n"); |
2389 | crtc4 |= VBLANK_INT_MASK; | 2533 | crtc4 |= VBLANK_INT_MASK; |
2390 | } | 2534 | } |
2391 | if (rdev->irq.crtc_vblank_int[4] || | 2535 | if (rdev->irq.crtc_vblank_int[4] || |
2392 | rdev->irq.pflip[4]) { | 2536 | atomic_read(&rdev->irq.pflip[4])) { |
2393 | DRM_DEBUG("evergreen_irq_set: vblank 4\n"); | 2537 | DRM_DEBUG("evergreen_irq_set: vblank 4\n"); |
2394 | crtc5 |= VBLANK_INT_MASK; | 2538 | crtc5 |= VBLANK_INT_MASK; |
2395 | } | 2539 | } |
2396 | if (rdev->irq.crtc_vblank_int[5] || | 2540 | if (rdev->irq.crtc_vblank_int[5] || |
2397 | rdev->irq.pflip[5]) { | 2541 | atomic_read(&rdev->irq.pflip[5])) { |
2398 | DRM_DEBUG("evergreen_irq_set: vblank 5\n"); | 2542 | DRM_DEBUG("evergreen_irq_set: vblank 5\n"); |
2399 | crtc6 |= VBLANK_INT_MASK; | 2543 | crtc6 |= VBLANK_INT_MASK; |
2400 | } | 2544 | } |
@@ -2676,7 +2820,6 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
2676 | u32 rptr; | 2820 | u32 rptr; |
2677 | u32 src_id, src_data; | 2821 | u32 src_id, src_data; |
2678 | u32 ring_index; | 2822 | u32 ring_index; |
2679 | unsigned long flags; | ||
2680 | bool queue_hotplug = false; | 2823 | bool queue_hotplug = false; |
2681 | bool queue_hdmi = false; | 2824 | bool queue_hdmi = false; |
2682 | 2825 | ||
@@ -2684,22 +2827,21 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
2684 | return IRQ_NONE; | 2827 | return IRQ_NONE; |
2685 | 2828 | ||
2686 | wptr = evergreen_get_ih_wptr(rdev); | 2829 | wptr = evergreen_get_ih_wptr(rdev); |
2830 | |||
2831 | restart_ih: | ||
2832 | /* is somebody else already processing irqs? */ | ||
2833 | if (atomic_xchg(&rdev->ih.lock, 1)) | ||
2834 | return IRQ_NONE; | ||
2835 | |||
2687 | rptr = rdev->ih.rptr; | 2836 | rptr = rdev->ih.rptr; |
2688 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 2837 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
2689 | 2838 | ||
2690 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
2691 | if (rptr == wptr) { | ||
2692 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2693 | return IRQ_NONE; | ||
2694 | } | ||
2695 | restart_ih: | ||
2696 | /* Order reading of wptr vs. reading of IH ring data */ | 2839 | /* Order reading of wptr vs. reading of IH ring data */ |
2697 | rmb(); | 2840 | rmb(); |
2698 | 2841 | ||
2699 | /* display interrupts */ | 2842 | /* display interrupts */ |
2700 | evergreen_irq_ack(rdev); | 2843 | evergreen_irq_ack(rdev); |
2701 | 2844 | ||
2702 | rdev->ih.wptr = wptr; | ||
2703 | while (rptr != wptr) { | 2845 | while (rptr != wptr) { |
2704 | /* wptr/rptr are in bytes! */ | 2846 | /* wptr/rptr are in bytes! */ |
2705 | ring_index = rptr / 4; | 2847 | ring_index = rptr / 4; |
@@ -2716,7 +2858,7 @@ restart_ih: | |||
2716 | rdev->pm.vblank_sync = true; | 2858 | rdev->pm.vblank_sync = true; |
2717 | wake_up(&rdev->irq.vblank_queue); | 2859 | wake_up(&rdev->irq.vblank_queue); |
2718 | } | 2860 | } |
2719 | if (rdev->irq.pflip[0]) | 2861 | if (atomic_read(&rdev->irq.pflip[0])) |
2720 | radeon_crtc_handle_flip(rdev, 0); | 2862 | radeon_crtc_handle_flip(rdev, 0); |
2721 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 2863 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; |
2722 | DRM_DEBUG("IH: D1 vblank\n"); | 2864 | DRM_DEBUG("IH: D1 vblank\n"); |
@@ -2742,7 +2884,7 @@ restart_ih: | |||
2742 | rdev->pm.vblank_sync = true; | 2884 | rdev->pm.vblank_sync = true; |
2743 | wake_up(&rdev->irq.vblank_queue); | 2885 | wake_up(&rdev->irq.vblank_queue); |
2744 | } | 2886 | } |
2745 | if (rdev->irq.pflip[1]) | 2887 | if (atomic_read(&rdev->irq.pflip[1])) |
2746 | radeon_crtc_handle_flip(rdev, 1); | 2888 | radeon_crtc_handle_flip(rdev, 1); |
2747 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | 2889 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; |
2748 | DRM_DEBUG("IH: D2 vblank\n"); | 2890 | DRM_DEBUG("IH: D2 vblank\n"); |
@@ -2768,7 +2910,7 @@ restart_ih: | |||
2768 | rdev->pm.vblank_sync = true; | 2910 | rdev->pm.vblank_sync = true; |
2769 | wake_up(&rdev->irq.vblank_queue); | 2911 | wake_up(&rdev->irq.vblank_queue); |
2770 | } | 2912 | } |
2771 | if (rdev->irq.pflip[2]) | 2913 | if (atomic_read(&rdev->irq.pflip[2])) |
2772 | radeon_crtc_handle_flip(rdev, 2); | 2914 | radeon_crtc_handle_flip(rdev, 2); |
2773 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | 2915 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; |
2774 | DRM_DEBUG("IH: D3 vblank\n"); | 2916 | DRM_DEBUG("IH: D3 vblank\n"); |
@@ -2794,7 +2936,7 @@ restart_ih: | |||
2794 | rdev->pm.vblank_sync = true; | 2936 | rdev->pm.vblank_sync = true; |
2795 | wake_up(&rdev->irq.vblank_queue); | 2937 | wake_up(&rdev->irq.vblank_queue); |
2796 | } | 2938 | } |
2797 | if (rdev->irq.pflip[3]) | 2939 | if (atomic_read(&rdev->irq.pflip[3])) |
2798 | radeon_crtc_handle_flip(rdev, 3); | 2940 | radeon_crtc_handle_flip(rdev, 3); |
2799 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | 2941 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; |
2800 | DRM_DEBUG("IH: D4 vblank\n"); | 2942 | DRM_DEBUG("IH: D4 vblank\n"); |
@@ -2820,7 +2962,7 @@ restart_ih: | |||
2820 | rdev->pm.vblank_sync = true; | 2962 | rdev->pm.vblank_sync = true; |
2821 | wake_up(&rdev->irq.vblank_queue); | 2963 | wake_up(&rdev->irq.vblank_queue); |
2822 | } | 2964 | } |
2823 | if (rdev->irq.pflip[4]) | 2965 | if (atomic_read(&rdev->irq.pflip[4])) |
2824 | radeon_crtc_handle_flip(rdev, 4); | 2966 | radeon_crtc_handle_flip(rdev, 4); |
2825 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | 2967 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; |
2826 | DRM_DEBUG("IH: D5 vblank\n"); | 2968 | DRM_DEBUG("IH: D5 vblank\n"); |
@@ -2846,7 +2988,7 @@ restart_ih: | |||
2846 | rdev->pm.vblank_sync = true; | 2988 | rdev->pm.vblank_sync = true; |
2847 | wake_up(&rdev->irq.vblank_queue); | 2989 | wake_up(&rdev->irq.vblank_queue); |
2848 | } | 2990 | } |
2849 | if (rdev->irq.pflip[5]) | 2991 | if (atomic_read(&rdev->irq.pflip[5])) |
2850 | radeon_crtc_handle_flip(rdev, 5); | 2992 | radeon_crtc_handle_flip(rdev, 5); |
2851 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | 2993 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; |
2852 | DRM_DEBUG("IH: D6 vblank\n"); | 2994 | DRM_DEBUG("IH: D6 vblank\n"); |
@@ -2986,7 +3128,6 @@ restart_ih: | |||
2986 | break; | 3128 | break; |
2987 | case 233: /* GUI IDLE */ | 3129 | case 233: /* GUI IDLE */ |
2988 | DRM_DEBUG("IH: GUI idle\n"); | 3130 | DRM_DEBUG("IH: GUI idle\n"); |
2989 | rdev->pm.gui_idle = true; | ||
2990 | wake_up(&rdev->irq.idle_queue); | 3131 | wake_up(&rdev->irq.idle_queue); |
2991 | break; | 3132 | break; |
2992 | default: | 3133 | default: |
@@ -2998,17 +3139,19 @@ restart_ih: | |||
2998 | rptr += 16; | 3139 | rptr += 16; |
2999 | rptr &= rdev->ih.ptr_mask; | 3140 | rptr &= rdev->ih.ptr_mask; |
3000 | } | 3141 | } |
3001 | /* make sure wptr hasn't changed while processing */ | ||
3002 | wptr = evergreen_get_ih_wptr(rdev); | ||
3003 | if (wptr != rdev->ih.wptr) | ||
3004 | goto restart_ih; | ||
3005 | if (queue_hotplug) | 3142 | if (queue_hotplug) |
3006 | schedule_work(&rdev->hotplug_work); | 3143 | schedule_work(&rdev->hotplug_work); |
3007 | if (queue_hdmi) | 3144 | if (queue_hdmi) |
3008 | schedule_work(&rdev->audio_work); | 3145 | schedule_work(&rdev->audio_work); |
3009 | rdev->ih.rptr = rptr; | 3146 | rdev->ih.rptr = rptr; |
3010 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3147 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3011 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3148 | atomic_set(&rdev->ih.lock, 0); |
3149 | |||
3150 | /* make sure wptr hasn't changed while processing */ | ||
3151 | wptr = evergreen_get_ih_wptr(rdev); | ||
3152 | if (wptr != rptr) | ||
3153 | goto restart_ih; | ||
3154 | |||
3012 | return IRQ_HANDLED; | 3155 | return IRQ_HANDLED; |
3013 | } | 3156 | } |
3014 | 3157 | ||
@@ -3096,13 +3239,11 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
3096 | if (r) | 3239 | if (r) |
3097 | return r; | 3240 | return r; |
3098 | 3241 | ||
3099 | r = radeon_ib_pool_start(rdev); | 3242 | r = radeon_ib_pool_init(rdev); |
3100 | if (r) | 3243 | if (r) { |
3101 | return r; | 3244 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
3102 | |||
3103 | r = radeon_ib_ring_tests(rdev); | ||
3104 | if (r) | ||
3105 | return r; | 3245 | return r; |
3246 | } | ||
3106 | 3247 | ||
3107 | r = r600_audio_init(rdev); | 3248 | r = r600_audio_init(rdev); |
3108 | if (r) { | 3249 | if (r) { |
@@ -3146,9 +3287,6 @@ int evergreen_suspend(struct radeon_device *rdev) | |||
3146 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 3287 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
3147 | 3288 | ||
3148 | r600_audio_fini(rdev); | 3289 | r600_audio_fini(rdev); |
3149 | /* FIXME: we should wait for ring to be empty */ | ||
3150 | radeon_ib_pool_suspend(rdev); | ||
3151 | r600_blit_suspend(rdev); | ||
3152 | r700_cp_stop(rdev); | 3290 | r700_cp_stop(rdev); |
3153 | ring->ready = false; | 3291 | ring->ready = false; |
3154 | evergreen_irq_suspend(rdev); | 3292 | evergreen_irq_suspend(rdev); |
@@ -3234,20 +3372,14 @@ int evergreen_init(struct radeon_device *rdev) | |||
3234 | if (r) | 3372 | if (r) |
3235 | return r; | 3373 | return r; |
3236 | 3374 | ||
3237 | r = radeon_ib_pool_init(rdev); | ||
3238 | rdev->accel_working = true; | 3375 | rdev->accel_working = true; |
3239 | if (r) { | ||
3240 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
3241 | rdev->accel_working = false; | ||
3242 | } | ||
3243 | |||
3244 | r = evergreen_startup(rdev); | 3376 | r = evergreen_startup(rdev); |
3245 | if (r) { | 3377 | if (r) { |
3246 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 3378 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
3247 | r700_cp_fini(rdev); | 3379 | r700_cp_fini(rdev); |
3248 | r600_irq_fini(rdev); | 3380 | r600_irq_fini(rdev); |
3249 | radeon_wb_fini(rdev); | 3381 | radeon_wb_fini(rdev); |
3250 | r100_ib_fini(rdev); | 3382 | radeon_ib_pool_fini(rdev); |
3251 | radeon_irq_kms_fini(rdev); | 3383 | radeon_irq_kms_fini(rdev); |
3252 | evergreen_pcie_gart_fini(rdev); | 3384 | evergreen_pcie_gart_fini(rdev); |
3253 | rdev->accel_working = false; | 3385 | rdev->accel_working = false; |
@@ -3274,7 +3406,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3274 | r700_cp_fini(rdev); | 3406 | r700_cp_fini(rdev); |
3275 | r600_irq_fini(rdev); | 3407 | r600_irq_fini(rdev); |
3276 | radeon_wb_fini(rdev); | 3408 | radeon_wb_fini(rdev); |
3277 | r100_ib_fini(rdev); | 3409 | radeon_ib_pool_fini(rdev); |
3278 | radeon_irq_kms_fini(rdev); | 3410 | radeon_irq_kms_fini(rdev); |
3279 | evergreen_pcie_gart_fini(rdev); | 3411 | evergreen_pcie_gart_fini(rdev); |
3280 | r600_vram_scratch_fini(rdev); | 3412 | r600_vram_scratch_fini(rdev); |
@@ -3289,7 +3421,8 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3289 | 3421 | ||
3290 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | 3422 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev) |
3291 | { | 3423 | { |
3292 | u32 link_width_cntl, speed_cntl; | 3424 | u32 link_width_cntl, speed_cntl, mask; |
3425 | int ret; | ||
3293 | 3426 | ||
3294 | if (radeon_pcie_gen2 == 0) | 3427 | if (radeon_pcie_gen2 == 0) |
3295 | return; | 3428 | return; |
@@ -3304,6 +3437,15 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | |||
3304 | if (ASIC_IS_X2(rdev)) | 3437 | if (ASIC_IS_X2(rdev)) |
3305 | return; | 3438 | return; |
3306 | 3439 | ||
3440 | ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); | ||
3441 | if (ret != 0) | ||
3442 | return; | ||
3443 | |||
3444 | if (!(mask & DRM_PCIE_SPEED_50)) | ||
3445 | return; | ||
3446 | |||
3447 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | ||
3448 | |||
3307 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | 3449 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); |
3308 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || | 3450 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || |
3309 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | 3451 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 1e96bd458cfd..89cb9feb5653 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
@@ -622,7 +622,8 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
622 | rdev->r600_blit.primitives.draw_auto = draw_auto; | 622 | rdev->r600_blit.primitives.draw_auto = draw_auto; |
623 | rdev->r600_blit.primitives.set_default_state = set_default_state; | 623 | rdev->r600_blit.primitives.set_default_state = set_default_state; |
624 | 624 | ||
625 | rdev->r600_blit.ring_size_common = 55; /* shaders + def state */ | 625 | rdev->r600_blit.ring_size_common = 8; /* sync semaphore */ |
626 | rdev->r600_blit.ring_size_common += 55; /* shaders + def state */ | ||
626 | rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ | 627 | rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ |
627 | rdev->r600_blit.ring_size_common += 5; /* done copy */ | 628 | rdev->r600_blit.ring_size_common += 5; /* done copy */ |
628 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ | 629 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ |
@@ -633,10 +634,6 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
633 | 634 | ||
634 | rdev->r600_blit.max_dim = 16384; | 635 | rdev->r600_blit.max_dim = 16384; |
635 | 636 | ||
636 | /* pin copy shader into vram if already initialized */ | ||
637 | if (rdev->r600_blit.shader_obj) | ||
638 | goto done; | ||
639 | |||
640 | rdev->r600_blit.state_offset = 0; | 637 | rdev->r600_blit.state_offset = 0; |
641 | 638 | ||
642 | if (rdev->family < CHIP_CAYMAN) | 639 | if (rdev->family < CHIP_CAYMAN) |
@@ -667,11 +664,26 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
667 | obj_size += cayman_ps_size * 4; | 664 | obj_size += cayman_ps_size * 4; |
668 | obj_size = ALIGN(obj_size, 256); | 665 | obj_size = ALIGN(obj_size, 256); |
669 | 666 | ||
670 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 667 | /* pin copy shader into vram if not already initialized */ |
671 | NULL, &rdev->r600_blit.shader_obj); | 668 | if (!rdev->r600_blit.shader_obj) { |
672 | if (r) { | 669 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, |
673 | DRM_ERROR("evergreen failed to allocate shader\n"); | 670 | RADEON_GEM_DOMAIN_VRAM, |
674 | return r; | 671 | NULL, &rdev->r600_blit.shader_obj); |
672 | if (r) { | ||
673 | DRM_ERROR("evergreen failed to allocate shader\n"); | ||
674 | return r; | ||
675 | } | ||
676 | |||
677 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
678 | if (unlikely(r != 0)) | ||
679 | return r; | ||
680 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
681 | &rdev->r600_blit.shader_gpu_addr); | ||
682 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
683 | if (r) { | ||
684 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
685 | return r; | ||
686 | } | ||
675 | } | 687 | } |
676 | 688 | ||
677 | DRM_DEBUG("evergreen blit allocated bo %08x vs %08x ps %08x\n", | 689 | DRM_DEBUG("evergreen blit allocated bo %08x vs %08x ps %08x\n", |
@@ -713,17 +725,6 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
713 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); | 725 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); |
714 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 726 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
715 | 727 | ||
716 | done: | ||
717 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
718 | if (unlikely(r != 0)) | ||
719 | return r; | ||
720 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
721 | &rdev->r600_blit.shader_gpu_addr); | ||
722 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
723 | if (r) { | ||
724 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
725 | return r; | ||
726 | } | ||
727 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); | 728 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
728 | return 0; | 729 | return 0; |
729 | } | 730 | } |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b50b15c70498..d3bd098e4e19 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -88,6 +88,10 @@ | |||
88 | #define CONFIG_MEMSIZE 0x5428 | 88 | #define CONFIG_MEMSIZE 0x5428 |
89 | 89 | ||
90 | #define CP_COHER_BASE 0x85F8 | 90 | #define CP_COHER_BASE 0x85F8 |
91 | #define CP_STALLED_STAT1 0x8674 | ||
92 | #define CP_STALLED_STAT2 0x8678 | ||
93 | #define CP_BUSY_STAT 0x867C | ||
94 | #define CP_STAT 0x8680 | ||
91 | #define CP_ME_CNTL 0x86D8 | 95 | #define CP_ME_CNTL 0x86D8 |
92 | #define CP_ME_HALT (1 << 28) | 96 | #define CP_ME_HALT (1 << 28) |
93 | #define CP_PFP_HALT (1 << 26) | 97 | #define CP_PFP_HALT (1 << 26) |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index b7bf18e40215..9945d86d9001 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -850,11 +850,20 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, | |||
850 | 850 | ||
851 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 851 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
852 | { | 852 | { |
853 | struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; | 853 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
854 | 854 | ||
855 | /* set to DX10/11 mode */ | 855 | /* set to DX10/11 mode */ |
856 | radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); | 856 | radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); |
857 | radeon_ring_write(ring, 1); | 857 | radeon_ring_write(ring, 1); |
858 | |||
859 | if (ring->rptr_save_reg) { | ||
860 | uint32_t next_rptr = ring->wptr + 3 + 4 + 8; | ||
861 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
862 | radeon_ring_write(ring, ((ring->rptr_save_reg - | ||
863 | PACKET3_SET_CONFIG_REG_START) >> 2)); | ||
864 | radeon_ring_write(ring, next_rptr); | ||
865 | } | ||
866 | |||
858 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 867 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
859 | radeon_ring_write(ring, | 868 | radeon_ring_write(ring, |
860 | #ifdef __BIG_ENDIAN | 869 | #ifdef __BIG_ENDIAN |
@@ -981,16 +990,41 @@ static int cayman_cp_start(struct radeon_device *rdev) | |||
981 | 990 | ||
982 | static void cayman_cp_fini(struct radeon_device *rdev) | 991 | static void cayman_cp_fini(struct radeon_device *rdev) |
983 | { | 992 | { |
993 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
984 | cayman_cp_enable(rdev, false); | 994 | cayman_cp_enable(rdev, false); |
985 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 995 | radeon_ring_fini(rdev, ring); |
996 | radeon_scratch_free(rdev, ring->rptr_save_reg); | ||
986 | } | 997 | } |
987 | 998 | ||
988 | int cayman_cp_resume(struct radeon_device *rdev) | 999 | int cayman_cp_resume(struct radeon_device *rdev) |
989 | { | 1000 | { |
1001 | static const int ridx[] = { | ||
1002 | RADEON_RING_TYPE_GFX_INDEX, | ||
1003 | CAYMAN_RING_TYPE_CP1_INDEX, | ||
1004 | CAYMAN_RING_TYPE_CP2_INDEX | ||
1005 | }; | ||
1006 | static const unsigned cp_rb_cntl[] = { | ||
1007 | CP_RB0_CNTL, | ||
1008 | CP_RB1_CNTL, | ||
1009 | CP_RB2_CNTL, | ||
1010 | }; | ||
1011 | static const unsigned cp_rb_rptr_addr[] = { | ||
1012 | CP_RB0_RPTR_ADDR, | ||
1013 | CP_RB1_RPTR_ADDR, | ||
1014 | CP_RB2_RPTR_ADDR | ||
1015 | }; | ||
1016 | static const unsigned cp_rb_rptr_addr_hi[] = { | ||
1017 | CP_RB0_RPTR_ADDR_HI, | ||
1018 | CP_RB1_RPTR_ADDR_HI, | ||
1019 | CP_RB2_RPTR_ADDR_HI | ||
1020 | }; | ||
1021 | static const unsigned cp_rb_base[] = { | ||
1022 | CP_RB0_BASE, | ||
1023 | CP_RB1_BASE, | ||
1024 | CP_RB2_BASE | ||
1025 | }; | ||
990 | struct radeon_ring *ring; | 1026 | struct radeon_ring *ring; |
991 | u32 tmp; | 1027 | int i, r; |
992 | u32 rb_bufsz; | ||
993 | int r; | ||
994 | 1028 | ||
995 | /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ | 1029 | /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ |
996 | WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | | 1030 | WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | |
@@ -1012,91 +1046,47 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1012 | 1046 | ||
1013 | WREG32(CP_DEBUG, (1 << 27)); | 1047 | WREG32(CP_DEBUG, (1 << 27)); |
1014 | 1048 | ||
1015 | /* ring 0 - compute and gfx */ | ||
1016 | /* Set ring buffer size */ | ||
1017 | ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
1018 | rb_bufsz = drm_order(ring->ring_size / 8); | ||
1019 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | ||
1020 | #ifdef __BIG_ENDIAN | ||
1021 | tmp |= BUF_SWAP_32BIT; | ||
1022 | #endif | ||
1023 | WREG32(CP_RB0_CNTL, tmp); | ||
1024 | |||
1025 | /* Initialize the ring buffer's read and write pointers */ | ||
1026 | WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); | ||
1027 | ring->wptr = 0; | ||
1028 | WREG32(CP_RB0_WPTR, ring->wptr); | ||
1029 | |||
1030 | /* set the wb address wether it's enabled or not */ | 1049 | /* set the wb address wether it's enabled or not */ |
1031 | WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); | ||
1032 | WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | ||
1033 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | 1050 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); |
1051 | WREG32(SCRATCH_UMSK, 0xff); | ||
1034 | 1052 | ||
1035 | if (rdev->wb.enabled) | 1053 | for (i = 0; i < 3; ++i) { |
1036 | WREG32(SCRATCH_UMSK, 0xff); | 1054 | uint32_t rb_cntl; |
1037 | else { | 1055 | uint64_t addr; |
1038 | tmp |= RB_NO_UPDATE; | ||
1039 | WREG32(SCRATCH_UMSK, 0); | ||
1040 | } | ||
1041 | 1056 | ||
1042 | mdelay(1); | 1057 | /* Set ring buffer size */ |
1043 | WREG32(CP_RB0_CNTL, tmp); | 1058 | ring = &rdev->ring[ridx[i]]; |
1044 | 1059 | rb_cntl = drm_order(ring->ring_size / 8); | |
1045 | WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); | 1060 | rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8; |
1046 | |||
1047 | ring->rptr = RREG32(CP_RB0_RPTR); | ||
1048 | |||
1049 | /* ring1 - compute only */ | ||
1050 | /* Set ring buffer size */ | ||
1051 | ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; | ||
1052 | rb_bufsz = drm_order(ring->ring_size / 8); | ||
1053 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | ||
1054 | #ifdef __BIG_ENDIAN | 1061 | #ifdef __BIG_ENDIAN |
1055 | tmp |= BUF_SWAP_32BIT; | 1062 | rb_cntl |= BUF_SWAP_32BIT; |
1056 | #endif | 1063 | #endif |
1057 | WREG32(CP_RB1_CNTL, tmp); | 1064 | WREG32(cp_rb_cntl[i], rb_cntl); |
1058 | |||
1059 | /* Initialize the ring buffer's read and write pointers */ | ||
1060 | WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); | ||
1061 | ring->wptr = 0; | ||
1062 | WREG32(CP_RB1_WPTR, ring->wptr); | ||
1063 | |||
1064 | /* set the wb address wether it's enabled or not */ | ||
1065 | WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); | ||
1066 | WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); | ||
1067 | |||
1068 | mdelay(1); | ||
1069 | WREG32(CP_RB1_CNTL, tmp); | ||
1070 | 1065 | ||
1071 | WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); | 1066 | /* set the wb address wether it's enabled or not */ |
1072 | 1067 | addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET; | |
1073 | ring->rptr = RREG32(CP_RB1_RPTR); | 1068 | WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC); |
1074 | 1069 | WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF); | |
1075 | /* ring2 - compute only */ | 1070 | } |
1076 | /* Set ring buffer size */ | ||
1077 | ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; | ||
1078 | rb_bufsz = drm_order(ring->ring_size / 8); | ||
1079 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | ||
1080 | #ifdef __BIG_ENDIAN | ||
1081 | tmp |= BUF_SWAP_32BIT; | ||
1082 | #endif | ||
1083 | WREG32(CP_RB2_CNTL, tmp); | ||
1084 | |||
1085 | /* Initialize the ring buffer's read and write pointers */ | ||
1086 | WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); | ||
1087 | ring->wptr = 0; | ||
1088 | WREG32(CP_RB2_WPTR, ring->wptr); | ||
1089 | 1071 | ||
1090 | /* set the wb address wether it's enabled or not */ | 1072 | /* set the rb base addr, this causes an internal reset of ALL rings */ |
1091 | WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); | 1073 | for (i = 0; i < 3; ++i) { |
1092 | WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF); | 1074 | ring = &rdev->ring[ridx[i]]; |
1075 | WREG32(cp_rb_base[i], ring->gpu_addr >> 8); | ||
1076 | } | ||
1093 | 1077 | ||
1094 | mdelay(1); | 1078 | for (i = 0; i < 3; ++i) { |
1095 | WREG32(CP_RB2_CNTL, tmp); | 1079 | /* Initialize the ring buffer's read and write pointers */ |
1080 | ring = &rdev->ring[ridx[i]]; | ||
1081 | WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA); | ||
1096 | 1082 | ||
1097 | WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); | 1083 | ring->rptr = ring->wptr = 0; |
1084 | WREG32(ring->rptr_reg, ring->rptr); | ||
1085 | WREG32(ring->wptr_reg, ring->wptr); | ||
1098 | 1086 | ||
1099 | ring->rptr = RREG32(CP_RB2_RPTR); | 1087 | mdelay(1); |
1088 | WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA); | ||
1089 | } | ||
1100 | 1090 | ||
1101 | /* start the rings */ | 1091 | /* start the rings */ |
1102 | cayman_cp_start(rdev); | 1092 | cayman_cp_start(rdev); |
@@ -1132,6 +1122,14 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1132 | RREG32(GRBM_STATUS_SE1)); | 1122 | RREG32(GRBM_STATUS_SE1)); |
1133 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1123 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
1134 | RREG32(SRBM_STATUS)); | 1124 | RREG32(SRBM_STATUS)); |
1125 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | ||
1126 | RREG32(CP_STALLED_STAT1)); | ||
1127 | dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", | ||
1128 | RREG32(CP_STALLED_STAT2)); | ||
1129 | dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", | ||
1130 | RREG32(CP_BUSY_STAT)); | ||
1131 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | ||
1132 | RREG32(CP_STAT)); | ||
1135 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", | 1133 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", |
1136 | RREG32(0x14F8)); | 1134 | RREG32(0x14F8)); |
1137 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", | 1135 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", |
@@ -1180,6 +1178,14 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1180 | RREG32(GRBM_STATUS_SE1)); | 1178 | RREG32(GRBM_STATUS_SE1)); |
1181 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1179 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
1182 | RREG32(SRBM_STATUS)); | 1180 | RREG32(SRBM_STATUS)); |
1181 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | ||
1182 | RREG32(CP_STALLED_STAT1)); | ||
1183 | dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", | ||
1184 | RREG32(CP_STALLED_STAT2)); | ||
1185 | dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", | ||
1186 | RREG32(CP_BUSY_STAT)); | ||
1187 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | ||
1188 | RREG32(CP_STAT)); | ||
1183 | evergreen_mc_resume(rdev, &save); | 1189 | evergreen_mc_resume(rdev, &save); |
1184 | return 0; | 1190 | return 0; |
1185 | } | 1191 | } |
@@ -1291,17 +1297,17 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1291 | if (r) | 1297 | if (r) |
1292 | return r; | 1298 | return r; |
1293 | 1299 | ||
1294 | r = radeon_ib_pool_start(rdev); | 1300 | r = radeon_ib_pool_init(rdev); |
1295 | if (r) | 1301 | if (r) { |
1296 | return r; | 1302 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
1297 | |||
1298 | r = radeon_ib_ring_tests(rdev); | ||
1299 | if (r) | ||
1300 | return r; | 1303 | return r; |
1304 | } | ||
1301 | 1305 | ||
1302 | r = radeon_vm_manager_start(rdev); | 1306 | r = radeon_vm_manager_init(rdev); |
1303 | if (r) | 1307 | if (r) { |
1308 | dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); | ||
1304 | return r; | 1309 | return r; |
1310 | } | ||
1305 | 1311 | ||
1306 | r = r600_audio_init(rdev); | 1312 | r = r600_audio_init(rdev); |
1307 | if (r) | 1313 | if (r) |
@@ -1334,10 +1340,6 @@ int cayman_resume(struct radeon_device *rdev) | |||
1334 | int cayman_suspend(struct radeon_device *rdev) | 1340 | int cayman_suspend(struct radeon_device *rdev) |
1335 | { | 1341 | { |
1336 | r600_audio_fini(rdev); | 1342 | r600_audio_fini(rdev); |
1337 | /* FIXME: we should wait for ring to be empty */ | ||
1338 | radeon_ib_pool_suspend(rdev); | ||
1339 | radeon_vm_manager_suspend(rdev); | ||
1340 | r600_blit_suspend(rdev); | ||
1341 | cayman_cp_enable(rdev, false); | 1343 | cayman_cp_enable(rdev, false); |
1342 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 1344 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
1343 | evergreen_irq_suspend(rdev); | 1345 | evergreen_irq_suspend(rdev); |
@@ -1413,17 +1415,7 @@ int cayman_init(struct radeon_device *rdev) | |||
1413 | if (r) | 1415 | if (r) |
1414 | return r; | 1416 | return r; |
1415 | 1417 | ||
1416 | r = radeon_ib_pool_init(rdev); | ||
1417 | rdev->accel_working = true; | 1418 | rdev->accel_working = true; |
1418 | if (r) { | ||
1419 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
1420 | rdev->accel_working = false; | ||
1421 | } | ||
1422 | r = radeon_vm_manager_init(rdev); | ||
1423 | if (r) { | ||
1424 | dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); | ||
1425 | } | ||
1426 | |||
1427 | r = cayman_startup(rdev); | 1419 | r = cayman_startup(rdev); |
1428 | if (r) { | 1420 | if (r) { |
1429 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 1421 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
@@ -1432,7 +1424,7 @@ int cayman_init(struct radeon_device *rdev) | |||
1432 | if (rdev->flags & RADEON_IS_IGP) | 1424 | if (rdev->flags & RADEON_IS_IGP) |
1433 | si_rlc_fini(rdev); | 1425 | si_rlc_fini(rdev); |
1434 | radeon_wb_fini(rdev); | 1426 | radeon_wb_fini(rdev); |
1435 | r100_ib_fini(rdev); | 1427 | radeon_ib_pool_fini(rdev); |
1436 | radeon_vm_manager_fini(rdev); | 1428 | radeon_vm_manager_fini(rdev); |
1437 | radeon_irq_kms_fini(rdev); | 1429 | radeon_irq_kms_fini(rdev); |
1438 | cayman_pcie_gart_fini(rdev); | 1430 | cayman_pcie_gart_fini(rdev); |
@@ -1463,7 +1455,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
1463 | si_rlc_fini(rdev); | 1455 | si_rlc_fini(rdev); |
1464 | radeon_wb_fini(rdev); | 1456 | radeon_wb_fini(rdev); |
1465 | radeon_vm_manager_fini(rdev); | 1457 | radeon_vm_manager_fini(rdev); |
1466 | r100_ib_fini(rdev); | 1458 | radeon_ib_pool_fini(rdev); |
1467 | radeon_irq_kms_fini(rdev); | 1459 | radeon_irq_kms_fini(rdev); |
1468 | cayman_pcie_gart_fini(rdev); | 1460 | cayman_pcie_gart_fini(rdev); |
1469 | r600_vram_scratch_fini(rdev); | 1461 | r600_vram_scratch_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index a0b98066e207..870db340d377 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
@@ -236,6 +236,10 @@ | |||
236 | #define CP_SEM_WAIT_TIMER 0x85BC | 236 | #define CP_SEM_WAIT_TIMER 0x85BC |
237 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 | 237 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 |
238 | #define CP_COHER_CNTL2 0x85E8 | 238 | #define CP_COHER_CNTL2 0x85E8 |
239 | #define CP_STALLED_STAT1 0x8674 | ||
240 | #define CP_STALLED_STAT2 0x8678 | ||
241 | #define CP_BUSY_STAT 0x867C | ||
242 | #define CP_STAT 0x8680 | ||
239 | #define CP_ME_CNTL 0x86D8 | 243 | #define CP_ME_CNTL 0x86D8 |
240 | #define CP_ME_HALT (1 << 28) | 244 | #define CP_ME_HALT (1 << 28) |
241 | #define CP_PFP_HALT (1 << 26) | 245 | #define CP_PFP_HALT (1 << 26) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index fb44e7e49083..8acb34fd3fd5 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -65,6 +65,19 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
65 | 65 | ||
66 | #include "r100_track.h" | 66 | #include "r100_track.h" |
67 | 67 | ||
68 | /* This files gather functions specifics to: | ||
69 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | ||
70 | * and others in some cases. | ||
71 | */ | ||
72 | |||
73 | /** | ||
74 | * r100_wait_for_vblank - vblank wait asic callback. | ||
75 | * | ||
76 | * @rdev: radeon_device pointer | ||
77 | * @crtc: crtc to wait for vblank on | ||
78 | * | ||
79 | * Wait for vblank on the requested crtc (r1xx-r4xx). | ||
80 | */ | ||
68 | void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) | 81 | void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) |
69 | { | 82 | { |
70 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | 83 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; |
@@ -99,128 +112,49 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) | |||
99 | } | 112 | } |
100 | } | 113 | } |
101 | 114 | ||
102 | /* This files gather functions specifics to: | 115 | /** |
103 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 116 | * r100_pre_page_flip - pre-pageflip callback. |
117 | * | ||
118 | * @rdev: radeon_device pointer | ||
119 | * @crtc: crtc to prepare for pageflip on | ||
120 | * | ||
121 | * Pre-pageflip callback (r1xx-r4xx). | ||
122 | * Enables the pageflip irq (vblank irq). | ||
104 | */ | 123 | */ |
105 | |||
106 | int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | ||
107 | struct radeon_cs_packet *pkt, | ||
108 | unsigned idx, | ||
109 | unsigned reg) | ||
110 | { | ||
111 | int r; | ||
112 | u32 tile_flags = 0; | ||
113 | u32 tmp; | ||
114 | struct radeon_cs_reloc *reloc; | ||
115 | u32 value; | ||
116 | |||
117 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
118 | if (r) { | ||
119 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
120 | idx, reg); | ||
121 | r100_cs_dump_packet(p, pkt); | ||
122 | return r; | ||
123 | } | ||
124 | |||
125 | value = radeon_get_ib_value(p, idx); | ||
126 | tmp = value & 0x003fffff; | ||
127 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); | ||
128 | |||
129 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | ||
130 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
131 | tile_flags |= RADEON_DST_TILE_MACRO; | ||
132 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
133 | if (reg == RADEON_SRC_PITCH_OFFSET) { | ||
134 | DRM_ERROR("Cannot src blit from microtiled surface\n"); | ||
135 | r100_cs_dump_packet(p, pkt); | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | tile_flags |= RADEON_DST_TILE_MICRO; | ||
139 | } | ||
140 | |||
141 | tmp |= tile_flags; | ||
142 | p->ib.ptr[idx] = (value & 0x3fc00000) | tmp; | ||
143 | } else | ||
144 | p->ib.ptr[idx] = (value & 0xffc00000) | tmp; | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, | ||
149 | struct radeon_cs_packet *pkt, | ||
150 | int idx) | ||
151 | { | ||
152 | unsigned c, i; | ||
153 | struct radeon_cs_reloc *reloc; | ||
154 | struct r100_cs_track *track; | ||
155 | int r = 0; | ||
156 | volatile uint32_t *ib; | ||
157 | u32 idx_value; | ||
158 | |||
159 | ib = p->ib.ptr; | ||
160 | track = (struct r100_cs_track *)p->track; | ||
161 | c = radeon_get_ib_value(p, idx++) & 0x1F; | ||
162 | if (c > 16) { | ||
163 | DRM_ERROR("Only 16 vertex buffers are allowed %d\n", | ||
164 | pkt->opcode); | ||
165 | r100_cs_dump_packet(p, pkt); | ||
166 | return -EINVAL; | ||
167 | } | ||
168 | track->num_arrays = c; | ||
169 | for (i = 0; i < (c - 1); i+=2, idx+=3) { | ||
170 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
171 | if (r) { | ||
172 | DRM_ERROR("No reloc for packet3 %d\n", | ||
173 | pkt->opcode); | ||
174 | r100_cs_dump_packet(p, pkt); | ||
175 | return r; | ||
176 | } | ||
177 | idx_value = radeon_get_ib_value(p, idx); | ||
178 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); | ||
179 | |||
180 | track->arrays[i + 0].esize = idx_value >> 8; | ||
181 | track->arrays[i + 0].robj = reloc->robj; | ||
182 | track->arrays[i + 0].esize &= 0x7F; | ||
183 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
184 | if (r) { | ||
185 | DRM_ERROR("No reloc for packet3 %d\n", | ||
186 | pkt->opcode); | ||
187 | r100_cs_dump_packet(p, pkt); | ||
188 | return r; | ||
189 | } | ||
190 | ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); | ||
191 | track->arrays[i + 1].robj = reloc->robj; | ||
192 | track->arrays[i + 1].esize = idx_value >> 24; | ||
193 | track->arrays[i + 1].esize &= 0x7F; | ||
194 | } | ||
195 | if (c & 1) { | ||
196 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
197 | if (r) { | ||
198 | DRM_ERROR("No reloc for packet3 %d\n", | ||
199 | pkt->opcode); | ||
200 | r100_cs_dump_packet(p, pkt); | ||
201 | return r; | ||
202 | } | ||
203 | idx_value = radeon_get_ib_value(p, idx); | ||
204 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); | ||
205 | track->arrays[i + 0].robj = reloc->robj; | ||
206 | track->arrays[i + 0].esize = idx_value >> 8; | ||
207 | track->arrays[i + 0].esize &= 0x7F; | ||
208 | } | ||
209 | return r; | ||
210 | } | ||
211 | |||
212 | void r100_pre_page_flip(struct radeon_device *rdev, int crtc) | 124 | void r100_pre_page_flip(struct radeon_device *rdev, int crtc) |
213 | { | 125 | { |
214 | /* enable the pflip int */ | 126 | /* enable the pflip int */ |
215 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | 127 | radeon_irq_kms_pflip_irq_get(rdev, crtc); |
216 | } | 128 | } |
217 | 129 | ||
130 | /** | ||
131 | * r100_post_page_flip - pos-pageflip callback. | ||
132 | * | ||
133 | * @rdev: radeon_device pointer | ||
134 | * @crtc: crtc to cleanup pageflip on | ||
135 | * | ||
136 | * Post-pageflip callback (r1xx-r4xx). | ||
137 | * Disables the pageflip irq (vblank irq). | ||
138 | */ | ||
218 | void r100_post_page_flip(struct radeon_device *rdev, int crtc) | 139 | void r100_post_page_flip(struct radeon_device *rdev, int crtc) |
219 | { | 140 | { |
220 | /* disable the pflip int */ | 141 | /* disable the pflip int */ |
221 | radeon_irq_kms_pflip_irq_put(rdev, crtc); | 142 | radeon_irq_kms_pflip_irq_put(rdev, crtc); |
222 | } | 143 | } |
223 | 144 | ||
145 | /** | ||
146 | * r100_page_flip - pageflip callback. | ||
147 | * | ||
148 | * @rdev: radeon_device pointer | ||
149 | * @crtc_id: crtc to cleanup pageflip on | ||
150 | * @crtc_base: new address of the crtc (GPU MC address) | ||
151 | * | ||
152 | * Does the actual pageflip (r1xx-r4xx). | ||
153 | * During vblank we take the crtc lock and wait for the update_pending | ||
154 | * bit to go high, when it does, we release the lock, and allow the | ||
155 | * double buffered update to take place. | ||
156 | * Returns the current update pending status. | ||
157 | */ | ||
224 | u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | 158 | u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
225 | { | 159 | { |
226 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 160 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
@@ -247,6 +181,15 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
247 | return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET; | 181 | return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET; |
248 | } | 182 | } |
249 | 183 | ||
184 | /** | ||
185 | * r100_pm_get_dynpm_state - look up dynpm power state callback. | ||
186 | * | ||
187 | * @rdev: radeon_device pointer | ||
188 | * | ||
189 | * Look up the optimal power state based on the | ||
190 | * current state of the GPU (r1xx-r5xx). | ||
191 | * Used for dynpm only. | ||
192 | */ | ||
250 | void r100_pm_get_dynpm_state(struct radeon_device *rdev) | 193 | void r100_pm_get_dynpm_state(struct radeon_device *rdev) |
251 | { | 194 | { |
252 | int i; | 195 | int i; |
@@ -329,6 +272,15 @@ void r100_pm_get_dynpm_state(struct radeon_device *rdev) | |||
329 | pcie_lanes); | 272 | pcie_lanes); |
330 | } | 273 | } |
331 | 274 | ||
275 | /** | ||
276 | * r100_pm_init_profile - Initialize power profiles callback. | ||
277 | * | ||
278 | * @rdev: radeon_device pointer | ||
279 | * | ||
280 | * Initialize the power states used in profile mode | ||
281 | * (r1xx-r3xx). | ||
282 | * Used for profile mode only. | ||
283 | */ | ||
332 | void r100_pm_init_profile(struct radeon_device *rdev) | 284 | void r100_pm_init_profile(struct radeon_device *rdev) |
333 | { | 285 | { |
334 | /* default */ | 286 | /* default */ |
@@ -368,6 +320,14 @@ void r100_pm_init_profile(struct radeon_device *rdev) | |||
368 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; | 320 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; |
369 | } | 321 | } |
370 | 322 | ||
323 | /** | ||
324 | * r100_pm_misc - set additional pm hw parameters callback. | ||
325 | * | ||
326 | * @rdev: radeon_device pointer | ||
327 | * | ||
328 | * Set non-clock parameters associated with a power state | ||
329 | * (voltage, pcie lanes, etc.) (r1xx-r4xx). | ||
330 | */ | ||
371 | void r100_pm_misc(struct radeon_device *rdev) | 331 | void r100_pm_misc(struct radeon_device *rdev) |
372 | { | 332 | { |
373 | int requested_index = rdev->pm.requested_power_state_index; | 333 | int requested_index = rdev->pm.requested_power_state_index; |
@@ -459,6 +419,13 @@ void r100_pm_misc(struct radeon_device *rdev) | |||
459 | } | 419 | } |
460 | } | 420 | } |
461 | 421 | ||
422 | /** | ||
423 | * r100_pm_prepare - pre-power state change callback. | ||
424 | * | ||
425 | * @rdev: radeon_device pointer | ||
426 | * | ||
427 | * Prepare for a power state change (r1xx-r4xx). | ||
428 | */ | ||
462 | void r100_pm_prepare(struct radeon_device *rdev) | 429 | void r100_pm_prepare(struct radeon_device *rdev) |
463 | { | 430 | { |
464 | struct drm_device *ddev = rdev->ddev; | 431 | struct drm_device *ddev = rdev->ddev; |
@@ -483,6 +450,13 @@ void r100_pm_prepare(struct radeon_device *rdev) | |||
483 | } | 450 | } |
484 | } | 451 | } |
485 | 452 | ||
453 | /** | ||
454 | * r100_pm_finish - post-power state change callback. | ||
455 | * | ||
456 | * @rdev: radeon_device pointer | ||
457 | * | ||
458 | * Clean up after a power state change (r1xx-r4xx). | ||
459 | */ | ||
486 | void r100_pm_finish(struct radeon_device *rdev) | 460 | void r100_pm_finish(struct radeon_device *rdev) |
487 | { | 461 | { |
488 | struct drm_device *ddev = rdev->ddev; | 462 | struct drm_device *ddev = rdev->ddev; |
@@ -507,6 +481,14 @@ void r100_pm_finish(struct radeon_device *rdev) | |||
507 | } | 481 | } |
508 | } | 482 | } |
509 | 483 | ||
484 | /** | ||
485 | * r100_gui_idle - gui idle callback. | ||
486 | * | ||
487 | * @rdev: radeon_device pointer | ||
488 | * | ||
489 | * Check of the GUI (2D/3D engines) are idle (r1xx-r5xx). | ||
490 | * Returns true if idle, false if not. | ||
491 | */ | ||
510 | bool r100_gui_idle(struct radeon_device *rdev) | 492 | bool r100_gui_idle(struct radeon_device *rdev) |
511 | { | 493 | { |
512 | if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) | 494 | if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) |
@@ -516,6 +498,15 @@ bool r100_gui_idle(struct radeon_device *rdev) | |||
516 | } | 498 | } |
517 | 499 | ||
518 | /* hpd for digital panel detect/disconnect */ | 500 | /* hpd for digital panel detect/disconnect */ |
501 | /** | ||
502 | * r100_hpd_sense - hpd sense callback. | ||
503 | * | ||
504 | * @rdev: radeon_device pointer | ||
505 | * @hpd: hpd (hotplug detect) pin | ||
506 | * | ||
507 | * Checks if a digital monitor is connected (r1xx-r4xx). | ||
508 | * Returns true if connected, false if not connected. | ||
509 | */ | ||
519 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | 510 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
520 | { | 511 | { |
521 | bool connected = false; | 512 | bool connected = false; |
@@ -535,6 +526,14 @@ bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | |||
535 | return connected; | 526 | return connected; |
536 | } | 527 | } |
537 | 528 | ||
529 | /** | ||
530 | * r100_hpd_set_polarity - hpd set polarity callback. | ||
531 | * | ||
532 | * @rdev: radeon_device pointer | ||
533 | * @hpd: hpd (hotplug detect) pin | ||
534 | * | ||
535 | * Set the polarity of the hpd pin (r1xx-r4xx). | ||
536 | */ | ||
538 | void r100_hpd_set_polarity(struct radeon_device *rdev, | 537 | void r100_hpd_set_polarity(struct radeon_device *rdev, |
539 | enum radeon_hpd_id hpd) | 538 | enum radeon_hpd_id hpd) |
540 | { | 539 | { |
@@ -563,47 +562,47 @@ void r100_hpd_set_polarity(struct radeon_device *rdev, | |||
563 | } | 562 | } |
564 | } | 563 | } |
565 | 564 | ||
565 | /** | ||
566 | * r100_hpd_init - hpd setup callback. | ||
567 | * | ||
568 | * @rdev: radeon_device pointer | ||
569 | * | ||
570 | * Setup the hpd pins used by the card (r1xx-r4xx). | ||
571 | * Set the polarity, and enable the hpd interrupts. | ||
572 | */ | ||
566 | void r100_hpd_init(struct radeon_device *rdev) | 573 | void r100_hpd_init(struct radeon_device *rdev) |
567 | { | 574 | { |
568 | struct drm_device *dev = rdev->ddev; | 575 | struct drm_device *dev = rdev->ddev; |
569 | struct drm_connector *connector; | 576 | struct drm_connector *connector; |
577 | unsigned enable = 0; | ||
570 | 578 | ||
571 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 579 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
572 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 580 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
573 | switch (radeon_connector->hpd.hpd) { | 581 | enable |= 1 << radeon_connector->hpd.hpd; |
574 | case RADEON_HPD_1: | ||
575 | rdev->irq.hpd[0] = true; | ||
576 | break; | ||
577 | case RADEON_HPD_2: | ||
578 | rdev->irq.hpd[1] = true; | ||
579 | break; | ||
580 | default: | ||
581 | break; | ||
582 | } | ||
583 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 582 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
584 | } | 583 | } |
585 | if (rdev->irq.installed) | 584 | radeon_irq_kms_enable_hpd(rdev, enable); |
586 | r100_irq_set(rdev); | ||
587 | } | 585 | } |
588 | 586 | ||
587 | /** | ||
588 | * r100_hpd_fini - hpd tear down callback. | ||
589 | * | ||
590 | * @rdev: radeon_device pointer | ||
591 | * | ||
592 | * Tear down the hpd pins used by the card (r1xx-r4xx). | ||
593 | * Disable the hpd interrupts. | ||
594 | */ | ||
589 | void r100_hpd_fini(struct radeon_device *rdev) | 595 | void r100_hpd_fini(struct radeon_device *rdev) |
590 | { | 596 | { |
591 | struct drm_device *dev = rdev->ddev; | 597 | struct drm_device *dev = rdev->ddev; |
592 | struct drm_connector *connector; | 598 | struct drm_connector *connector; |
599 | unsigned disable = 0; | ||
593 | 600 | ||
594 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 601 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
595 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 602 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
596 | switch (radeon_connector->hpd.hpd) { | 603 | disable |= 1 << radeon_connector->hpd.hpd; |
597 | case RADEON_HPD_1: | ||
598 | rdev->irq.hpd[0] = false; | ||
599 | break; | ||
600 | case RADEON_HPD_2: | ||
601 | rdev->irq.hpd[1] = false; | ||
602 | break; | ||
603 | default: | ||
604 | break; | ||
605 | } | ||
606 | } | 604 | } |
605 | radeon_irq_kms_disable_hpd(rdev, disable); | ||
607 | } | 606 | } |
608 | 607 | ||
609 | /* | 608 | /* |
@@ -635,15 +634,6 @@ int r100_pci_gart_init(struct radeon_device *rdev) | |||
635 | return radeon_gart_table_ram_alloc(rdev); | 634 | return radeon_gart_table_ram_alloc(rdev); |
636 | } | 635 | } |
637 | 636 | ||
638 | /* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ | ||
639 | void r100_enable_bm(struct radeon_device *rdev) | ||
640 | { | ||
641 | uint32_t tmp; | ||
642 | /* Enable bus mastering */ | ||
643 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
644 | WREG32(RADEON_BUS_CNTL, tmp); | ||
645 | } | ||
646 | |||
647 | int r100_pci_gart_enable(struct radeon_device *rdev) | 637 | int r100_pci_gart_enable(struct radeon_device *rdev) |
648 | { | 638 | { |
649 | uint32_t tmp; | 639 | uint32_t tmp; |
@@ -705,18 +695,18 @@ int r100_irq_set(struct radeon_device *rdev) | |||
705 | WREG32(R_000040_GEN_INT_CNTL, 0); | 695 | WREG32(R_000040_GEN_INT_CNTL, 0); |
706 | return -EINVAL; | 696 | return -EINVAL; |
707 | } | 697 | } |
708 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 698 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
709 | tmp |= RADEON_SW_INT_ENABLE; | 699 | tmp |= RADEON_SW_INT_ENABLE; |
710 | } | 700 | } |
711 | if (rdev->irq.gui_idle) { | 701 | if (rdev->irq.gui_idle) { |
712 | tmp |= RADEON_GUI_IDLE_MASK; | 702 | tmp |= RADEON_GUI_IDLE_MASK; |
713 | } | 703 | } |
714 | if (rdev->irq.crtc_vblank_int[0] || | 704 | if (rdev->irq.crtc_vblank_int[0] || |
715 | rdev->irq.pflip[0]) { | 705 | atomic_read(&rdev->irq.pflip[0])) { |
716 | tmp |= RADEON_CRTC_VBLANK_MASK; | 706 | tmp |= RADEON_CRTC_VBLANK_MASK; |
717 | } | 707 | } |
718 | if (rdev->irq.crtc_vblank_int[1] || | 708 | if (rdev->irq.crtc_vblank_int[1] || |
719 | rdev->irq.pflip[1]) { | 709 | atomic_read(&rdev->irq.pflip[1])) { |
720 | tmp |= RADEON_CRTC2_VBLANK_MASK; | 710 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
721 | } | 711 | } |
722 | if (rdev->irq.hpd[0]) { | 712 | if (rdev->irq.hpd[0]) { |
@@ -782,7 +772,6 @@ int r100_irq_process(struct radeon_device *rdev) | |||
782 | /* gui idle interrupt */ | 772 | /* gui idle interrupt */ |
783 | if (status & RADEON_GUI_IDLE_STAT) { | 773 | if (status & RADEON_GUI_IDLE_STAT) { |
784 | rdev->irq.gui_idle_acked = true; | 774 | rdev->irq.gui_idle_acked = true; |
785 | rdev->pm.gui_idle = true; | ||
786 | wake_up(&rdev->irq.idle_queue); | 775 | wake_up(&rdev->irq.idle_queue); |
787 | } | 776 | } |
788 | /* Vertical blank interrupts */ | 777 | /* Vertical blank interrupts */ |
@@ -792,7 +781,7 @@ int r100_irq_process(struct radeon_device *rdev) | |||
792 | rdev->pm.vblank_sync = true; | 781 | rdev->pm.vblank_sync = true; |
793 | wake_up(&rdev->irq.vblank_queue); | 782 | wake_up(&rdev->irq.vblank_queue); |
794 | } | 783 | } |
795 | if (rdev->irq.pflip[0]) | 784 | if (atomic_read(&rdev->irq.pflip[0])) |
796 | radeon_crtc_handle_flip(rdev, 0); | 785 | radeon_crtc_handle_flip(rdev, 0); |
797 | } | 786 | } |
798 | if (status & RADEON_CRTC2_VBLANK_STAT) { | 787 | if (status & RADEON_CRTC2_VBLANK_STAT) { |
@@ -801,7 +790,7 @@ int r100_irq_process(struct radeon_device *rdev) | |||
801 | rdev->pm.vblank_sync = true; | 790 | rdev->pm.vblank_sync = true; |
802 | wake_up(&rdev->irq.vblank_queue); | 791 | wake_up(&rdev->irq.vblank_queue); |
803 | } | 792 | } |
804 | if (rdev->irq.pflip[1]) | 793 | if (atomic_read(&rdev->irq.pflip[1])) |
805 | radeon_crtc_handle_flip(rdev, 1); | 794 | radeon_crtc_handle_flip(rdev, 1); |
806 | } | 795 | } |
807 | if (status & RADEON_FP_DETECT_STAT) { | 796 | if (status & RADEON_FP_DETECT_STAT) { |
@@ -883,7 +872,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
883 | uint64_t src_offset, | 872 | uint64_t src_offset, |
884 | uint64_t dst_offset, | 873 | uint64_t dst_offset, |
885 | unsigned num_gpu_pages, | 874 | unsigned num_gpu_pages, |
886 | struct radeon_fence *fence) | 875 | struct radeon_fence **fence) |
887 | { | 876 | { |
888 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 877 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
889 | uint32_t cur_pages; | 878 | uint32_t cur_pages; |
@@ -947,7 +936,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
947 | RADEON_WAIT_HOST_IDLECLEAN | | 936 | RADEON_WAIT_HOST_IDLECLEAN | |
948 | RADEON_WAIT_DMA_GUI_IDLE); | 937 | RADEON_WAIT_DMA_GUI_IDLE); |
949 | if (fence) { | 938 | if (fence) { |
950 | r = radeon_fence_emit(rdev, fence); | 939 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); |
951 | } | 940 | } |
952 | radeon_ring_unlock_commit(rdev, ring); | 941 | radeon_ring_unlock_commit(rdev, ring); |
953 | return r; | 942 | return r; |
@@ -1192,6 +1181,14 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
1192 | } | 1181 | } |
1193 | ring->ready = true; | 1182 | ring->ready = true; |
1194 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); | 1183 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
1184 | |||
1185 | if (radeon_ring_supports_scratch_reg(rdev, ring)) { | ||
1186 | r = radeon_scratch_get(rdev, &ring->rptr_save_reg); | ||
1187 | if (r) { | ||
1188 | DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); | ||
1189 | ring->rptr_save_reg = 0; | ||
1190 | } | ||
1191 | } | ||
1195 | return 0; | 1192 | return 0; |
1196 | } | 1193 | } |
1197 | 1194 | ||
@@ -1202,6 +1199,7 @@ void r100_cp_fini(struct radeon_device *rdev) | |||
1202 | } | 1199 | } |
1203 | /* Disable ring */ | 1200 | /* Disable ring */ |
1204 | r100_cp_disable(rdev); | 1201 | r100_cp_disable(rdev); |
1202 | radeon_scratch_free(rdev, rdev->ring[RADEON_RING_TYPE_GFX_INDEX].rptr_save_reg); | ||
1205 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 1203 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
1206 | DRM_INFO("radeon: cp finalized\n"); | 1204 | DRM_INFO("radeon: cp finalized\n"); |
1207 | } | 1205 | } |
@@ -1223,6 +1221,112 @@ void r100_cp_disable(struct radeon_device *rdev) | |||
1223 | /* | 1221 | /* |
1224 | * CS functions | 1222 | * CS functions |
1225 | */ | 1223 | */ |
1224 | int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | ||
1225 | struct radeon_cs_packet *pkt, | ||
1226 | unsigned idx, | ||
1227 | unsigned reg) | ||
1228 | { | ||
1229 | int r; | ||
1230 | u32 tile_flags = 0; | ||
1231 | u32 tmp; | ||
1232 | struct radeon_cs_reloc *reloc; | ||
1233 | u32 value; | ||
1234 | |||
1235 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1236 | if (r) { | ||
1237 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1238 | idx, reg); | ||
1239 | r100_cs_dump_packet(p, pkt); | ||
1240 | return r; | ||
1241 | } | ||
1242 | |||
1243 | value = radeon_get_ib_value(p, idx); | ||
1244 | tmp = value & 0x003fffff; | ||
1245 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); | ||
1246 | |||
1247 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | ||
1248 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
1249 | tile_flags |= RADEON_DST_TILE_MACRO; | ||
1250 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
1251 | if (reg == RADEON_SRC_PITCH_OFFSET) { | ||
1252 | DRM_ERROR("Cannot src blit from microtiled surface\n"); | ||
1253 | r100_cs_dump_packet(p, pkt); | ||
1254 | return -EINVAL; | ||
1255 | } | ||
1256 | tile_flags |= RADEON_DST_TILE_MICRO; | ||
1257 | } | ||
1258 | |||
1259 | tmp |= tile_flags; | ||
1260 | p->ib.ptr[idx] = (value & 0x3fc00000) | tmp; | ||
1261 | } else | ||
1262 | p->ib.ptr[idx] = (value & 0xffc00000) | tmp; | ||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, | ||
1267 | struct radeon_cs_packet *pkt, | ||
1268 | int idx) | ||
1269 | { | ||
1270 | unsigned c, i; | ||
1271 | struct radeon_cs_reloc *reloc; | ||
1272 | struct r100_cs_track *track; | ||
1273 | int r = 0; | ||
1274 | volatile uint32_t *ib; | ||
1275 | u32 idx_value; | ||
1276 | |||
1277 | ib = p->ib.ptr; | ||
1278 | track = (struct r100_cs_track *)p->track; | ||
1279 | c = radeon_get_ib_value(p, idx++) & 0x1F; | ||
1280 | if (c > 16) { | ||
1281 | DRM_ERROR("Only 16 vertex buffers are allowed %d\n", | ||
1282 | pkt->opcode); | ||
1283 | r100_cs_dump_packet(p, pkt); | ||
1284 | return -EINVAL; | ||
1285 | } | ||
1286 | track->num_arrays = c; | ||
1287 | for (i = 0; i < (c - 1); i+=2, idx+=3) { | ||
1288 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1289 | if (r) { | ||
1290 | DRM_ERROR("No reloc for packet3 %d\n", | ||
1291 | pkt->opcode); | ||
1292 | r100_cs_dump_packet(p, pkt); | ||
1293 | return r; | ||
1294 | } | ||
1295 | idx_value = radeon_get_ib_value(p, idx); | ||
1296 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); | ||
1297 | |||
1298 | track->arrays[i + 0].esize = idx_value >> 8; | ||
1299 | track->arrays[i + 0].robj = reloc->robj; | ||
1300 | track->arrays[i + 0].esize &= 0x7F; | ||
1301 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1302 | if (r) { | ||
1303 | DRM_ERROR("No reloc for packet3 %d\n", | ||
1304 | pkt->opcode); | ||
1305 | r100_cs_dump_packet(p, pkt); | ||
1306 | return r; | ||
1307 | } | ||
1308 | ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); | ||
1309 | track->arrays[i + 1].robj = reloc->robj; | ||
1310 | track->arrays[i + 1].esize = idx_value >> 24; | ||
1311 | track->arrays[i + 1].esize &= 0x7F; | ||
1312 | } | ||
1313 | if (c & 1) { | ||
1314 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1315 | if (r) { | ||
1316 | DRM_ERROR("No reloc for packet3 %d\n", | ||
1317 | pkt->opcode); | ||
1318 | r100_cs_dump_packet(p, pkt); | ||
1319 | return r; | ||
1320 | } | ||
1321 | idx_value = radeon_get_ib_value(p, idx); | ||
1322 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); | ||
1323 | track->arrays[i + 0].robj = reloc->robj; | ||
1324 | track->arrays[i + 0].esize = idx_value >> 8; | ||
1325 | track->arrays[i + 0].esize &= 0x7F; | ||
1326 | } | ||
1327 | return r; | ||
1328 | } | ||
1329 | |||
1226 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, | 1330 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
1227 | struct radeon_cs_packet *pkt, | 1331 | struct radeon_cs_packet *pkt, |
1228 | const unsigned *auth, unsigned n, | 1332 | const unsigned *auth, unsigned n, |
@@ -2048,6 +2152,379 @@ int r100_cs_parse(struct radeon_cs_parser *p) | |||
2048 | return 0; | 2152 | return 0; |
2049 | } | 2153 | } |
2050 | 2154 | ||
2155 | static void r100_cs_track_texture_print(struct r100_cs_track_texture *t) | ||
2156 | { | ||
2157 | DRM_ERROR("pitch %d\n", t->pitch); | ||
2158 | DRM_ERROR("use_pitch %d\n", t->use_pitch); | ||
2159 | DRM_ERROR("width %d\n", t->width); | ||
2160 | DRM_ERROR("width_11 %d\n", t->width_11); | ||
2161 | DRM_ERROR("height %d\n", t->height); | ||
2162 | DRM_ERROR("height_11 %d\n", t->height_11); | ||
2163 | DRM_ERROR("num levels %d\n", t->num_levels); | ||
2164 | DRM_ERROR("depth %d\n", t->txdepth); | ||
2165 | DRM_ERROR("bpp %d\n", t->cpp); | ||
2166 | DRM_ERROR("coordinate type %d\n", t->tex_coord_type); | ||
2167 | DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); | ||
2168 | DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); | ||
2169 | DRM_ERROR("compress format %d\n", t->compress_format); | ||
2170 | } | ||
2171 | |||
2172 | static int r100_track_compress_size(int compress_format, int w, int h) | ||
2173 | { | ||
2174 | int block_width, block_height, block_bytes; | ||
2175 | int wblocks, hblocks; | ||
2176 | int min_wblocks; | ||
2177 | int sz; | ||
2178 | |||
2179 | block_width = 4; | ||
2180 | block_height = 4; | ||
2181 | |||
2182 | switch (compress_format) { | ||
2183 | case R100_TRACK_COMP_DXT1: | ||
2184 | block_bytes = 8; | ||
2185 | min_wblocks = 4; | ||
2186 | break; | ||
2187 | default: | ||
2188 | case R100_TRACK_COMP_DXT35: | ||
2189 | block_bytes = 16; | ||
2190 | min_wblocks = 2; | ||
2191 | break; | ||
2192 | } | ||
2193 | |||
2194 | hblocks = (h + block_height - 1) / block_height; | ||
2195 | wblocks = (w + block_width - 1) / block_width; | ||
2196 | if (wblocks < min_wblocks) | ||
2197 | wblocks = min_wblocks; | ||
2198 | sz = wblocks * hblocks * block_bytes; | ||
2199 | return sz; | ||
2200 | } | ||
2201 | |||
2202 | static int r100_cs_track_cube(struct radeon_device *rdev, | ||
2203 | struct r100_cs_track *track, unsigned idx) | ||
2204 | { | ||
2205 | unsigned face, w, h; | ||
2206 | struct radeon_bo *cube_robj; | ||
2207 | unsigned long size; | ||
2208 | unsigned compress_format = track->textures[idx].compress_format; | ||
2209 | |||
2210 | for (face = 0; face < 5; face++) { | ||
2211 | cube_robj = track->textures[idx].cube_info[face].robj; | ||
2212 | w = track->textures[idx].cube_info[face].width; | ||
2213 | h = track->textures[idx].cube_info[face].height; | ||
2214 | |||
2215 | if (compress_format) { | ||
2216 | size = r100_track_compress_size(compress_format, w, h); | ||
2217 | } else | ||
2218 | size = w * h; | ||
2219 | size *= track->textures[idx].cpp; | ||
2220 | |||
2221 | size += track->textures[idx].cube_info[face].offset; | ||
2222 | |||
2223 | if (size > radeon_bo_size(cube_robj)) { | ||
2224 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", | ||
2225 | size, radeon_bo_size(cube_robj)); | ||
2226 | r100_cs_track_texture_print(&track->textures[idx]); | ||
2227 | return -1; | ||
2228 | } | ||
2229 | } | ||
2230 | return 0; | ||
2231 | } | ||
2232 | |||
2233 | static int r100_cs_track_texture_check(struct radeon_device *rdev, | ||
2234 | struct r100_cs_track *track) | ||
2235 | { | ||
2236 | struct radeon_bo *robj; | ||
2237 | unsigned long size; | ||
2238 | unsigned u, i, w, h, d; | ||
2239 | int ret; | ||
2240 | |||
2241 | for (u = 0; u < track->num_texture; u++) { | ||
2242 | if (!track->textures[u].enabled) | ||
2243 | continue; | ||
2244 | if (track->textures[u].lookup_disable) | ||
2245 | continue; | ||
2246 | robj = track->textures[u].robj; | ||
2247 | if (robj == NULL) { | ||
2248 | DRM_ERROR("No texture bound to unit %u\n", u); | ||
2249 | return -EINVAL; | ||
2250 | } | ||
2251 | size = 0; | ||
2252 | for (i = 0; i <= track->textures[u].num_levels; i++) { | ||
2253 | if (track->textures[u].use_pitch) { | ||
2254 | if (rdev->family < CHIP_R300) | ||
2255 | w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); | ||
2256 | else | ||
2257 | w = track->textures[u].pitch / (1 << i); | ||
2258 | } else { | ||
2259 | w = track->textures[u].width; | ||
2260 | if (rdev->family >= CHIP_RV515) | ||
2261 | w |= track->textures[u].width_11; | ||
2262 | w = w / (1 << i); | ||
2263 | if (track->textures[u].roundup_w) | ||
2264 | w = roundup_pow_of_two(w); | ||
2265 | } | ||
2266 | h = track->textures[u].height; | ||
2267 | if (rdev->family >= CHIP_RV515) | ||
2268 | h |= track->textures[u].height_11; | ||
2269 | h = h / (1 << i); | ||
2270 | if (track->textures[u].roundup_h) | ||
2271 | h = roundup_pow_of_two(h); | ||
2272 | if (track->textures[u].tex_coord_type == 1) { | ||
2273 | d = (1 << track->textures[u].txdepth) / (1 << i); | ||
2274 | if (!d) | ||
2275 | d = 1; | ||
2276 | } else { | ||
2277 | d = 1; | ||
2278 | } | ||
2279 | if (track->textures[u].compress_format) { | ||
2280 | |||
2281 | size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; | ||
2282 | /* compressed textures are block based */ | ||
2283 | } else | ||
2284 | size += w * h * d; | ||
2285 | } | ||
2286 | size *= track->textures[u].cpp; | ||
2287 | |||
2288 | switch (track->textures[u].tex_coord_type) { | ||
2289 | case 0: | ||
2290 | case 1: | ||
2291 | break; | ||
2292 | case 2: | ||
2293 | if (track->separate_cube) { | ||
2294 | ret = r100_cs_track_cube(rdev, track, u); | ||
2295 | if (ret) | ||
2296 | return ret; | ||
2297 | } else | ||
2298 | size *= 6; | ||
2299 | break; | ||
2300 | default: | ||
2301 | DRM_ERROR("Invalid texture coordinate type %u for unit " | ||
2302 | "%u\n", track->textures[u].tex_coord_type, u); | ||
2303 | return -EINVAL; | ||
2304 | } | ||
2305 | if (size > radeon_bo_size(robj)) { | ||
2306 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " | ||
2307 | "%lu\n", u, size, radeon_bo_size(robj)); | ||
2308 | r100_cs_track_texture_print(&track->textures[u]); | ||
2309 | return -EINVAL; | ||
2310 | } | ||
2311 | } | ||
2312 | return 0; | ||
2313 | } | ||
2314 | |||
2315 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | ||
2316 | { | ||
2317 | unsigned i; | ||
2318 | unsigned long size; | ||
2319 | unsigned prim_walk; | ||
2320 | unsigned nverts; | ||
2321 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; | ||
2322 | |||
2323 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && | ||
2324 | !track->blend_read_enable) | ||
2325 | num_cb = 0; | ||
2326 | |||
2327 | for (i = 0; i < num_cb; i++) { | ||
2328 | if (track->cb[i].robj == NULL) { | ||
2329 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); | ||
2330 | return -EINVAL; | ||
2331 | } | ||
2332 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; | ||
2333 | size += track->cb[i].offset; | ||
2334 | if (size > radeon_bo_size(track->cb[i].robj)) { | ||
2335 | DRM_ERROR("[drm] Buffer too small for color buffer %d " | ||
2336 | "(need %lu have %lu) !\n", i, size, | ||
2337 | radeon_bo_size(track->cb[i].robj)); | ||
2338 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", | ||
2339 | i, track->cb[i].pitch, track->cb[i].cpp, | ||
2340 | track->cb[i].offset, track->maxy); | ||
2341 | return -EINVAL; | ||
2342 | } | ||
2343 | } | ||
2344 | track->cb_dirty = false; | ||
2345 | |||
2346 | if (track->zb_dirty && track->z_enabled) { | ||
2347 | if (track->zb.robj == NULL) { | ||
2348 | DRM_ERROR("[drm] No buffer for z buffer !\n"); | ||
2349 | return -EINVAL; | ||
2350 | } | ||
2351 | size = track->zb.pitch * track->zb.cpp * track->maxy; | ||
2352 | size += track->zb.offset; | ||
2353 | if (size > radeon_bo_size(track->zb.robj)) { | ||
2354 | DRM_ERROR("[drm] Buffer too small for z buffer " | ||
2355 | "(need %lu have %lu) !\n", size, | ||
2356 | radeon_bo_size(track->zb.robj)); | ||
2357 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", | ||
2358 | track->zb.pitch, track->zb.cpp, | ||
2359 | track->zb.offset, track->maxy); | ||
2360 | return -EINVAL; | ||
2361 | } | ||
2362 | } | ||
2363 | track->zb_dirty = false; | ||
2364 | |||
2365 | if (track->aa_dirty && track->aaresolve) { | ||
2366 | if (track->aa.robj == NULL) { | ||
2367 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); | ||
2368 | return -EINVAL; | ||
2369 | } | ||
2370 | /* I believe the format comes from colorbuffer0. */ | ||
2371 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; | ||
2372 | size += track->aa.offset; | ||
2373 | if (size > radeon_bo_size(track->aa.robj)) { | ||
2374 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " | ||
2375 | "(need %lu have %lu) !\n", i, size, | ||
2376 | radeon_bo_size(track->aa.robj)); | ||
2377 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", | ||
2378 | i, track->aa.pitch, track->cb[0].cpp, | ||
2379 | track->aa.offset, track->maxy); | ||
2380 | return -EINVAL; | ||
2381 | } | ||
2382 | } | ||
2383 | track->aa_dirty = false; | ||
2384 | |||
2385 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; | ||
2386 | if (track->vap_vf_cntl & (1 << 14)) { | ||
2387 | nverts = track->vap_alt_nverts; | ||
2388 | } else { | ||
2389 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; | ||
2390 | } | ||
2391 | switch (prim_walk) { | ||
2392 | case 1: | ||
2393 | for (i = 0; i < track->num_arrays; i++) { | ||
2394 | size = track->arrays[i].esize * track->max_indx * 4; | ||
2395 | if (track->arrays[i].robj == NULL) { | ||
2396 | DRM_ERROR("(PW %u) Vertex array %u no buffer " | ||
2397 | "bound\n", prim_walk, i); | ||
2398 | return -EINVAL; | ||
2399 | } | ||
2400 | if (size > radeon_bo_size(track->arrays[i].robj)) { | ||
2401 | dev_err(rdev->dev, "(PW %u) Vertex array %u " | ||
2402 | "need %lu dwords have %lu dwords\n", | ||
2403 | prim_walk, i, size >> 2, | ||
2404 | radeon_bo_size(track->arrays[i].robj) | ||
2405 | >> 2); | ||
2406 | DRM_ERROR("Max indices %u\n", track->max_indx); | ||
2407 | return -EINVAL; | ||
2408 | } | ||
2409 | } | ||
2410 | break; | ||
2411 | case 2: | ||
2412 | for (i = 0; i < track->num_arrays; i++) { | ||
2413 | size = track->arrays[i].esize * (nverts - 1) * 4; | ||
2414 | if (track->arrays[i].robj == NULL) { | ||
2415 | DRM_ERROR("(PW %u) Vertex array %u no buffer " | ||
2416 | "bound\n", prim_walk, i); | ||
2417 | return -EINVAL; | ||
2418 | } | ||
2419 | if (size > radeon_bo_size(track->arrays[i].robj)) { | ||
2420 | dev_err(rdev->dev, "(PW %u) Vertex array %u " | ||
2421 | "need %lu dwords have %lu dwords\n", | ||
2422 | prim_walk, i, size >> 2, | ||
2423 | radeon_bo_size(track->arrays[i].robj) | ||
2424 | >> 2); | ||
2425 | return -EINVAL; | ||
2426 | } | ||
2427 | } | ||
2428 | break; | ||
2429 | case 3: | ||
2430 | size = track->vtx_size * nverts; | ||
2431 | if (size != track->immd_dwords) { | ||
2432 | DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", | ||
2433 | track->immd_dwords, size); | ||
2434 | DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", | ||
2435 | nverts, track->vtx_size); | ||
2436 | return -EINVAL; | ||
2437 | } | ||
2438 | break; | ||
2439 | default: | ||
2440 | DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", | ||
2441 | prim_walk); | ||
2442 | return -EINVAL; | ||
2443 | } | ||
2444 | |||
2445 | if (track->tex_dirty) { | ||
2446 | track->tex_dirty = false; | ||
2447 | return r100_cs_track_texture_check(rdev, track); | ||
2448 | } | ||
2449 | return 0; | ||
2450 | } | ||
2451 | |||
2452 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) | ||
2453 | { | ||
2454 | unsigned i, face; | ||
2455 | |||
2456 | track->cb_dirty = true; | ||
2457 | track->zb_dirty = true; | ||
2458 | track->tex_dirty = true; | ||
2459 | track->aa_dirty = true; | ||
2460 | |||
2461 | if (rdev->family < CHIP_R300) { | ||
2462 | track->num_cb = 1; | ||
2463 | if (rdev->family <= CHIP_RS200) | ||
2464 | track->num_texture = 3; | ||
2465 | else | ||
2466 | track->num_texture = 6; | ||
2467 | track->maxy = 2048; | ||
2468 | track->separate_cube = 1; | ||
2469 | } else { | ||
2470 | track->num_cb = 4; | ||
2471 | track->num_texture = 16; | ||
2472 | track->maxy = 4096; | ||
2473 | track->separate_cube = 0; | ||
2474 | track->aaresolve = false; | ||
2475 | track->aa.robj = NULL; | ||
2476 | } | ||
2477 | |||
2478 | for (i = 0; i < track->num_cb; i++) { | ||
2479 | track->cb[i].robj = NULL; | ||
2480 | track->cb[i].pitch = 8192; | ||
2481 | track->cb[i].cpp = 16; | ||
2482 | track->cb[i].offset = 0; | ||
2483 | } | ||
2484 | track->z_enabled = true; | ||
2485 | track->zb.robj = NULL; | ||
2486 | track->zb.pitch = 8192; | ||
2487 | track->zb.cpp = 4; | ||
2488 | track->zb.offset = 0; | ||
2489 | track->vtx_size = 0x7F; | ||
2490 | track->immd_dwords = 0xFFFFFFFFUL; | ||
2491 | track->num_arrays = 11; | ||
2492 | track->max_indx = 0x00FFFFFFUL; | ||
2493 | for (i = 0; i < track->num_arrays; i++) { | ||
2494 | track->arrays[i].robj = NULL; | ||
2495 | track->arrays[i].esize = 0x7F; | ||
2496 | } | ||
2497 | for (i = 0; i < track->num_texture; i++) { | ||
2498 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; | ||
2499 | track->textures[i].pitch = 16536; | ||
2500 | track->textures[i].width = 16536; | ||
2501 | track->textures[i].height = 16536; | ||
2502 | track->textures[i].width_11 = 1 << 11; | ||
2503 | track->textures[i].height_11 = 1 << 11; | ||
2504 | track->textures[i].num_levels = 12; | ||
2505 | if (rdev->family <= CHIP_RS200) { | ||
2506 | track->textures[i].tex_coord_type = 0; | ||
2507 | track->textures[i].txdepth = 0; | ||
2508 | } else { | ||
2509 | track->textures[i].txdepth = 16; | ||
2510 | track->textures[i].tex_coord_type = 1; | ||
2511 | } | ||
2512 | track->textures[i].cpp = 64; | ||
2513 | track->textures[i].robj = NULL; | ||
2514 | /* CS IB emission code makes sure texture unit are disabled */ | ||
2515 | track->textures[i].enabled = false; | ||
2516 | track->textures[i].lookup_disable = false; | ||
2517 | track->textures[i].roundup_w = true; | ||
2518 | track->textures[i].roundup_h = true; | ||
2519 | if (track->separate_cube) | ||
2520 | for (face = 0; face < 5; face++) { | ||
2521 | track->textures[i].cube_info[face].robj = NULL; | ||
2522 | track->textures[i].cube_info[face].width = 16536; | ||
2523 | track->textures[i].cube_info[face].height = 16536; | ||
2524 | track->textures[i].cube_info[face].offset = 0; | ||
2525 | } | ||
2526 | } | ||
2527 | } | ||
2051 | 2528 | ||
2052 | /* | 2529 | /* |
2053 | * Global GPU functions | 2530 | * Global GPU functions |
@@ -2175,6 +2652,15 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2175 | return radeon_ring_test_lockup(rdev, ring); | 2652 | return radeon_ring_test_lockup(rdev, ring); |
2176 | } | 2653 | } |
2177 | 2654 | ||
2655 | /* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ | ||
2656 | void r100_enable_bm(struct radeon_device *rdev) | ||
2657 | { | ||
2658 | uint32_t tmp; | ||
2659 | /* Enable bus mastering */ | ||
2660 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
2661 | WREG32(RADEON_BUS_CNTL, tmp); | ||
2662 | } | ||
2663 | |||
2178 | void r100_bm_disable(struct radeon_device *rdev) | 2664 | void r100_bm_disable(struct radeon_device *rdev) |
2179 | { | 2665 | { |
2180 | u32 tmp; | 2666 | u32 tmp; |
@@ -3261,380 +3747,6 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
3261 | } | 3747 | } |
3262 | } | 3748 | } |
3263 | 3749 | ||
3264 | static void r100_cs_track_texture_print(struct r100_cs_track_texture *t) | ||
3265 | { | ||
3266 | DRM_ERROR("pitch %d\n", t->pitch); | ||
3267 | DRM_ERROR("use_pitch %d\n", t->use_pitch); | ||
3268 | DRM_ERROR("width %d\n", t->width); | ||
3269 | DRM_ERROR("width_11 %d\n", t->width_11); | ||
3270 | DRM_ERROR("height %d\n", t->height); | ||
3271 | DRM_ERROR("height_11 %d\n", t->height_11); | ||
3272 | DRM_ERROR("num levels %d\n", t->num_levels); | ||
3273 | DRM_ERROR("depth %d\n", t->txdepth); | ||
3274 | DRM_ERROR("bpp %d\n", t->cpp); | ||
3275 | DRM_ERROR("coordinate type %d\n", t->tex_coord_type); | ||
3276 | DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); | ||
3277 | DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); | ||
3278 | DRM_ERROR("compress format %d\n", t->compress_format); | ||
3279 | } | ||
3280 | |||
3281 | static int r100_track_compress_size(int compress_format, int w, int h) | ||
3282 | { | ||
3283 | int block_width, block_height, block_bytes; | ||
3284 | int wblocks, hblocks; | ||
3285 | int min_wblocks; | ||
3286 | int sz; | ||
3287 | |||
3288 | block_width = 4; | ||
3289 | block_height = 4; | ||
3290 | |||
3291 | switch (compress_format) { | ||
3292 | case R100_TRACK_COMP_DXT1: | ||
3293 | block_bytes = 8; | ||
3294 | min_wblocks = 4; | ||
3295 | break; | ||
3296 | default: | ||
3297 | case R100_TRACK_COMP_DXT35: | ||
3298 | block_bytes = 16; | ||
3299 | min_wblocks = 2; | ||
3300 | break; | ||
3301 | } | ||
3302 | |||
3303 | hblocks = (h + block_height - 1) / block_height; | ||
3304 | wblocks = (w + block_width - 1) / block_width; | ||
3305 | if (wblocks < min_wblocks) | ||
3306 | wblocks = min_wblocks; | ||
3307 | sz = wblocks * hblocks * block_bytes; | ||
3308 | return sz; | ||
3309 | } | ||
3310 | |||
3311 | static int r100_cs_track_cube(struct radeon_device *rdev, | ||
3312 | struct r100_cs_track *track, unsigned idx) | ||
3313 | { | ||
3314 | unsigned face, w, h; | ||
3315 | struct radeon_bo *cube_robj; | ||
3316 | unsigned long size; | ||
3317 | unsigned compress_format = track->textures[idx].compress_format; | ||
3318 | |||
3319 | for (face = 0; face < 5; face++) { | ||
3320 | cube_robj = track->textures[idx].cube_info[face].robj; | ||
3321 | w = track->textures[idx].cube_info[face].width; | ||
3322 | h = track->textures[idx].cube_info[face].height; | ||
3323 | |||
3324 | if (compress_format) { | ||
3325 | size = r100_track_compress_size(compress_format, w, h); | ||
3326 | } else | ||
3327 | size = w * h; | ||
3328 | size *= track->textures[idx].cpp; | ||
3329 | |||
3330 | size += track->textures[idx].cube_info[face].offset; | ||
3331 | |||
3332 | if (size > radeon_bo_size(cube_robj)) { | ||
3333 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", | ||
3334 | size, radeon_bo_size(cube_robj)); | ||
3335 | r100_cs_track_texture_print(&track->textures[idx]); | ||
3336 | return -1; | ||
3337 | } | ||
3338 | } | ||
3339 | return 0; | ||
3340 | } | ||
3341 | |||
3342 | static int r100_cs_track_texture_check(struct radeon_device *rdev, | ||
3343 | struct r100_cs_track *track) | ||
3344 | { | ||
3345 | struct radeon_bo *robj; | ||
3346 | unsigned long size; | ||
3347 | unsigned u, i, w, h, d; | ||
3348 | int ret; | ||
3349 | |||
3350 | for (u = 0; u < track->num_texture; u++) { | ||
3351 | if (!track->textures[u].enabled) | ||
3352 | continue; | ||
3353 | if (track->textures[u].lookup_disable) | ||
3354 | continue; | ||
3355 | robj = track->textures[u].robj; | ||
3356 | if (robj == NULL) { | ||
3357 | DRM_ERROR("No texture bound to unit %u\n", u); | ||
3358 | return -EINVAL; | ||
3359 | } | ||
3360 | size = 0; | ||
3361 | for (i = 0; i <= track->textures[u].num_levels; i++) { | ||
3362 | if (track->textures[u].use_pitch) { | ||
3363 | if (rdev->family < CHIP_R300) | ||
3364 | w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); | ||
3365 | else | ||
3366 | w = track->textures[u].pitch / (1 << i); | ||
3367 | } else { | ||
3368 | w = track->textures[u].width; | ||
3369 | if (rdev->family >= CHIP_RV515) | ||
3370 | w |= track->textures[u].width_11; | ||
3371 | w = w / (1 << i); | ||
3372 | if (track->textures[u].roundup_w) | ||
3373 | w = roundup_pow_of_two(w); | ||
3374 | } | ||
3375 | h = track->textures[u].height; | ||
3376 | if (rdev->family >= CHIP_RV515) | ||
3377 | h |= track->textures[u].height_11; | ||
3378 | h = h / (1 << i); | ||
3379 | if (track->textures[u].roundup_h) | ||
3380 | h = roundup_pow_of_two(h); | ||
3381 | if (track->textures[u].tex_coord_type == 1) { | ||
3382 | d = (1 << track->textures[u].txdepth) / (1 << i); | ||
3383 | if (!d) | ||
3384 | d = 1; | ||
3385 | } else { | ||
3386 | d = 1; | ||
3387 | } | ||
3388 | if (track->textures[u].compress_format) { | ||
3389 | |||
3390 | size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; | ||
3391 | /* compressed textures are block based */ | ||
3392 | } else | ||
3393 | size += w * h * d; | ||
3394 | } | ||
3395 | size *= track->textures[u].cpp; | ||
3396 | |||
3397 | switch (track->textures[u].tex_coord_type) { | ||
3398 | case 0: | ||
3399 | case 1: | ||
3400 | break; | ||
3401 | case 2: | ||
3402 | if (track->separate_cube) { | ||
3403 | ret = r100_cs_track_cube(rdev, track, u); | ||
3404 | if (ret) | ||
3405 | return ret; | ||
3406 | } else | ||
3407 | size *= 6; | ||
3408 | break; | ||
3409 | default: | ||
3410 | DRM_ERROR("Invalid texture coordinate type %u for unit " | ||
3411 | "%u\n", track->textures[u].tex_coord_type, u); | ||
3412 | return -EINVAL; | ||
3413 | } | ||
3414 | if (size > radeon_bo_size(robj)) { | ||
3415 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " | ||
3416 | "%lu\n", u, size, radeon_bo_size(robj)); | ||
3417 | r100_cs_track_texture_print(&track->textures[u]); | ||
3418 | return -EINVAL; | ||
3419 | } | ||
3420 | } | ||
3421 | return 0; | ||
3422 | } | ||
3423 | |||
3424 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | ||
3425 | { | ||
3426 | unsigned i; | ||
3427 | unsigned long size; | ||
3428 | unsigned prim_walk; | ||
3429 | unsigned nverts; | ||
3430 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; | ||
3431 | |||
3432 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && | ||
3433 | !track->blend_read_enable) | ||
3434 | num_cb = 0; | ||
3435 | |||
3436 | for (i = 0; i < num_cb; i++) { | ||
3437 | if (track->cb[i].robj == NULL) { | ||
3438 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); | ||
3439 | return -EINVAL; | ||
3440 | } | ||
3441 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; | ||
3442 | size += track->cb[i].offset; | ||
3443 | if (size > radeon_bo_size(track->cb[i].robj)) { | ||
3444 | DRM_ERROR("[drm] Buffer too small for color buffer %d " | ||
3445 | "(need %lu have %lu) !\n", i, size, | ||
3446 | radeon_bo_size(track->cb[i].robj)); | ||
3447 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", | ||
3448 | i, track->cb[i].pitch, track->cb[i].cpp, | ||
3449 | track->cb[i].offset, track->maxy); | ||
3450 | return -EINVAL; | ||
3451 | } | ||
3452 | } | ||
3453 | track->cb_dirty = false; | ||
3454 | |||
3455 | if (track->zb_dirty && track->z_enabled) { | ||
3456 | if (track->zb.robj == NULL) { | ||
3457 | DRM_ERROR("[drm] No buffer for z buffer !\n"); | ||
3458 | return -EINVAL; | ||
3459 | } | ||
3460 | size = track->zb.pitch * track->zb.cpp * track->maxy; | ||
3461 | size += track->zb.offset; | ||
3462 | if (size > radeon_bo_size(track->zb.robj)) { | ||
3463 | DRM_ERROR("[drm] Buffer too small for z buffer " | ||
3464 | "(need %lu have %lu) !\n", size, | ||
3465 | radeon_bo_size(track->zb.robj)); | ||
3466 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", | ||
3467 | track->zb.pitch, track->zb.cpp, | ||
3468 | track->zb.offset, track->maxy); | ||
3469 | return -EINVAL; | ||
3470 | } | ||
3471 | } | ||
3472 | track->zb_dirty = false; | ||
3473 | |||
3474 | if (track->aa_dirty && track->aaresolve) { | ||
3475 | if (track->aa.robj == NULL) { | ||
3476 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); | ||
3477 | return -EINVAL; | ||
3478 | } | ||
3479 | /* I believe the format comes from colorbuffer0. */ | ||
3480 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; | ||
3481 | size += track->aa.offset; | ||
3482 | if (size > radeon_bo_size(track->aa.robj)) { | ||
3483 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " | ||
3484 | "(need %lu have %lu) !\n", i, size, | ||
3485 | radeon_bo_size(track->aa.robj)); | ||
3486 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", | ||
3487 | i, track->aa.pitch, track->cb[0].cpp, | ||
3488 | track->aa.offset, track->maxy); | ||
3489 | return -EINVAL; | ||
3490 | } | ||
3491 | } | ||
3492 | track->aa_dirty = false; | ||
3493 | |||
3494 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; | ||
3495 | if (track->vap_vf_cntl & (1 << 14)) { | ||
3496 | nverts = track->vap_alt_nverts; | ||
3497 | } else { | ||
3498 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; | ||
3499 | } | ||
3500 | switch (prim_walk) { | ||
3501 | case 1: | ||
3502 | for (i = 0; i < track->num_arrays; i++) { | ||
3503 | size = track->arrays[i].esize * track->max_indx * 4; | ||
3504 | if (track->arrays[i].robj == NULL) { | ||
3505 | DRM_ERROR("(PW %u) Vertex array %u no buffer " | ||
3506 | "bound\n", prim_walk, i); | ||
3507 | return -EINVAL; | ||
3508 | } | ||
3509 | if (size > radeon_bo_size(track->arrays[i].robj)) { | ||
3510 | dev_err(rdev->dev, "(PW %u) Vertex array %u " | ||
3511 | "need %lu dwords have %lu dwords\n", | ||
3512 | prim_walk, i, size >> 2, | ||
3513 | radeon_bo_size(track->arrays[i].robj) | ||
3514 | >> 2); | ||
3515 | DRM_ERROR("Max indices %u\n", track->max_indx); | ||
3516 | return -EINVAL; | ||
3517 | } | ||
3518 | } | ||
3519 | break; | ||
3520 | case 2: | ||
3521 | for (i = 0; i < track->num_arrays; i++) { | ||
3522 | size = track->arrays[i].esize * (nverts - 1) * 4; | ||
3523 | if (track->arrays[i].robj == NULL) { | ||
3524 | DRM_ERROR("(PW %u) Vertex array %u no buffer " | ||
3525 | "bound\n", prim_walk, i); | ||
3526 | return -EINVAL; | ||
3527 | } | ||
3528 | if (size > radeon_bo_size(track->arrays[i].robj)) { | ||
3529 | dev_err(rdev->dev, "(PW %u) Vertex array %u " | ||
3530 | "need %lu dwords have %lu dwords\n", | ||
3531 | prim_walk, i, size >> 2, | ||
3532 | radeon_bo_size(track->arrays[i].robj) | ||
3533 | >> 2); | ||
3534 | return -EINVAL; | ||
3535 | } | ||
3536 | } | ||
3537 | break; | ||
3538 | case 3: | ||
3539 | size = track->vtx_size * nverts; | ||
3540 | if (size != track->immd_dwords) { | ||
3541 | DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", | ||
3542 | track->immd_dwords, size); | ||
3543 | DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", | ||
3544 | nverts, track->vtx_size); | ||
3545 | return -EINVAL; | ||
3546 | } | ||
3547 | break; | ||
3548 | default: | ||
3549 | DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", | ||
3550 | prim_walk); | ||
3551 | return -EINVAL; | ||
3552 | } | ||
3553 | |||
3554 | if (track->tex_dirty) { | ||
3555 | track->tex_dirty = false; | ||
3556 | return r100_cs_track_texture_check(rdev, track); | ||
3557 | } | ||
3558 | return 0; | ||
3559 | } | ||
3560 | |||
3561 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) | ||
3562 | { | ||
3563 | unsigned i, face; | ||
3564 | |||
3565 | track->cb_dirty = true; | ||
3566 | track->zb_dirty = true; | ||
3567 | track->tex_dirty = true; | ||
3568 | track->aa_dirty = true; | ||
3569 | |||
3570 | if (rdev->family < CHIP_R300) { | ||
3571 | track->num_cb = 1; | ||
3572 | if (rdev->family <= CHIP_RS200) | ||
3573 | track->num_texture = 3; | ||
3574 | else | ||
3575 | track->num_texture = 6; | ||
3576 | track->maxy = 2048; | ||
3577 | track->separate_cube = 1; | ||
3578 | } else { | ||
3579 | track->num_cb = 4; | ||
3580 | track->num_texture = 16; | ||
3581 | track->maxy = 4096; | ||
3582 | track->separate_cube = 0; | ||
3583 | track->aaresolve = false; | ||
3584 | track->aa.robj = NULL; | ||
3585 | } | ||
3586 | |||
3587 | for (i = 0; i < track->num_cb; i++) { | ||
3588 | track->cb[i].robj = NULL; | ||
3589 | track->cb[i].pitch = 8192; | ||
3590 | track->cb[i].cpp = 16; | ||
3591 | track->cb[i].offset = 0; | ||
3592 | } | ||
3593 | track->z_enabled = true; | ||
3594 | track->zb.robj = NULL; | ||
3595 | track->zb.pitch = 8192; | ||
3596 | track->zb.cpp = 4; | ||
3597 | track->zb.offset = 0; | ||
3598 | track->vtx_size = 0x7F; | ||
3599 | track->immd_dwords = 0xFFFFFFFFUL; | ||
3600 | track->num_arrays = 11; | ||
3601 | track->max_indx = 0x00FFFFFFUL; | ||
3602 | for (i = 0; i < track->num_arrays; i++) { | ||
3603 | track->arrays[i].robj = NULL; | ||
3604 | track->arrays[i].esize = 0x7F; | ||
3605 | } | ||
3606 | for (i = 0; i < track->num_texture; i++) { | ||
3607 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; | ||
3608 | track->textures[i].pitch = 16536; | ||
3609 | track->textures[i].width = 16536; | ||
3610 | track->textures[i].height = 16536; | ||
3611 | track->textures[i].width_11 = 1 << 11; | ||
3612 | track->textures[i].height_11 = 1 << 11; | ||
3613 | track->textures[i].num_levels = 12; | ||
3614 | if (rdev->family <= CHIP_RS200) { | ||
3615 | track->textures[i].tex_coord_type = 0; | ||
3616 | track->textures[i].txdepth = 0; | ||
3617 | } else { | ||
3618 | track->textures[i].txdepth = 16; | ||
3619 | track->textures[i].tex_coord_type = 1; | ||
3620 | } | ||
3621 | track->textures[i].cpp = 64; | ||
3622 | track->textures[i].robj = NULL; | ||
3623 | /* CS IB emission code makes sure texture unit are disabled */ | ||
3624 | track->textures[i].enabled = false; | ||
3625 | track->textures[i].lookup_disable = false; | ||
3626 | track->textures[i].roundup_w = true; | ||
3627 | track->textures[i].roundup_h = true; | ||
3628 | if (track->separate_cube) | ||
3629 | for (face = 0; face < 5; face++) { | ||
3630 | track->textures[i].cube_info[face].robj = NULL; | ||
3631 | track->textures[i].cube_info[face].width = 16536; | ||
3632 | track->textures[i].cube_info[face].height = 16536; | ||
3633 | track->textures[i].cube_info[face].offset = 0; | ||
3634 | } | ||
3635 | } | ||
3636 | } | ||
3637 | |||
3638 | int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | 3750 | int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) |
3639 | { | 3751 | { |
3640 | uint32_t scratch; | 3752 | uint32_t scratch; |
@@ -3679,6 +3791,12 @@ void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
3679 | { | 3791 | { |
3680 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 3792 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
3681 | 3793 | ||
3794 | if (ring->rptr_save_reg) { | ||
3795 | u32 next_rptr = ring->wptr + 2 + 3; | ||
3796 | radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0)); | ||
3797 | radeon_ring_write(ring, next_rptr); | ||
3798 | } | ||
3799 | |||
3682 | radeon_ring_write(ring, PACKET0(RADEON_CP_IB_BASE, 1)); | 3800 | radeon_ring_write(ring, PACKET0(RADEON_CP_IB_BASE, 1)); |
3683 | radeon_ring_write(ring, ib->gpu_addr); | 3801 | radeon_ring_write(ring, ib->gpu_addr); |
3684 | radeon_ring_write(ring, ib->length_dw); | 3802 | radeon_ring_write(ring, ib->length_dw); |
@@ -3711,7 +3829,7 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
3711 | ib.ptr[6] = PACKET2(0); | 3829 | ib.ptr[6] = PACKET2(0); |
3712 | ib.ptr[7] = PACKET2(0); | 3830 | ib.ptr[7] = PACKET2(0); |
3713 | ib.length_dw = 8; | 3831 | ib.length_dw = 8; |
3714 | r = radeon_ib_schedule(rdev, &ib); | 3832 | r = radeon_ib_schedule(rdev, &ib, NULL); |
3715 | if (r) { | 3833 | if (r) { |
3716 | radeon_scratch_free(rdev, scratch); | 3834 | radeon_scratch_free(rdev, scratch); |
3717 | radeon_ib_free(rdev, &ib); | 3835 | radeon_ib_free(rdev, &ib); |
@@ -3740,12 +3858,6 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
3740 | return r; | 3858 | return r; |
3741 | } | 3859 | } |
3742 | 3860 | ||
3743 | void r100_ib_fini(struct radeon_device *rdev) | ||
3744 | { | ||
3745 | radeon_ib_pool_suspend(rdev); | ||
3746 | radeon_ib_pool_fini(rdev); | ||
3747 | } | ||
3748 | |||
3749 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) | 3861 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) |
3750 | { | 3862 | { |
3751 | /* Shutdown CP we shouldn't need to do that but better be safe than | 3863 | /* Shutdown CP we shouldn't need to do that but better be safe than |
@@ -3905,13 +4017,11 @@ static int r100_startup(struct radeon_device *rdev) | |||
3905 | return r; | 4017 | return r; |
3906 | } | 4018 | } |
3907 | 4019 | ||
3908 | r = radeon_ib_pool_start(rdev); | 4020 | r = radeon_ib_pool_init(rdev); |
3909 | if (r) | 4021 | if (r) { |
3910 | return r; | 4022 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
3911 | |||
3912 | r = radeon_ib_ring_tests(rdev); | ||
3913 | if (r) | ||
3914 | return r; | 4023 | return r; |
4024 | } | ||
3915 | 4025 | ||
3916 | return 0; | 4026 | return 0; |
3917 | } | 4027 | } |
@@ -3948,7 +4058,6 @@ int r100_resume(struct radeon_device *rdev) | |||
3948 | 4058 | ||
3949 | int r100_suspend(struct radeon_device *rdev) | 4059 | int r100_suspend(struct radeon_device *rdev) |
3950 | { | 4060 | { |
3951 | radeon_ib_pool_suspend(rdev); | ||
3952 | r100_cp_disable(rdev); | 4061 | r100_cp_disable(rdev); |
3953 | radeon_wb_disable(rdev); | 4062 | radeon_wb_disable(rdev); |
3954 | r100_irq_disable(rdev); | 4063 | r100_irq_disable(rdev); |
@@ -3961,7 +4070,7 @@ void r100_fini(struct radeon_device *rdev) | |||
3961 | { | 4070 | { |
3962 | r100_cp_fini(rdev); | 4071 | r100_cp_fini(rdev); |
3963 | radeon_wb_fini(rdev); | 4072 | radeon_wb_fini(rdev); |
3964 | r100_ib_fini(rdev); | 4073 | radeon_ib_pool_fini(rdev); |
3965 | radeon_gem_fini(rdev); | 4074 | radeon_gem_fini(rdev); |
3966 | if (rdev->flags & RADEON_IS_PCI) | 4075 | if (rdev->flags & RADEON_IS_PCI) |
3967 | r100_pci_gart_fini(rdev); | 4076 | r100_pci_gart_fini(rdev); |
@@ -4068,20 +4177,14 @@ int r100_init(struct radeon_device *rdev) | |||
4068 | } | 4177 | } |
4069 | r100_set_safe_registers(rdev); | 4178 | r100_set_safe_registers(rdev); |
4070 | 4179 | ||
4071 | r = radeon_ib_pool_init(rdev); | ||
4072 | rdev->accel_working = true; | 4180 | rdev->accel_working = true; |
4073 | if (r) { | ||
4074 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
4075 | rdev->accel_working = false; | ||
4076 | } | ||
4077 | |||
4078 | r = r100_startup(rdev); | 4181 | r = r100_startup(rdev); |
4079 | if (r) { | 4182 | if (r) { |
4080 | /* Somethings want wront with the accel init stop accel */ | 4183 | /* Somethings want wront with the accel init stop accel */ |
4081 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 4184 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
4082 | r100_cp_fini(rdev); | 4185 | r100_cp_fini(rdev); |
4083 | radeon_wb_fini(rdev); | 4186 | radeon_wb_fini(rdev); |
4084 | r100_ib_fini(rdev); | 4187 | radeon_ib_pool_fini(rdev); |
4085 | radeon_irq_kms_fini(rdev); | 4188 | radeon_irq_kms_fini(rdev); |
4086 | if (rdev->flags & RADEON_IS_PCI) | 4189 | if (rdev->flags & RADEON_IS_PCI) |
4087 | r100_pci_gart_fini(rdev); | 4190 | r100_pci_gart_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index a26144d01207..f0889259eb08 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
@@ -85,7 +85,7 @@ int r200_copy_dma(struct radeon_device *rdev, | |||
85 | uint64_t src_offset, | 85 | uint64_t src_offset, |
86 | uint64_t dst_offset, | 86 | uint64_t dst_offset, |
87 | unsigned num_gpu_pages, | 87 | unsigned num_gpu_pages, |
88 | struct radeon_fence *fence) | 88 | struct radeon_fence **fence) |
89 | { | 89 | { |
90 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 90 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
91 | uint32_t size; | 91 | uint32_t size; |
@@ -120,7 +120,7 @@ int r200_copy_dma(struct radeon_device *rdev, | |||
120 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); | 120 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); |
121 | radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); | 121 | radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); |
122 | if (fence) { | 122 | if (fence) { |
123 | r = radeon_fence_emit(rdev, fence); | 123 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); |
124 | } | 124 | } |
125 | radeon_ring_unlock_commit(rdev, ring); | 125 | radeon_ring_unlock_commit(rdev, ring); |
126 | return r; | 126 | return r; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 97722a33e513..646a1927dda7 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -1391,13 +1391,11 @@ static int r300_startup(struct radeon_device *rdev) | |||
1391 | return r; | 1391 | return r; |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | r = radeon_ib_pool_start(rdev); | 1394 | r = radeon_ib_pool_init(rdev); |
1395 | if (r) | 1395 | if (r) { |
1396 | return r; | 1396 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
1397 | |||
1398 | r = radeon_ib_ring_tests(rdev); | ||
1399 | if (r) | ||
1400 | return r; | 1397 | return r; |
1398 | } | ||
1401 | 1399 | ||
1402 | return 0; | 1400 | return 0; |
1403 | } | 1401 | } |
@@ -1436,7 +1434,6 @@ int r300_resume(struct radeon_device *rdev) | |||
1436 | 1434 | ||
1437 | int r300_suspend(struct radeon_device *rdev) | 1435 | int r300_suspend(struct radeon_device *rdev) |
1438 | { | 1436 | { |
1439 | radeon_ib_pool_suspend(rdev); | ||
1440 | r100_cp_disable(rdev); | 1437 | r100_cp_disable(rdev); |
1441 | radeon_wb_disable(rdev); | 1438 | radeon_wb_disable(rdev); |
1442 | r100_irq_disable(rdev); | 1439 | r100_irq_disable(rdev); |
@@ -1451,7 +1448,7 @@ void r300_fini(struct radeon_device *rdev) | |||
1451 | { | 1448 | { |
1452 | r100_cp_fini(rdev); | 1449 | r100_cp_fini(rdev); |
1453 | radeon_wb_fini(rdev); | 1450 | radeon_wb_fini(rdev); |
1454 | r100_ib_fini(rdev); | 1451 | radeon_ib_pool_fini(rdev); |
1455 | radeon_gem_fini(rdev); | 1452 | radeon_gem_fini(rdev); |
1456 | if (rdev->flags & RADEON_IS_PCIE) | 1453 | if (rdev->flags & RADEON_IS_PCIE) |
1457 | rv370_pcie_gart_fini(rdev); | 1454 | rv370_pcie_gart_fini(rdev); |
@@ -1538,20 +1535,14 @@ int r300_init(struct radeon_device *rdev) | |||
1538 | } | 1535 | } |
1539 | r300_set_reg_safe(rdev); | 1536 | r300_set_reg_safe(rdev); |
1540 | 1537 | ||
1541 | r = radeon_ib_pool_init(rdev); | ||
1542 | rdev->accel_working = true; | 1538 | rdev->accel_working = true; |
1543 | if (r) { | ||
1544 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
1545 | rdev->accel_working = false; | ||
1546 | } | ||
1547 | |||
1548 | r = r300_startup(rdev); | 1539 | r = r300_startup(rdev); |
1549 | if (r) { | 1540 | if (r) { |
1550 | /* Somethings want wront with the accel init stop accel */ | 1541 | /* Somethings want wront with the accel init stop accel */ |
1551 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 1542 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
1552 | r100_cp_fini(rdev); | 1543 | r100_cp_fini(rdev); |
1553 | radeon_wb_fini(rdev); | 1544 | radeon_wb_fini(rdev); |
1554 | r100_ib_fini(rdev); | 1545 | radeon_ib_pool_fini(rdev); |
1555 | radeon_irq_kms_fini(rdev); | 1546 | radeon_irq_kms_fini(rdev); |
1556 | if (rdev->flags & RADEON_IS_PCIE) | 1547 | if (rdev->flags & RADEON_IS_PCIE) |
1557 | rv370_pcie_gart_fini(rdev); | 1548 | rv370_pcie_gart_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 99137be7a300..f2f5bf6d339f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -275,13 +275,11 @@ static int r420_startup(struct radeon_device *rdev) | |||
275 | } | 275 | } |
276 | r420_cp_errata_init(rdev); | 276 | r420_cp_errata_init(rdev); |
277 | 277 | ||
278 | r = radeon_ib_pool_start(rdev); | 278 | r = radeon_ib_pool_init(rdev); |
279 | if (r) | 279 | if (r) { |
280 | return r; | 280 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
281 | |||
282 | r = radeon_ib_ring_tests(rdev); | ||
283 | if (r) | ||
284 | return r; | 281 | return r; |
282 | } | ||
285 | 283 | ||
286 | return 0; | 284 | return 0; |
287 | } | 285 | } |
@@ -324,7 +322,6 @@ int r420_resume(struct radeon_device *rdev) | |||
324 | 322 | ||
325 | int r420_suspend(struct radeon_device *rdev) | 323 | int r420_suspend(struct radeon_device *rdev) |
326 | { | 324 | { |
327 | radeon_ib_pool_suspend(rdev); | ||
328 | r420_cp_errata_fini(rdev); | 325 | r420_cp_errata_fini(rdev); |
329 | r100_cp_disable(rdev); | 326 | r100_cp_disable(rdev); |
330 | radeon_wb_disable(rdev); | 327 | radeon_wb_disable(rdev); |
@@ -340,7 +337,7 @@ void r420_fini(struct radeon_device *rdev) | |||
340 | { | 337 | { |
341 | r100_cp_fini(rdev); | 338 | r100_cp_fini(rdev); |
342 | radeon_wb_fini(rdev); | 339 | radeon_wb_fini(rdev); |
343 | r100_ib_fini(rdev); | 340 | radeon_ib_pool_fini(rdev); |
344 | radeon_gem_fini(rdev); | 341 | radeon_gem_fini(rdev); |
345 | if (rdev->flags & RADEON_IS_PCIE) | 342 | if (rdev->flags & RADEON_IS_PCIE) |
346 | rv370_pcie_gart_fini(rdev); | 343 | rv370_pcie_gart_fini(rdev); |
@@ -438,20 +435,14 @@ int r420_init(struct radeon_device *rdev) | |||
438 | } | 435 | } |
439 | r420_set_reg_safe(rdev); | 436 | r420_set_reg_safe(rdev); |
440 | 437 | ||
441 | r = radeon_ib_pool_init(rdev); | ||
442 | rdev->accel_working = true; | 438 | rdev->accel_working = true; |
443 | if (r) { | ||
444 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
445 | rdev->accel_working = false; | ||
446 | } | ||
447 | |||
448 | r = r420_startup(rdev); | 439 | r = r420_startup(rdev); |
449 | if (r) { | 440 | if (r) { |
450 | /* Somethings want wront with the accel init stop accel */ | 441 | /* Somethings want wront with the accel init stop accel */ |
451 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 442 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
452 | r100_cp_fini(rdev); | 443 | r100_cp_fini(rdev); |
453 | radeon_wb_fini(rdev); | 444 | radeon_wb_fini(rdev); |
454 | r100_ib_fini(rdev); | 445 | radeon_ib_pool_fini(rdev); |
455 | radeon_irq_kms_fini(rdev); | 446 | radeon_irq_kms_fini(rdev); |
456 | if (rdev->flags & RADEON_IS_PCIE) | 447 | if (rdev->flags & RADEON_IS_PCIE) |
457 | rv370_pcie_gart_fini(rdev); | 448 | rv370_pcie_gart_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index b5cf8375cd25..079d3c52c08a 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -203,13 +203,11 @@ static int r520_startup(struct radeon_device *rdev) | |||
203 | return r; | 203 | return r; |
204 | } | 204 | } |
205 | 205 | ||
206 | r = radeon_ib_pool_start(rdev); | 206 | r = radeon_ib_pool_init(rdev); |
207 | if (r) | 207 | if (r) { |
208 | return r; | 208 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
209 | |||
210 | r = radeon_ib_ring_tests(rdev); | ||
211 | if (r) | ||
212 | return r; | 209 | return r; |
210 | } | ||
213 | 211 | ||
214 | return 0; | 212 | return 0; |
215 | } | 213 | } |
@@ -311,20 +309,14 @@ int r520_init(struct radeon_device *rdev) | |||
311 | return r; | 309 | return r; |
312 | rv515_set_safe_registers(rdev); | 310 | rv515_set_safe_registers(rdev); |
313 | 311 | ||
314 | r = radeon_ib_pool_init(rdev); | ||
315 | rdev->accel_working = true; | 312 | rdev->accel_working = true; |
316 | if (r) { | ||
317 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
318 | rdev->accel_working = false; | ||
319 | } | ||
320 | |||
321 | r = r520_startup(rdev); | 313 | r = r520_startup(rdev); |
322 | if (r) { | 314 | if (r) { |
323 | /* Somethings want wront with the accel init stop accel */ | 315 | /* Somethings want wront with the accel init stop accel */ |
324 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 316 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
325 | r100_cp_fini(rdev); | 317 | r100_cp_fini(rdev); |
326 | radeon_wb_fini(rdev); | 318 | radeon_wb_fini(rdev); |
327 | r100_ib_fini(rdev); | 319 | radeon_ib_pool_fini(rdev); |
328 | radeon_irq_kms_fini(rdev); | 320 | radeon_irq_kms_fini(rdev); |
329 | rv370_pcie_gart_fini(rdev); | 321 | rv370_pcie_gart_fini(rdev); |
330 | radeon_agp_fini(rdev); | 322 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index bff627293812..637280f541a3 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -709,6 +709,7 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
709 | { | 709 | { |
710 | struct drm_device *dev = rdev->ddev; | 710 | struct drm_device *dev = rdev->ddev; |
711 | struct drm_connector *connector; | 711 | struct drm_connector *connector; |
712 | unsigned enable = 0; | ||
712 | 713 | ||
713 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 714 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
714 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 715 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -729,28 +730,22 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
729 | switch (radeon_connector->hpd.hpd) { | 730 | switch (radeon_connector->hpd.hpd) { |
730 | case RADEON_HPD_1: | 731 | case RADEON_HPD_1: |
731 | WREG32(DC_HPD1_CONTROL, tmp); | 732 | WREG32(DC_HPD1_CONTROL, tmp); |
732 | rdev->irq.hpd[0] = true; | ||
733 | break; | 733 | break; |
734 | case RADEON_HPD_2: | 734 | case RADEON_HPD_2: |
735 | WREG32(DC_HPD2_CONTROL, tmp); | 735 | WREG32(DC_HPD2_CONTROL, tmp); |
736 | rdev->irq.hpd[1] = true; | ||
737 | break; | 736 | break; |
738 | case RADEON_HPD_3: | 737 | case RADEON_HPD_3: |
739 | WREG32(DC_HPD3_CONTROL, tmp); | 738 | WREG32(DC_HPD3_CONTROL, tmp); |
740 | rdev->irq.hpd[2] = true; | ||
741 | break; | 739 | break; |
742 | case RADEON_HPD_4: | 740 | case RADEON_HPD_4: |
743 | WREG32(DC_HPD4_CONTROL, tmp); | 741 | WREG32(DC_HPD4_CONTROL, tmp); |
744 | rdev->irq.hpd[3] = true; | ||
745 | break; | 742 | break; |
746 | /* DCE 3.2 */ | 743 | /* DCE 3.2 */ |
747 | case RADEON_HPD_5: | 744 | case RADEON_HPD_5: |
748 | WREG32(DC_HPD5_CONTROL, tmp); | 745 | WREG32(DC_HPD5_CONTROL, tmp); |
749 | rdev->irq.hpd[4] = true; | ||
750 | break; | 746 | break; |
751 | case RADEON_HPD_6: | 747 | case RADEON_HPD_6: |
752 | WREG32(DC_HPD6_CONTROL, tmp); | 748 | WREG32(DC_HPD6_CONTROL, tmp); |
753 | rdev->irq.hpd[5] = true; | ||
754 | break; | 749 | break; |
755 | default: | 750 | default: |
756 | break; | 751 | break; |
@@ -759,85 +754,73 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
759 | switch (radeon_connector->hpd.hpd) { | 754 | switch (radeon_connector->hpd.hpd) { |
760 | case RADEON_HPD_1: | 755 | case RADEON_HPD_1: |
761 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | 756 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
762 | rdev->irq.hpd[0] = true; | ||
763 | break; | 757 | break; |
764 | case RADEON_HPD_2: | 758 | case RADEON_HPD_2: |
765 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); | 759 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
766 | rdev->irq.hpd[1] = true; | ||
767 | break; | 760 | break; |
768 | case RADEON_HPD_3: | 761 | case RADEON_HPD_3: |
769 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); | 762 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
770 | rdev->irq.hpd[2] = true; | ||
771 | break; | 763 | break; |
772 | default: | 764 | default: |
773 | break; | 765 | break; |
774 | } | 766 | } |
775 | } | 767 | } |
768 | enable |= 1 << radeon_connector->hpd.hpd; | ||
776 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 769 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
777 | } | 770 | } |
778 | if (rdev->irq.installed) | 771 | radeon_irq_kms_enable_hpd(rdev, enable); |
779 | r600_irq_set(rdev); | ||
780 | } | 772 | } |
781 | 773 | ||
782 | void r600_hpd_fini(struct radeon_device *rdev) | 774 | void r600_hpd_fini(struct radeon_device *rdev) |
783 | { | 775 | { |
784 | struct drm_device *dev = rdev->ddev; | 776 | struct drm_device *dev = rdev->ddev; |
785 | struct drm_connector *connector; | 777 | struct drm_connector *connector; |
778 | unsigned disable = 0; | ||
786 | 779 | ||
787 | if (ASIC_IS_DCE3(rdev)) { | 780 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
788 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 781 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
789 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 782 | if (ASIC_IS_DCE3(rdev)) { |
790 | switch (radeon_connector->hpd.hpd) { | 783 | switch (radeon_connector->hpd.hpd) { |
791 | case RADEON_HPD_1: | 784 | case RADEON_HPD_1: |
792 | WREG32(DC_HPD1_CONTROL, 0); | 785 | WREG32(DC_HPD1_CONTROL, 0); |
793 | rdev->irq.hpd[0] = false; | ||
794 | break; | 786 | break; |
795 | case RADEON_HPD_2: | 787 | case RADEON_HPD_2: |
796 | WREG32(DC_HPD2_CONTROL, 0); | 788 | WREG32(DC_HPD2_CONTROL, 0); |
797 | rdev->irq.hpd[1] = false; | ||
798 | break; | 789 | break; |
799 | case RADEON_HPD_3: | 790 | case RADEON_HPD_3: |
800 | WREG32(DC_HPD3_CONTROL, 0); | 791 | WREG32(DC_HPD3_CONTROL, 0); |
801 | rdev->irq.hpd[2] = false; | ||
802 | break; | 792 | break; |
803 | case RADEON_HPD_4: | 793 | case RADEON_HPD_4: |
804 | WREG32(DC_HPD4_CONTROL, 0); | 794 | WREG32(DC_HPD4_CONTROL, 0); |
805 | rdev->irq.hpd[3] = false; | ||
806 | break; | 795 | break; |
807 | /* DCE 3.2 */ | 796 | /* DCE 3.2 */ |
808 | case RADEON_HPD_5: | 797 | case RADEON_HPD_5: |
809 | WREG32(DC_HPD5_CONTROL, 0); | 798 | WREG32(DC_HPD5_CONTROL, 0); |
810 | rdev->irq.hpd[4] = false; | ||
811 | break; | 799 | break; |
812 | case RADEON_HPD_6: | 800 | case RADEON_HPD_6: |
813 | WREG32(DC_HPD6_CONTROL, 0); | 801 | WREG32(DC_HPD6_CONTROL, 0); |
814 | rdev->irq.hpd[5] = false; | ||
815 | break; | 802 | break; |
816 | default: | 803 | default: |
817 | break; | 804 | break; |
818 | } | 805 | } |
819 | } | 806 | } else { |
820 | } else { | ||
821 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
822 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
823 | switch (radeon_connector->hpd.hpd) { | 807 | switch (radeon_connector->hpd.hpd) { |
824 | case RADEON_HPD_1: | 808 | case RADEON_HPD_1: |
825 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); | 809 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); |
826 | rdev->irq.hpd[0] = false; | ||
827 | break; | 810 | break; |
828 | case RADEON_HPD_2: | 811 | case RADEON_HPD_2: |
829 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); | 812 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); |
830 | rdev->irq.hpd[1] = false; | ||
831 | break; | 813 | break; |
832 | case RADEON_HPD_3: | 814 | case RADEON_HPD_3: |
833 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); | 815 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); |
834 | rdev->irq.hpd[2] = false; | ||
835 | break; | 816 | break; |
836 | default: | 817 | default: |
837 | break; | 818 | break; |
838 | } | 819 | } |
839 | } | 820 | } |
821 | disable |= 1 << radeon_connector->hpd.hpd; | ||
840 | } | 822 | } |
823 | radeon_irq_kms_disable_hpd(rdev, disable); | ||
841 | } | 824 | } |
842 | 825 | ||
843 | /* | 826 | /* |
@@ -1306,6 +1289,14 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
1306 | RREG32(R_008014_GRBM_STATUS2)); | 1289 | RREG32(R_008014_GRBM_STATUS2)); |
1307 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", | 1290 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", |
1308 | RREG32(R_000E50_SRBM_STATUS)); | 1291 | RREG32(R_000E50_SRBM_STATUS)); |
1292 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | ||
1293 | RREG32(CP_STALLED_STAT1)); | ||
1294 | dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", | ||
1295 | RREG32(CP_STALLED_STAT2)); | ||
1296 | dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", | ||
1297 | RREG32(CP_BUSY_STAT)); | ||
1298 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | ||
1299 | RREG32(CP_STAT)); | ||
1309 | rv515_mc_stop(rdev, &save); | 1300 | rv515_mc_stop(rdev, &save); |
1310 | if (r600_mc_wait_for_idle(rdev)) { | 1301 | if (r600_mc_wait_for_idle(rdev)) { |
1311 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | 1302 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); |
@@ -1349,6 +1340,14 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
1349 | RREG32(R_008014_GRBM_STATUS2)); | 1340 | RREG32(R_008014_GRBM_STATUS2)); |
1350 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", | 1341 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", |
1351 | RREG32(R_000E50_SRBM_STATUS)); | 1342 | RREG32(R_000E50_SRBM_STATUS)); |
1343 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | ||
1344 | RREG32(CP_STALLED_STAT1)); | ||
1345 | dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", | ||
1346 | RREG32(CP_STALLED_STAT2)); | ||
1347 | dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", | ||
1348 | RREG32(CP_BUSY_STAT)); | ||
1349 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | ||
1350 | RREG32(CP_STAT)); | ||
1352 | rv515_mc_resume(rdev, &save); | 1351 | rv515_mc_resume(rdev, &save); |
1353 | return 0; | 1352 | return 0; |
1354 | } | 1353 | } |
@@ -2172,18 +2171,29 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2172 | void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) | 2171 | void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) |
2173 | { | 2172 | { |
2174 | u32 rb_bufsz; | 2173 | u32 rb_bufsz; |
2174 | int r; | ||
2175 | 2175 | ||
2176 | /* Align ring size */ | 2176 | /* Align ring size */ |
2177 | rb_bufsz = drm_order(ring_size / 8); | 2177 | rb_bufsz = drm_order(ring_size / 8); |
2178 | ring_size = (1 << (rb_bufsz + 1)) * 4; | 2178 | ring_size = (1 << (rb_bufsz + 1)) * 4; |
2179 | ring->ring_size = ring_size; | 2179 | ring->ring_size = ring_size; |
2180 | ring->align_mask = 16 - 1; | 2180 | ring->align_mask = 16 - 1; |
2181 | |||
2182 | if (radeon_ring_supports_scratch_reg(rdev, ring)) { | ||
2183 | r = radeon_scratch_get(rdev, &ring->rptr_save_reg); | ||
2184 | if (r) { | ||
2185 | DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); | ||
2186 | ring->rptr_save_reg = 0; | ||
2187 | } | ||
2188 | } | ||
2181 | } | 2189 | } |
2182 | 2190 | ||
2183 | void r600_cp_fini(struct radeon_device *rdev) | 2191 | void r600_cp_fini(struct radeon_device *rdev) |
2184 | { | 2192 | { |
2193 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
2185 | r600_cp_stop(rdev); | 2194 | r600_cp_stop(rdev); |
2186 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 2195 | radeon_ring_fini(rdev, ring); |
2196 | radeon_scratch_free(rdev, ring->rptr_save_reg); | ||
2187 | } | 2197 | } |
2188 | 2198 | ||
2189 | 2199 | ||
@@ -2206,7 +2216,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2206 | { | 2216 | { |
2207 | uint32_t scratch; | 2217 | uint32_t scratch; |
2208 | uint32_t tmp = 0; | 2218 | uint32_t tmp = 0; |
2209 | unsigned i, ridx = radeon_ring_index(rdev, ring); | 2219 | unsigned i; |
2210 | int r; | 2220 | int r; |
2211 | 2221 | ||
2212 | r = radeon_scratch_get(rdev, &scratch); | 2222 | r = radeon_scratch_get(rdev, &scratch); |
@@ -2217,7 +2227,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2217 | WREG32(scratch, 0xCAFEDEAD); | 2227 | WREG32(scratch, 0xCAFEDEAD); |
2218 | r = radeon_ring_lock(rdev, ring, 3); | 2228 | r = radeon_ring_lock(rdev, ring, 3); |
2219 | if (r) { | 2229 | if (r) { |
2220 | DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r); | 2230 | DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ring->idx, r); |
2221 | radeon_scratch_free(rdev, scratch); | 2231 | radeon_scratch_free(rdev, scratch); |
2222 | return r; | 2232 | return r; |
2223 | } | 2233 | } |
@@ -2232,10 +2242,10 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2232 | DRM_UDELAY(1); | 2242 | DRM_UDELAY(1); |
2233 | } | 2243 | } |
2234 | if (i < rdev->usec_timeout) { | 2244 | if (i < rdev->usec_timeout) { |
2235 | DRM_INFO("ring test on %d succeeded in %d usecs\n", ridx, i); | 2245 | DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); |
2236 | } else { | 2246 | } else { |
2237 | DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n", | 2247 | DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n", |
2238 | ridx, scratch, tmp); | 2248 | ring->idx, scratch, tmp); |
2239 | r = -EINVAL; | 2249 | r = -EINVAL; |
2240 | } | 2250 | } |
2241 | radeon_scratch_free(rdev, scratch); | 2251 | radeon_scratch_free(rdev, scratch); |
@@ -2309,34 +2319,21 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
2309 | uint64_t src_offset, | 2319 | uint64_t src_offset, |
2310 | uint64_t dst_offset, | 2320 | uint64_t dst_offset, |
2311 | unsigned num_gpu_pages, | 2321 | unsigned num_gpu_pages, |
2312 | struct radeon_fence *fence) | 2322 | struct radeon_fence **fence) |
2313 | { | 2323 | { |
2324 | struct radeon_semaphore *sem = NULL; | ||
2314 | struct radeon_sa_bo *vb = NULL; | 2325 | struct radeon_sa_bo *vb = NULL; |
2315 | int r; | 2326 | int r; |
2316 | 2327 | ||
2317 | r = r600_blit_prepare_copy(rdev, num_gpu_pages, &vb); | 2328 | r = r600_blit_prepare_copy(rdev, num_gpu_pages, fence, &vb, &sem); |
2318 | if (r) { | 2329 | if (r) { |
2319 | return r; | 2330 | return r; |
2320 | } | 2331 | } |
2321 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages, vb); | 2332 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages, vb); |
2322 | r600_blit_done_copy(rdev, fence, vb); | 2333 | r600_blit_done_copy(rdev, fence, vb, sem); |
2323 | return 0; | 2334 | return 0; |
2324 | } | 2335 | } |
2325 | 2336 | ||
2326 | void r600_blit_suspend(struct radeon_device *rdev) | ||
2327 | { | ||
2328 | int r; | ||
2329 | |||
2330 | /* unpin shaders bo */ | ||
2331 | if (rdev->r600_blit.shader_obj) { | ||
2332 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
2333 | if (!r) { | ||
2334 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
2335 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
2336 | } | ||
2337 | } | ||
2338 | } | ||
2339 | |||
2340 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, | 2337 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, |
2341 | uint32_t tiling_flags, uint32_t pitch, | 2338 | uint32_t tiling_flags, uint32_t pitch, |
2342 | uint32_t offset, uint32_t obj_size) | 2339 | uint32_t offset, uint32_t obj_size) |
@@ -2419,13 +2416,11 @@ int r600_startup(struct radeon_device *rdev) | |||
2419 | if (r) | 2416 | if (r) |
2420 | return r; | 2417 | return r; |
2421 | 2418 | ||
2422 | r = radeon_ib_pool_start(rdev); | 2419 | r = radeon_ib_pool_init(rdev); |
2423 | if (r) | 2420 | if (r) { |
2424 | return r; | 2421 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
2425 | |||
2426 | r = radeon_ib_ring_tests(rdev); | ||
2427 | if (r) | ||
2428 | return r; | 2422 | return r; |
2423 | } | ||
2429 | 2424 | ||
2430 | r = r600_audio_init(rdev); | 2425 | r = r600_audio_init(rdev); |
2431 | if (r) { | 2426 | if (r) { |
@@ -2475,9 +2470,6 @@ int r600_resume(struct radeon_device *rdev) | |||
2475 | int r600_suspend(struct radeon_device *rdev) | 2470 | int r600_suspend(struct radeon_device *rdev) |
2476 | { | 2471 | { |
2477 | r600_audio_fini(rdev); | 2472 | r600_audio_fini(rdev); |
2478 | radeon_ib_pool_suspend(rdev); | ||
2479 | r600_blit_suspend(rdev); | ||
2480 | /* FIXME: we should wait for ring to be empty */ | ||
2481 | r600_cp_stop(rdev); | 2473 | r600_cp_stop(rdev); |
2482 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 2474 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
2483 | r600_irq_suspend(rdev); | 2475 | r600_irq_suspend(rdev); |
@@ -2559,20 +2551,14 @@ int r600_init(struct radeon_device *rdev) | |||
2559 | if (r) | 2551 | if (r) |
2560 | return r; | 2552 | return r; |
2561 | 2553 | ||
2562 | r = radeon_ib_pool_init(rdev); | ||
2563 | rdev->accel_working = true; | 2554 | rdev->accel_working = true; |
2564 | if (r) { | ||
2565 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
2566 | rdev->accel_working = false; | ||
2567 | } | ||
2568 | |||
2569 | r = r600_startup(rdev); | 2555 | r = r600_startup(rdev); |
2570 | if (r) { | 2556 | if (r) { |
2571 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 2557 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2572 | r600_cp_fini(rdev); | 2558 | r600_cp_fini(rdev); |
2573 | r600_irq_fini(rdev); | 2559 | r600_irq_fini(rdev); |
2574 | radeon_wb_fini(rdev); | 2560 | radeon_wb_fini(rdev); |
2575 | r100_ib_fini(rdev); | 2561 | radeon_ib_pool_fini(rdev); |
2576 | radeon_irq_kms_fini(rdev); | 2562 | radeon_irq_kms_fini(rdev); |
2577 | r600_pcie_gart_fini(rdev); | 2563 | r600_pcie_gart_fini(rdev); |
2578 | rdev->accel_working = false; | 2564 | rdev->accel_working = false; |
@@ -2588,7 +2574,7 @@ void r600_fini(struct radeon_device *rdev) | |||
2588 | r600_cp_fini(rdev); | 2574 | r600_cp_fini(rdev); |
2589 | r600_irq_fini(rdev); | 2575 | r600_irq_fini(rdev); |
2590 | radeon_wb_fini(rdev); | 2576 | radeon_wb_fini(rdev); |
2591 | r100_ib_fini(rdev); | 2577 | radeon_ib_pool_fini(rdev); |
2592 | radeon_irq_kms_fini(rdev); | 2578 | radeon_irq_kms_fini(rdev); |
2593 | r600_pcie_gart_fini(rdev); | 2579 | r600_pcie_gart_fini(rdev); |
2594 | r600_vram_scratch_fini(rdev); | 2580 | r600_vram_scratch_fini(rdev); |
@@ -2607,9 +2593,24 @@ void r600_fini(struct radeon_device *rdev) | |||
2607 | */ | 2593 | */ |
2608 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 2594 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
2609 | { | 2595 | { |
2610 | struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; | 2596 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
2597 | u32 next_rptr; | ||
2598 | |||
2599 | if (ring->rptr_save_reg) { | ||
2600 | next_rptr = ring->wptr + 3 + 4; | ||
2601 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
2602 | radeon_ring_write(ring, ((ring->rptr_save_reg - | ||
2603 | PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | ||
2604 | radeon_ring_write(ring, next_rptr); | ||
2605 | } else if (rdev->wb.enabled) { | ||
2606 | next_rptr = ring->wptr + 5 + 4; | ||
2607 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3)); | ||
2608 | radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
2609 | radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18)); | ||
2610 | radeon_ring_write(ring, next_rptr); | ||
2611 | radeon_ring_write(ring, 0); | ||
2612 | } | ||
2611 | 2613 | ||
2612 | /* FIXME: implement */ | ||
2613 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 2614 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
2614 | radeon_ring_write(ring, | 2615 | radeon_ring_write(ring, |
2615 | #ifdef __BIG_ENDIAN | 2616 | #ifdef __BIG_ENDIAN |
@@ -2627,7 +2628,6 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2627 | uint32_t tmp = 0; | 2628 | uint32_t tmp = 0; |
2628 | unsigned i; | 2629 | unsigned i; |
2629 | int r; | 2630 | int r; |
2630 | int ring_index = radeon_ring_index(rdev, ring); | ||
2631 | 2631 | ||
2632 | r = radeon_scratch_get(rdev, &scratch); | 2632 | r = radeon_scratch_get(rdev, &scratch); |
2633 | if (r) { | 2633 | if (r) { |
@@ -2635,7 +2635,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2635 | return r; | 2635 | return r; |
2636 | } | 2636 | } |
2637 | WREG32(scratch, 0xCAFEDEAD); | 2637 | WREG32(scratch, 0xCAFEDEAD); |
2638 | r = radeon_ib_get(rdev, ring_index, &ib, 256); | 2638 | r = radeon_ib_get(rdev, ring->idx, &ib, 256); |
2639 | if (r) { | 2639 | if (r) { |
2640 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); | 2640 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); |
2641 | return r; | 2641 | return r; |
@@ -2644,7 +2644,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2644 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2644 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
2645 | ib.ptr[2] = 0xDEADBEEF; | 2645 | ib.ptr[2] = 0xDEADBEEF; |
2646 | ib.length_dw = 3; | 2646 | ib.length_dw = 3; |
2647 | r = radeon_ib_schedule(rdev, &ib); | 2647 | r = radeon_ib_schedule(rdev, &ib, NULL); |
2648 | if (r) { | 2648 | if (r) { |
2649 | radeon_scratch_free(rdev, scratch); | 2649 | radeon_scratch_free(rdev, scratch); |
2650 | radeon_ib_free(rdev, &ib); | 2650 | radeon_ib_free(rdev, &ib); |
@@ -2857,7 +2857,6 @@ void r600_disable_interrupts(struct radeon_device *rdev) | |||
2857 | WREG32(IH_RB_RPTR, 0); | 2857 | WREG32(IH_RB_RPTR, 0); |
2858 | WREG32(IH_RB_WPTR, 0); | 2858 | WREG32(IH_RB_WPTR, 0); |
2859 | rdev->ih.enabled = false; | 2859 | rdev->ih.enabled = false; |
2860 | rdev->ih.wptr = 0; | ||
2861 | rdev->ih.rptr = 0; | 2860 | rdev->ih.rptr = 0; |
2862 | } | 2861 | } |
2863 | 2862 | ||
@@ -3042,18 +3041,18 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3042 | hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | 3041 | hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; |
3043 | } | 3042 | } |
3044 | 3043 | ||
3045 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 3044 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
3046 | DRM_DEBUG("r600_irq_set: sw int\n"); | 3045 | DRM_DEBUG("r600_irq_set: sw int\n"); |
3047 | cp_int_cntl |= RB_INT_ENABLE; | 3046 | cp_int_cntl |= RB_INT_ENABLE; |
3048 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 3047 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
3049 | } | 3048 | } |
3050 | if (rdev->irq.crtc_vblank_int[0] || | 3049 | if (rdev->irq.crtc_vblank_int[0] || |
3051 | rdev->irq.pflip[0]) { | 3050 | atomic_read(&rdev->irq.pflip[0])) { |
3052 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | 3051 | DRM_DEBUG("r600_irq_set: vblank 0\n"); |
3053 | mode_int |= D1MODE_VBLANK_INT_MASK; | 3052 | mode_int |= D1MODE_VBLANK_INT_MASK; |
3054 | } | 3053 | } |
3055 | if (rdev->irq.crtc_vblank_int[1] || | 3054 | if (rdev->irq.crtc_vblank_int[1] || |
3056 | rdev->irq.pflip[1]) { | 3055 | atomic_read(&rdev->irq.pflip[1])) { |
3057 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | 3056 | DRM_DEBUG("r600_irq_set: vblank 1\n"); |
3058 | mode_int |= D2MODE_VBLANK_INT_MASK; | 3057 | mode_int |= D2MODE_VBLANK_INT_MASK; |
3059 | } | 3058 | } |
@@ -3309,7 +3308,6 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3309 | u32 rptr; | 3308 | u32 rptr; |
3310 | u32 src_id, src_data; | 3309 | u32 src_id, src_data; |
3311 | u32 ring_index; | 3310 | u32 ring_index; |
3312 | unsigned long flags; | ||
3313 | bool queue_hotplug = false; | 3311 | bool queue_hotplug = false; |
3314 | bool queue_hdmi = false; | 3312 | bool queue_hdmi = false; |
3315 | 3313 | ||
@@ -3321,24 +3319,21 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3321 | RREG32(IH_RB_WPTR); | 3319 | RREG32(IH_RB_WPTR); |
3322 | 3320 | ||
3323 | wptr = r600_get_ih_wptr(rdev); | 3321 | wptr = r600_get_ih_wptr(rdev); |
3324 | rptr = rdev->ih.rptr; | ||
3325 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
3326 | |||
3327 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
3328 | 3322 | ||
3329 | if (rptr == wptr) { | 3323 | restart_ih: |
3330 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3324 | /* is somebody else already processing irqs? */ |
3325 | if (atomic_xchg(&rdev->ih.lock, 1)) | ||
3331 | return IRQ_NONE; | 3326 | return IRQ_NONE; |
3332 | } | ||
3333 | 3327 | ||
3334 | restart_ih: | 3328 | rptr = rdev->ih.rptr; |
3329 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
3330 | |||
3335 | /* Order reading of wptr vs. reading of IH ring data */ | 3331 | /* Order reading of wptr vs. reading of IH ring data */ |
3336 | rmb(); | 3332 | rmb(); |
3337 | 3333 | ||
3338 | /* display interrupts */ | 3334 | /* display interrupts */ |
3339 | r600_irq_ack(rdev); | 3335 | r600_irq_ack(rdev); |
3340 | 3336 | ||
3341 | rdev->ih.wptr = wptr; | ||
3342 | while (rptr != wptr) { | 3337 | while (rptr != wptr) { |
3343 | /* wptr/rptr are in bytes! */ | 3338 | /* wptr/rptr are in bytes! */ |
3344 | ring_index = rptr / 4; | 3339 | ring_index = rptr / 4; |
@@ -3355,7 +3350,7 @@ restart_ih: | |||
3355 | rdev->pm.vblank_sync = true; | 3350 | rdev->pm.vblank_sync = true; |
3356 | wake_up(&rdev->irq.vblank_queue); | 3351 | wake_up(&rdev->irq.vblank_queue); |
3357 | } | 3352 | } |
3358 | if (rdev->irq.pflip[0]) | 3353 | if (atomic_read(&rdev->irq.pflip[0])) |
3359 | radeon_crtc_handle_flip(rdev, 0); | 3354 | radeon_crtc_handle_flip(rdev, 0); |
3360 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 3355 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; |
3361 | DRM_DEBUG("IH: D1 vblank\n"); | 3356 | DRM_DEBUG("IH: D1 vblank\n"); |
@@ -3381,7 +3376,7 @@ restart_ih: | |||
3381 | rdev->pm.vblank_sync = true; | 3376 | rdev->pm.vblank_sync = true; |
3382 | wake_up(&rdev->irq.vblank_queue); | 3377 | wake_up(&rdev->irq.vblank_queue); |
3383 | } | 3378 | } |
3384 | if (rdev->irq.pflip[1]) | 3379 | if (atomic_read(&rdev->irq.pflip[1])) |
3385 | radeon_crtc_handle_flip(rdev, 1); | 3380 | radeon_crtc_handle_flip(rdev, 1); |
3386 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; | 3381 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; |
3387 | DRM_DEBUG("IH: D2 vblank\n"); | 3382 | DRM_DEBUG("IH: D2 vblank\n"); |
@@ -3480,7 +3475,6 @@ restart_ih: | |||
3480 | break; | 3475 | break; |
3481 | case 233: /* GUI IDLE */ | 3476 | case 233: /* GUI IDLE */ |
3482 | DRM_DEBUG("IH: GUI idle\n"); | 3477 | DRM_DEBUG("IH: GUI idle\n"); |
3483 | rdev->pm.gui_idle = true; | ||
3484 | wake_up(&rdev->irq.idle_queue); | 3478 | wake_up(&rdev->irq.idle_queue); |
3485 | break; | 3479 | break; |
3486 | default: | 3480 | default: |
@@ -3492,17 +3486,19 @@ restart_ih: | |||
3492 | rptr += 16; | 3486 | rptr += 16; |
3493 | rptr &= rdev->ih.ptr_mask; | 3487 | rptr &= rdev->ih.ptr_mask; |
3494 | } | 3488 | } |
3495 | /* make sure wptr hasn't changed while processing */ | ||
3496 | wptr = r600_get_ih_wptr(rdev); | ||
3497 | if (wptr != rdev->ih.wptr) | ||
3498 | goto restart_ih; | ||
3499 | if (queue_hotplug) | 3489 | if (queue_hotplug) |
3500 | schedule_work(&rdev->hotplug_work); | 3490 | schedule_work(&rdev->hotplug_work); |
3501 | if (queue_hdmi) | 3491 | if (queue_hdmi) |
3502 | schedule_work(&rdev->audio_work); | 3492 | schedule_work(&rdev->audio_work); |
3503 | rdev->ih.rptr = rptr; | 3493 | rdev->ih.rptr = rptr; |
3504 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3494 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3505 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3495 | atomic_set(&rdev->ih.lock, 0); |
3496 | |||
3497 | /* make sure wptr hasn't changed while processing */ | ||
3498 | wptr = r600_get_ih_wptr(rdev); | ||
3499 | if (wptr != rptr) | ||
3500 | goto restart_ih; | ||
3501 | |||
3506 | return IRQ_HANDLED; | 3502 | return IRQ_HANDLED; |
3507 | } | 3503 | } |
3508 | 3504 | ||
@@ -3685,6 +3681,8 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
3685 | { | 3681 | { |
3686 | u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; | 3682 | u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; |
3687 | u16 link_cntl2; | 3683 | u16 link_cntl2; |
3684 | u32 mask; | ||
3685 | int ret; | ||
3688 | 3686 | ||
3689 | if (radeon_pcie_gen2 == 0) | 3687 | if (radeon_pcie_gen2 == 0) |
3690 | return; | 3688 | return; |
@@ -3703,6 +3701,15 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
3703 | if (rdev->family <= CHIP_R600) | 3701 | if (rdev->family <= CHIP_R600) |
3704 | return; | 3702 | return; |
3705 | 3703 | ||
3704 | ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); | ||
3705 | if (ret != 0) | ||
3706 | return; | ||
3707 | |||
3708 | if (!(mask & DRM_PCIE_SPEED_50)) | ||
3709 | return; | ||
3710 | |||
3711 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | ||
3712 | |||
3706 | /* 55 nm r6xx asics */ | 3713 | /* 55 nm r6xx asics */ |
3707 | if ((rdev->family == CHIP_RV670) || | 3714 | if ((rdev->family == CHIP_RV670) || |
3708 | (rdev->family == CHIP_RV620) || | 3715 | (rdev->family == CHIP_RV620) || |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 03b6e0d3d503..2bef8549ddfe 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -512,7 +512,8 @@ int r600_blit_init(struct radeon_device *rdev) | |||
512 | rdev->r600_blit.primitives.draw_auto = draw_auto; | 512 | rdev->r600_blit.primitives.draw_auto = draw_auto; |
513 | rdev->r600_blit.primitives.set_default_state = set_default_state; | 513 | rdev->r600_blit.primitives.set_default_state = set_default_state; |
514 | 514 | ||
515 | rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ | 515 | rdev->r600_blit.ring_size_common = 8; /* sync semaphore */ |
516 | rdev->r600_blit.ring_size_common += 40; /* shaders + def state */ | ||
516 | rdev->r600_blit.ring_size_common += 5; /* done copy */ | 517 | rdev->r600_blit.ring_size_common += 5; /* done copy */ |
517 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ | 518 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ |
518 | 519 | ||
@@ -523,10 +524,6 @@ int r600_blit_init(struct radeon_device *rdev) | |||
523 | 524 | ||
524 | rdev->r600_blit.max_dim = 8192; | 525 | rdev->r600_blit.max_dim = 8192; |
525 | 526 | ||
526 | /* pin copy shader into vram if already initialized */ | ||
527 | if (rdev->r600_blit.shader_obj) | ||
528 | goto done; | ||
529 | |||
530 | rdev->r600_blit.state_offset = 0; | 527 | rdev->r600_blit.state_offset = 0; |
531 | 528 | ||
532 | if (rdev->family >= CHIP_RV770) | 529 | if (rdev->family >= CHIP_RV770) |
@@ -551,11 +548,26 @@ int r600_blit_init(struct radeon_device *rdev) | |||
551 | obj_size += r6xx_ps_size * 4; | 548 | obj_size += r6xx_ps_size * 4; |
552 | obj_size = ALIGN(obj_size, 256); | 549 | obj_size = ALIGN(obj_size, 256); |
553 | 550 | ||
554 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 551 | /* pin copy shader into vram if not already initialized */ |
555 | NULL, &rdev->r600_blit.shader_obj); | 552 | if (rdev->r600_blit.shader_obj == NULL) { |
556 | if (r) { | 553 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, |
557 | DRM_ERROR("r600 failed to allocate shader\n"); | 554 | RADEON_GEM_DOMAIN_VRAM, |
558 | return r; | 555 | NULL, &rdev->r600_blit.shader_obj); |
556 | if (r) { | ||
557 | DRM_ERROR("r600 failed to allocate shader\n"); | ||
558 | return r; | ||
559 | } | ||
560 | |||
561 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
562 | if (unlikely(r != 0)) | ||
563 | return r; | ||
564 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
565 | &rdev->r600_blit.shader_gpu_addr); | ||
566 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
567 | if (r) { | ||
568 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
569 | return r; | ||
570 | } | ||
559 | } | 571 | } |
560 | 572 | ||
561 | DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n", | 573 | DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n", |
@@ -586,17 +598,6 @@ int r600_blit_init(struct radeon_device *rdev) | |||
586 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); | 598 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); |
587 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 599 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
588 | 600 | ||
589 | done: | ||
590 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
591 | if (unlikely(r != 0)) | ||
592 | return r; | ||
593 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
594 | &rdev->r600_blit.shader_gpu_addr); | ||
595 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
596 | if (r) { | ||
597 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
598 | return r; | ||
599 | } | ||
600 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); | 601 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
601 | return 0; | 602 | return 0; |
602 | } | 603 | } |
@@ -666,7 +667,8 @@ static unsigned r600_blit_create_rect(unsigned num_gpu_pages, | |||
666 | 667 | ||
667 | 668 | ||
668 | int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, | 669 | int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, |
669 | struct radeon_sa_bo **vb) | 670 | struct radeon_fence **fence, struct radeon_sa_bo **vb, |
671 | struct radeon_semaphore **sem) | ||
670 | { | 672 | { |
671 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 673 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
672 | int r; | 674 | int r; |
@@ -689,34 +691,50 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, | |||
689 | return r; | 691 | return r; |
690 | } | 692 | } |
691 | 693 | ||
694 | r = radeon_semaphore_create(rdev, sem); | ||
695 | if (r) { | ||
696 | radeon_sa_bo_free(rdev, vb, NULL); | ||
697 | return r; | ||
698 | } | ||
699 | |||
692 | /* calculate number of loops correctly */ | 700 | /* calculate number of loops correctly */ |
693 | ring_size = num_loops * dwords_per_loop; | 701 | ring_size = num_loops * dwords_per_loop; |
694 | ring_size += rdev->r600_blit.ring_size_common; | 702 | ring_size += rdev->r600_blit.ring_size_common; |
695 | r = radeon_ring_lock(rdev, ring, ring_size); | 703 | r = radeon_ring_lock(rdev, ring, ring_size); |
696 | if (r) { | 704 | if (r) { |
697 | radeon_sa_bo_free(rdev, vb, NULL); | 705 | radeon_sa_bo_free(rdev, vb, NULL); |
706 | radeon_semaphore_free(rdev, sem, NULL); | ||
698 | return r; | 707 | return r; |
699 | } | 708 | } |
700 | 709 | ||
710 | if (radeon_fence_need_sync(*fence, RADEON_RING_TYPE_GFX_INDEX)) { | ||
711 | radeon_semaphore_sync_rings(rdev, *sem, (*fence)->ring, | ||
712 | RADEON_RING_TYPE_GFX_INDEX); | ||
713 | radeon_fence_note_sync(*fence, RADEON_RING_TYPE_GFX_INDEX); | ||
714 | } else { | ||
715 | radeon_semaphore_free(rdev, sem, NULL); | ||
716 | } | ||
717 | |||
701 | rdev->r600_blit.primitives.set_default_state(rdev); | 718 | rdev->r600_blit.primitives.set_default_state(rdev); |
702 | rdev->r600_blit.primitives.set_shaders(rdev); | 719 | rdev->r600_blit.primitives.set_shaders(rdev); |
703 | return 0; | 720 | return 0; |
704 | } | 721 | } |
705 | 722 | ||
706 | void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence, | 723 | void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence **fence, |
707 | struct radeon_sa_bo *vb) | 724 | struct radeon_sa_bo *vb, struct radeon_semaphore *sem) |
708 | { | 725 | { |
709 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 726 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
710 | int r; | 727 | int r; |
711 | 728 | ||
712 | r = radeon_fence_emit(rdev, fence); | 729 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); |
713 | if (r) { | 730 | if (r) { |
714 | radeon_ring_unlock_undo(rdev, ring); | 731 | radeon_ring_unlock_undo(rdev, ring); |
715 | return; | 732 | return; |
716 | } | 733 | } |
717 | 734 | ||
718 | radeon_ring_unlock_commit(rdev, ring); | 735 | radeon_ring_unlock_commit(rdev, ring); |
719 | radeon_sa_bo_free(rdev, &vb, fence); | 736 | radeon_sa_bo_free(rdev, &vb, *fence); |
737 | radeon_semaphore_free(rdev, &sem, *fence); | ||
720 | } | 738 | } |
721 | 739 | ||
722 | void r600_kms_blit_copy(struct radeon_device *rdev, | 740 | void r600_kms_blit_copy(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 82a0a4c919c0..e3558c3ef24a 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -519,8 +519,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
519 | 519 | ||
520 | if (rdev->irq.installed) { | 520 | if (rdev->irq.installed) { |
521 | /* if irq is available use it */ | 521 | /* if irq is available use it */ |
522 | rdev->irq.afmt[dig->afmt->id] = true; | 522 | radeon_irq_kms_enable_afmt(rdev, dig->afmt->id); |
523 | radeon_irq_set(rdev); | ||
524 | } | 523 | } |
525 | 524 | ||
526 | dig->afmt->enabled = true; | 525 | dig->afmt->enabled = true; |
@@ -556,8 +555,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
556 | offset, radeon_encoder->encoder_id); | 555 | offset, radeon_encoder->encoder_id); |
557 | 556 | ||
558 | /* disable irq */ | 557 | /* disable irq */ |
559 | rdev->irq.afmt[dig->afmt->id] = false; | 558 | radeon_irq_kms_disable_afmt(rdev, dig->afmt->id); |
560 | radeon_irq_set(rdev); | ||
561 | 559 | ||
562 | /* Older chipsets not handled by AtomBIOS */ | 560 | /* Older chipsets not handled by AtomBIOS */ |
563 | if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { | 561 | if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 025fd5b6c08c..4b116ae75fc2 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -153,6 +153,9 @@ | |||
153 | 153 | ||
154 | #define CONFIG_MEMSIZE 0x5428 | 154 | #define CONFIG_MEMSIZE 0x5428 |
155 | #define CONFIG_CNTL 0x5424 | 155 | #define CONFIG_CNTL 0x5424 |
156 | #define CP_STALLED_STAT1 0x8674 | ||
157 | #define CP_STALLED_STAT2 0x8678 | ||
158 | #define CP_BUSY_STAT 0x867C | ||
156 | #define CP_STAT 0x8680 | 159 | #define CP_STAT 0x8680 |
157 | #define CP_COHER_BASE 0x85F8 | 160 | #define CP_COHER_BASE 0x85F8 |
158 | #define CP_DEBUG 0xC1FC | 161 | #define CP_DEBUG 0xC1FC |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index fefcca55c1eb..5431af292408 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -113,7 +113,6 @@ extern int radeon_lockup_timeout; | |||
113 | 113 | ||
114 | /* fence seq are set to this number when signaled */ | 114 | /* fence seq are set to this number when signaled */ |
115 | #define RADEON_FENCE_SIGNALED_SEQ 0LL | 115 | #define RADEON_FENCE_SIGNALED_SEQ 0LL |
116 | #define RADEON_FENCE_NOTEMITED_SEQ (~0LL) | ||
117 | 116 | ||
118 | /* internal ring indices */ | 117 | /* internal ring indices */ |
119 | /* r1xx+ has gfx CP ring */ | 118 | /* r1xx+ has gfx CP ring */ |
@@ -160,48 +159,6 @@ static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) | |||
160 | #endif | 159 | #endif |
161 | bool radeon_get_bios(struct radeon_device *rdev); | 160 | bool radeon_get_bios(struct radeon_device *rdev); |
162 | 161 | ||
163 | |||
164 | /* | ||
165 | * Mutex which allows recursive locking from the same process. | ||
166 | */ | ||
167 | struct radeon_mutex { | ||
168 | struct mutex mutex; | ||
169 | struct task_struct *owner; | ||
170 | int level; | ||
171 | }; | ||
172 | |||
173 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
174 | { | ||
175 | mutex_init(&mutex->mutex); | ||
176 | mutex->owner = NULL; | ||
177 | mutex->level = 0; | ||
178 | } | ||
179 | |||
180 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
181 | { | ||
182 | if (mutex_trylock(&mutex->mutex)) { | ||
183 | /* The mutex was unlocked before, so it's ours now */ | ||
184 | mutex->owner = current; | ||
185 | } else if (mutex->owner != current) { | ||
186 | /* Another process locked the mutex, take it */ | ||
187 | mutex_lock(&mutex->mutex); | ||
188 | mutex->owner = current; | ||
189 | } | ||
190 | /* Otherwise the mutex was already locked by this process */ | ||
191 | |||
192 | mutex->level++; | ||
193 | } | ||
194 | |||
195 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
196 | { | ||
197 | if (--mutex->level > 0) | ||
198 | return; | ||
199 | |||
200 | mutex->owner = NULL; | ||
201 | mutex_unlock(&mutex->mutex); | ||
202 | } | ||
203 | |||
204 | |||
205 | /* | 162 | /* |
206 | * Dummy page | 163 | * Dummy page |
207 | */ | 164 | */ |
@@ -258,8 +215,8 @@ struct radeon_fence_driver { | |||
258 | uint32_t scratch_reg; | 215 | uint32_t scratch_reg; |
259 | uint64_t gpu_addr; | 216 | uint64_t gpu_addr; |
260 | volatile uint32_t *cpu_addr; | 217 | volatile uint32_t *cpu_addr; |
261 | /* seq is protected by ring emission lock */ | 218 | /* sync_seq is protected by ring emission lock */ |
262 | uint64_t seq; | 219 | uint64_t sync_seq[RADEON_NUM_RINGS]; |
263 | atomic64_t last_seq; | 220 | atomic64_t last_seq; |
264 | unsigned long last_activity; | 221 | unsigned long last_activity; |
265 | bool initialized; | 222 | bool initialized; |
@@ -277,19 +234,39 @@ struct radeon_fence { | |||
277 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); | 234 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); |
278 | int radeon_fence_driver_init(struct radeon_device *rdev); | 235 | int radeon_fence_driver_init(struct radeon_device *rdev); |
279 | void radeon_fence_driver_fini(struct radeon_device *rdev); | 236 | void radeon_fence_driver_fini(struct radeon_device *rdev); |
280 | int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence, int ring); | 237 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring); |
281 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence); | ||
282 | void radeon_fence_process(struct radeon_device *rdev, int ring); | 238 | void radeon_fence_process(struct radeon_device *rdev, int ring); |
283 | bool radeon_fence_signaled(struct radeon_fence *fence); | 239 | bool radeon_fence_signaled(struct radeon_fence *fence); |
284 | int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); | 240 | int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); |
285 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); | 241 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); |
286 | int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); | 242 | void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); |
287 | int radeon_fence_wait_any(struct radeon_device *rdev, | 243 | int radeon_fence_wait_any(struct radeon_device *rdev, |
288 | struct radeon_fence **fences, | 244 | struct radeon_fence **fences, |
289 | bool intr); | 245 | bool intr); |
290 | struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); | 246 | struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); |
291 | void radeon_fence_unref(struct radeon_fence **fence); | 247 | void radeon_fence_unref(struct radeon_fence **fence); |
292 | unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring); | 248 | unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring); |
249 | bool radeon_fence_need_sync(struct radeon_fence *fence, int ring); | ||
250 | void radeon_fence_note_sync(struct radeon_fence *fence, int ring); | ||
251 | static inline struct radeon_fence *radeon_fence_later(struct radeon_fence *a, | ||
252 | struct radeon_fence *b) | ||
253 | { | ||
254 | if (!a) { | ||
255 | return b; | ||
256 | } | ||
257 | |||
258 | if (!b) { | ||
259 | return a; | ||
260 | } | ||
261 | |||
262 | BUG_ON(a->ring != b->ring); | ||
263 | |||
264 | if (a->seq > b->seq) { | ||
265 | return a; | ||
266 | } else { | ||
267 | return b; | ||
268 | } | ||
269 | } | ||
293 | 270 | ||
294 | /* | 271 | /* |
295 | * Tiling registers | 272 | * Tiling registers |
@@ -385,7 +362,7 @@ struct radeon_bo_list { | |||
385 | * alignment). | 362 | * alignment). |
386 | */ | 363 | */ |
387 | struct radeon_sa_manager { | 364 | struct radeon_sa_manager { |
388 | spinlock_t lock; | 365 | wait_queue_head_t wq; |
389 | struct radeon_bo *bo; | 366 | struct radeon_bo *bo; |
390 | struct list_head *hole; | 367 | struct list_head *hole; |
391 | struct list_head flist[RADEON_NUM_RINGS]; | 368 | struct list_head flist[RADEON_NUM_RINGS]; |
@@ -451,10 +428,9 @@ void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, | |||
451 | struct radeon_semaphore *semaphore); | 428 | struct radeon_semaphore *semaphore); |
452 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, | 429 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, |
453 | struct radeon_semaphore *semaphore, | 430 | struct radeon_semaphore *semaphore, |
454 | bool sync_to[RADEON_NUM_RINGS], | 431 | int signaler, int waiter); |
455 | int dst_ring); | ||
456 | void radeon_semaphore_free(struct radeon_device *rdev, | 432 | void radeon_semaphore_free(struct radeon_device *rdev, |
457 | struct radeon_semaphore *semaphore, | 433 | struct radeon_semaphore **semaphore, |
458 | struct radeon_fence *fence); | 434 | struct radeon_fence *fence); |
459 | 435 | ||
460 | /* | 436 | /* |
@@ -597,21 +573,18 @@ union radeon_irq_stat_regs { | |||
597 | #define RADEON_MAX_AFMT_BLOCKS 6 | 573 | #define RADEON_MAX_AFMT_BLOCKS 6 |
598 | 574 | ||
599 | struct radeon_irq { | 575 | struct radeon_irq { |
600 | bool installed; | 576 | bool installed; |
601 | bool sw_int[RADEON_NUM_RINGS]; | 577 | spinlock_t lock; |
602 | bool crtc_vblank_int[RADEON_MAX_CRTCS]; | 578 | atomic_t ring_int[RADEON_NUM_RINGS]; |
603 | bool pflip[RADEON_MAX_CRTCS]; | 579 | bool crtc_vblank_int[RADEON_MAX_CRTCS]; |
604 | wait_queue_head_t vblank_queue; | 580 | atomic_t pflip[RADEON_MAX_CRTCS]; |
605 | bool hpd[RADEON_MAX_HPD_PINS]; | 581 | wait_queue_head_t vblank_queue; |
606 | bool gui_idle; | 582 | bool hpd[RADEON_MAX_HPD_PINS]; |
607 | bool gui_idle_acked; | 583 | bool gui_idle; |
608 | wait_queue_head_t idle_queue; | 584 | bool gui_idle_acked; |
609 | bool afmt[RADEON_MAX_AFMT_BLOCKS]; | 585 | wait_queue_head_t idle_queue; |
610 | spinlock_t sw_lock; | 586 | bool afmt[RADEON_MAX_AFMT_BLOCKS]; |
611 | int sw_refcount[RADEON_NUM_RINGS]; | 587 | union radeon_irq_stat_regs stat_regs; |
612 | union radeon_irq_stat_regs stat_regs; | ||
613 | spinlock_t pflip_lock[RADEON_MAX_CRTCS]; | ||
614 | int pflip_refcount[RADEON_MAX_CRTCS]; | ||
615 | }; | 588 | }; |
616 | 589 | ||
617 | int radeon_irq_kms_init(struct radeon_device *rdev); | 590 | int radeon_irq_kms_init(struct radeon_device *rdev); |
@@ -620,6 +593,11 @@ void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring); | |||
620 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring); | 593 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring); |
621 | void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); | 594 | void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); |
622 | void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); | 595 | void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); |
596 | void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block); | ||
597 | void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block); | ||
598 | void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask); | ||
599 | void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask); | ||
600 | int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev); | ||
623 | 601 | ||
624 | /* | 602 | /* |
625 | * CP & rings. | 603 | * CP & rings. |
@@ -630,9 +608,11 @@ struct radeon_ib { | |||
630 | uint32_t length_dw; | 608 | uint32_t length_dw; |
631 | uint64_t gpu_addr; | 609 | uint64_t gpu_addr; |
632 | uint32_t *ptr; | 610 | uint32_t *ptr; |
611 | int ring; | ||
633 | struct radeon_fence *fence; | 612 | struct radeon_fence *fence; |
634 | unsigned vm_id; | 613 | unsigned vm_id; |
635 | bool is_const_ib; | 614 | bool is_const_ib; |
615 | struct radeon_fence *sync_to[RADEON_NUM_RINGS]; | ||
636 | struct radeon_semaphore *semaphore; | 616 | struct radeon_semaphore *semaphore; |
637 | }; | 617 | }; |
638 | 618 | ||
@@ -642,6 +622,9 @@ struct radeon_ring { | |||
642 | unsigned rptr; | 622 | unsigned rptr; |
643 | unsigned rptr_offs; | 623 | unsigned rptr_offs; |
644 | unsigned rptr_reg; | 624 | unsigned rptr_reg; |
625 | unsigned rptr_save_reg; | ||
626 | u64 next_rptr_gpu_addr; | ||
627 | volatile u32 *next_rptr_cpu_addr; | ||
645 | unsigned wptr; | 628 | unsigned wptr; |
646 | unsigned wptr_old; | 629 | unsigned wptr_old; |
647 | unsigned wptr_reg; | 630 | unsigned wptr_reg; |
@@ -657,6 +640,7 @@ struct radeon_ring { | |||
657 | u32 ptr_reg_shift; | 640 | u32 ptr_reg_shift; |
658 | u32 ptr_reg_mask; | 641 | u32 ptr_reg_mask; |
659 | u32 nop; | 642 | u32 nop; |
643 | u32 idx; | ||
660 | }; | 644 | }; |
661 | 645 | ||
662 | /* | 646 | /* |
@@ -690,6 +674,7 @@ struct radeon_vm_funcs { | |||
690 | }; | 674 | }; |
691 | 675 | ||
692 | struct radeon_vm_manager { | 676 | struct radeon_vm_manager { |
677 | struct mutex lock; | ||
693 | struct list_head lru_vm; | 678 | struct list_head lru_vm; |
694 | uint32_t use_bitmap; | 679 | uint32_t use_bitmap; |
695 | struct radeon_sa_manager sa_manager; | 680 | struct radeon_sa_manager sa_manager; |
@@ -718,13 +703,10 @@ struct r600_ih { | |||
718 | struct radeon_bo *ring_obj; | 703 | struct radeon_bo *ring_obj; |
719 | volatile uint32_t *ring; | 704 | volatile uint32_t *ring; |
720 | unsigned rptr; | 705 | unsigned rptr; |
721 | unsigned rptr_offs; | ||
722 | unsigned wptr; | ||
723 | unsigned wptr_old; | ||
724 | unsigned ring_size; | 706 | unsigned ring_size; |
725 | uint64_t gpu_addr; | 707 | uint64_t gpu_addr; |
726 | uint32_t ptr_mask; | 708 | uint32_t ptr_mask; |
727 | spinlock_t lock; | 709 | atomic_t lock; |
728 | bool enabled; | 710 | bool enabled; |
729 | }; | 711 | }; |
730 | 712 | ||
@@ -757,8 +739,6 @@ struct r600_blit { | |||
757 | u32 state_len; | 739 | u32 state_len; |
758 | }; | 740 | }; |
759 | 741 | ||
760 | void r600_blit_suspend(struct radeon_device *rdev); | ||
761 | |||
762 | /* | 742 | /* |
763 | * SI RLC stuff | 743 | * SI RLC stuff |
764 | */ | 744 | */ |
@@ -774,14 +754,14 @@ struct si_rlc { | |||
774 | int radeon_ib_get(struct radeon_device *rdev, int ring, | 754 | int radeon_ib_get(struct radeon_device *rdev, int ring, |
775 | struct radeon_ib *ib, unsigned size); | 755 | struct radeon_ib *ib, unsigned size); |
776 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); | 756 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); |
777 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); | 757 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, |
758 | struct radeon_ib *const_ib); | ||
778 | int radeon_ib_pool_init(struct radeon_device *rdev); | 759 | int radeon_ib_pool_init(struct radeon_device *rdev); |
779 | void radeon_ib_pool_fini(struct radeon_device *rdev); | 760 | void radeon_ib_pool_fini(struct radeon_device *rdev); |
780 | int radeon_ib_pool_start(struct radeon_device *rdev); | ||
781 | int radeon_ib_pool_suspend(struct radeon_device *rdev); | ||
782 | int radeon_ib_ring_tests(struct radeon_device *rdev); | 761 | int radeon_ib_ring_tests(struct radeon_device *rdev); |
783 | /* Ring access between begin & end cannot sleep */ | 762 | /* Ring access between begin & end cannot sleep */ |
784 | int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *cp); | 763 | bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, |
764 | struct radeon_ring *ring); | ||
785 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); | 765 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); |
786 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 766 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); |
787 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 767 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); |
@@ -793,6 +773,10 @@ int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | |||
793 | void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); | 773 | void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); |
794 | void radeon_ring_lockup_update(struct radeon_ring *ring); | 774 | void radeon_ring_lockup_update(struct radeon_ring *ring); |
795 | bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | 775 | bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); |
776 | unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, | ||
777 | uint32_t **data); | ||
778 | int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, | ||
779 | unsigned size, uint32_t *data); | ||
796 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, | 780 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, |
797 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, | 781 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, |
798 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); | 782 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); |
@@ -891,6 +875,7 @@ struct radeon_wb { | |||
891 | }; | 875 | }; |
892 | 876 | ||
893 | #define RADEON_WB_SCRATCH_OFFSET 0 | 877 | #define RADEON_WB_SCRATCH_OFFSET 0 |
878 | #define RADEON_WB_RING0_NEXT_RPTR 256 | ||
894 | #define RADEON_WB_CP_RPTR_OFFSET 1024 | 879 | #define RADEON_WB_CP_RPTR_OFFSET 1024 |
895 | #define RADEON_WB_CP1_RPTR_OFFSET 1280 | 880 | #define RADEON_WB_CP1_RPTR_OFFSET 1280 |
896 | #define RADEON_WB_CP2_RPTR_OFFSET 1536 | 881 | #define RADEON_WB_CP2_RPTR_OFFSET 1536 |
@@ -1039,11 +1024,12 @@ struct radeon_power_state { | |||
1039 | 1024 | ||
1040 | struct radeon_pm { | 1025 | struct radeon_pm { |
1041 | struct mutex mutex; | 1026 | struct mutex mutex; |
1027 | /* write locked while reprogramming mclk */ | ||
1028 | struct rw_semaphore mclk_lock; | ||
1042 | u32 active_crtcs; | 1029 | u32 active_crtcs; |
1043 | int active_crtc_count; | 1030 | int active_crtc_count; |
1044 | int req_vblank; | 1031 | int req_vblank; |
1045 | bool vblank_sync; | 1032 | bool vblank_sync; |
1046 | bool gui_idle; | ||
1047 | fixed20_12 max_bandwidth; | 1033 | fixed20_12 max_bandwidth; |
1048 | fixed20_12 igp_sideport_mclk; | 1034 | fixed20_12 igp_sideport_mclk; |
1049 | fixed20_12 igp_system_mclk; | 1035 | fixed20_12 igp_system_mclk; |
@@ -1192,20 +1178,20 @@ struct radeon_asic { | |||
1192 | uint64_t src_offset, | 1178 | uint64_t src_offset, |
1193 | uint64_t dst_offset, | 1179 | uint64_t dst_offset, |
1194 | unsigned num_gpu_pages, | 1180 | unsigned num_gpu_pages, |
1195 | struct radeon_fence *fence); | 1181 | struct radeon_fence **fence); |
1196 | u32 blit_ring_index; | 1182 | u32 blit_ring_index; |
1197 | int (*dma)(struct radeon_device *rdev, | 1183 | int (*dma)(struct radeon_device *rdev, |
1198 | uint64_t src_offset, | 1184 | uint64_t src_offset, |
1199 | uint64_t dst_offset, | 1185 | uint64_t dst_offset, |
1200 | unsigned num_gpu_pages, | 1186 | unsigned num_gpu_pages, |
1201 | struct radeon_fence *fence); | 1187 | struct radeon_fence **fence); |
1202 | u32 dma_ring_index; | 1188 | u32 dma_ring_index; |
1203 | /* method used for bo copy */ | 1189 | /* method used for bo copy */ |
1204 | int (*copy)(struct radeon_device *rdev, | 1190 | int (*copy)(struct radeon_device *rdev, |
1205 | uint64_t src_offset, | 1191 | uint64_t src_offset, |
1206 | uint64_t dst_offset, | 1192 | uint64_t dst_offset, |
1207 | unsigned num_gpu_pages, | 1193 | unsigned num_gpu_pages, |
1208 | struct radeon_fence *fence); | 1194 | struct radeon_fence **fence); |
1209 | /* ring used for bo copies */ | 1195 | /* ring used for bo copies */ |
1210 | u32 copy_ring_index; | 1196 | u32 copy_ring_index; |
1211 | } copy; | 1197 | } copy; |
@@ -1467,6 +1453,7 @@ struct radeon_device { | |||
1467 | struct device *dev; | 1453 | struct device *dev; |
1468 | struct drm_device *ddev; | 1454 | struct drm_device *ddev; |
1469 | struct pci_dev *pdev; | 1455 | struct pci_dev *pdev; |
1456 | struct rw_semaphore exclusive_lock; | ||
1470 | /* ASIC */ | 1457 | /* ASIC */ |
1471 | union radeon_asic_config config; | 1458 | union radeon_asic_config config; |
1472 | enum radeon_family family; | 1459 | enum radeon_family family; |
@@ -1512,7 +1499,6 @@ struct radeon_device { | |||
1512 | struct radeon_gem gem; | 1499 | struct radeon_gem gem; |
1513 | struct radeon_pm pm; | 1500 | struct radeon_pm pm; |
1514 | uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; | 1501 | uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; |
1515 | struct radeon_mutex cs_mutex; | ||
1516 | struct radeon_wb wb; | 1502 | struct radeon_wb wb; |
1517 | struct radeon_dummy_page dummy_page; | 1503 | struct radeon_dummy_page dummy_page; |
1518 | bool shutdown; | 1504 | bool shutdown; |
@@ -1534,7 +1520,6 @@ struct radeon_device { | |||
1534 | struct work_struct audio_work; | 1520 | struct work_struct audio_work; |
1535 | int num_crtc; /* number of crtcs */ | 1521 | int num_crtc; /* number of crtcs */ |
1536 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ | 1522 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ |
1537 | struct mutex vram_mutex; | ||
1538 | bool audio_enabled; | 1523 | bool audio_enabled; |
1539 | struct r600_audio audio_status; /* audio stuff */ | 1524 | struct r600_audio audio_status; /* audio stuff */ |
1540 | struct notifier_block acpi_nb; | 1525 | struct notifier_block acpi_nb; |
@@ -1785,8 +1770,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size | |||
1785 | */ | 1770 | */ |
1786 | int radeon_vm_manager_init(struct radeon_device *rdev); | 1771 | int radeon_vm_manager_init(struct radeon_device *rdev); |
1787 | void radeon_vm_manager_fini(struct radeon_device *rdev); | 1772 | void radeon_vm_manager_fini(struct radeon_device *rdev); |
1788 | int radeon_vm_manager_start(struct radeon_device *rdev); | ||
1789 | int radeon_vm_manager_suspend(struct radeon_device *rdev); | ||
1790 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); | 1773 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); |
1791 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); | 1774 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); |
1792 | int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); | 1775 | int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index f533df5f7d50..973417c4b014 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -40,6 +40,16 @@ | |||
40 | /* | 40 | /* |
41 | * Registers accessors functions. | 41 | * Registers accessors functions. |
42 | */ | 42 | */ |
43 | /** | ||
44 | * radeon_invalid_rreg - dummy reg read function | ||
45 | * | ||
46 | * @rdev: radeon device pointer | ||
47 | * @reg: offset of register | ||
48 | * | ||
49 | * Dummy register read function. Used for register blocks | ||
50 | * that certain asics don't have (all asics). | ||
51 | * Returns the value in the register. | ||
52 | */ | ||
43 | static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) | 53 | static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) |
44 | { | 54 | { |
45 | DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); | 55 | DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); |
@@ -47,6 +57,16 @@ static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) | |||
47 | return 0; | 57 | return 0; |
48 | } | 58 | } |
49 | 59 | ||
60 | /** | ||
61 | * radeon_invalid_wreg - dummy reg write function | ||
62 | * | ||
63 | * @rdev: radeon device pointer | ||
64 | * @reg: offset of register | ||
65 | * @v: value to write to the register | ||
66 | * | ||
67 | * Dummy register read function. Used for register blocks | ||
68 | * that certain asics don't have (all asics). | ||
69 | */ | ||
50 | static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | 70 | static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
51 | { | 71 | { |
52 | DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", | 72 | DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", |
@@ -54,6 +74,14 @@ static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
54 | BUG_ON(1); | 74 | BUG_ON(1); |
55 | } | 75 | } |
56 | 76 | ||
77 | /** | ||
78 | * radeon_register_accessor_init - sets up the register accessor callbacks | ||
79 | * | ||
80 | * @rdev: radeon device pointer | ||
81 | * | ||
82 | * Sets up the register accessor callbacks for various register | ||
83 | * apertures. Not all asics have all apertures (all asics). | ||
84 | */ | ||
57 | static void radeon_register_accessor_init(struct radeon_device *rdev) | 85 | static void radeon_register_accessor_init(struct radeon_device *rdev) |
58 | { | 86 | { |
59 | rdev->mc_rreg = &radeon_invalid_rreg; | 87 | rdev->mc_rreg = &radeon_invalid_rreg; |
@@ -102,6 +130,14 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) | |||
102 | 130 | ||
103 | 131 | ||
104 | /* helper to disable agp */ | 132 | /* helper to disable agp */ |
133 | /** | ||
134 | * radeon_agp_disable - AGP disable helper function | ||
135 | * | ||
136 | * @rdev: radeon device pointer | ||
137 | * | ||
138 | * Removes AGP flags and changes the gart callbacks on AGP | ||
139 | * cards when using the internal gart rather than AGP (all asics). | ||
140 | */ | ||
105 | void radeon_agp_disable(struct radeon_device *rdev) | 141 | void radeon_agp_disable(struct radeon_device *rdev) |
106 | { | 142 | { |
107 | rdev->flags &= ~RADEON_IS_AGP; | 143 | rdev->flags &= ~RADEON_IS_AGP; |
@@ -1608,6 +1644,16 @@ static struct radeon_asic si_asic = { | |||
1608 | }, | 1644 | }, |
1609 | }; | 1645 | }; |
1610 | 1646 | ||
1647 | /** | ||
1648 | * radeon_asic_init - register asic specific callbacks | ||
1649 | * | ||
1650 | * @rdev: radeon device pointer | ||
1651 | * | ||
1652 | * Registers the appropriate asic specific callbacks for each | ||
1653 | * chip family. Also sets other asics specific info like the number | ||
1654 | * of crtcs and the register aperture accessors (all asics). | ||
1655 | * Returns 0 for success. | ||
1656 | */ | ||
1611 | int radeon_asic_init(struct radeon_device *rdev) | 1657 | int radeon_asic_init(struct radeon_device *rdev) |
1612 | { | 1658 | { |
1613 | radeon_register_accessor_init(rdev); | 1659 | radeon_register_accessor_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index e76a941ef14e..f4af24310438 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -79,7 +79,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
79 | uint64_t src_offset, | 79 | uint64_t src_offset, |
80 | uint64_t dst_offset, | 80 | uint64_t dst_offset, |
81 | unsigned num_gpu_pages, | 81 | unsigned num_gpu_pages, |
82 | struct radeon_fence *fence); | 82 | struct radeon_fence **fence); |
83 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, | 83 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, |
84 | uint32_t tiling_flags, uint32_t pitch, | 84 | uint32_t tiling_flags, uint32_t pitch, |
85 | uint32_t offset, uint32_t obj_size); | 85 | uint32_t offset, uint32_t obj_size); |
@@ -103,7 +103,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev); | |||
103 | void r100_pci_gart_disable(struct radeon_device *rdev); | 103 | void r100_pci_gart_disable(struct radeon_device *rdev); |
104 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); | 104 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); |
105 | int r100_gui_wait_for_idle(struct radeon_device *rdev); | 105 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
106 | void r100_ib_fini(struct radeon_device *rdev); | ||
107 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 106 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
108 | void r100_irq_disable(struct radeon_device *rdev); | 107 | void r100_irq_disable(struct radeon_device *rdev); |
109 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); | 108 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); |
@@ -144,7 +143,7 @@ extern int r200_copy_dma(struct radeon_device *rdev, | |||
144 | uint64_t src_offset, | 143 | uint64_t src_offset, |
145 | uint64_t dst_offset, | 144 | uint64_t dst_offset, |
146 | unsigned num_gpu_pages, | 145 | unsigned num_gpu_pages, |
147 | struct radeon_fence *fence); | 146 | struct radeon_fence **fence); |
148 | void r200_set_safe_registers(struct radeon_device *rdev); | 147 | void r200_set_safe_registers(struct radeon_device *rdev); |
149 | 148 | ||
150 | /* | 149 | /* |
@@ -318,7 +317,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | |||
318 | int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | 317 | int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); |
319 | int r600_copy_blit(struct radeon_device *rdev, | 318 | int r600_copy_blit(struct radeon_device *rdev, |
320 | uint64_t src_offset, uint64_t dst_offset, | 319 | uint64_t src_offset, uint64_t dst_offset, |
321 | unsigned num_gpu_pages, struct radeon_fence *fence); | 320 | unsigned num_gpu_pages, struct radeon_fence **fence); |
322 | void r600_hpd_init(struct radeon_device *rdev); | 321 | void r600_hpd_init(struct radeon_device *rdev); |
323 | void r600_hpd_fini(struct radeon_device *rdev); | 322 | void r600_hpd_fini(struct radeon_device *rdev); |
324 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 323 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
@@ -363,9 +362,10 @@ int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); | |||
363 | void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); | 362 | void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); |
364 | /* r600 blit */ | 363 | /* r600 blit */ |
365 | int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, | 364 | int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, |
366 | struct radeon_sa_bo **vb); | 365 | struct radeon_fence **fence, struct radeon_sa_bo **vb, |
367 | void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence, | 366 | struct radeon_semaphore **sem); |
368 | struct radeon_sa_bo *vb); | 367 | void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence **fence, |
368 | struct radeon_sa_bo *vb, struct radeon_semaphore *sem); | ||
369 | void r600_kms_blit_copy(struct radeon_device *rdev, | 369 | void r600_kms_blit_copy(struct radeon_device *rdev, |
370 | u64 src_gpu_addr, u64 dst_gpu_addr, | 370 | u64 src_gpu_addr, u64 dst_gpu_addr, |
371 | unsigned num_gpu_pages, | 371 | unsigned num_gpu_pages, |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 364f5b1a04b9..bedda9caadd9 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -45,20 +45,14 @@ static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size, | |||
45 | for (i = 0; i < n; i++) { | 45 | for (i = 0; i < n; i++) { |
46 | switch (flag) { | 46 | switch (flag) { |
47 | case RADEON_BENCHMARK_COPY_DMA: | 47 | case RADEON_BENCHMARK_COPY_DMA: |
48 | r = radeon_fence_create(rdev, &fence, radeon_copy_dma_ring_index(rdev)); | ||
49 | if (r) | ||
50 | return r; | ||
51 | r = radeon_copy_dma(rdev, saddr, daddr, | 48 | r = radeon_copy_dma(rdev, saddr, daddr, |
52 | size / RADEON_GPU_PAGE_SIZE, | 49 | size / RADEON_GPU_PAGE_SIZE, |
53 | fence); | 50 | &fence); |
54 | break; | 51 | break; |
55 | case RADEON_BENCHMARK_COPY_BLIT: | 52 | case RADEON_BENCHMARK_COPY_BLIT: |
56 | r = radeon_fence_create(rdev, &fence, radeon_copy_blit_ring_index(rdev)); | ||
57 | if (r) | ||
58 | return r; | ||
59 | r = radeon_copy_blit(rdev, saddr, daddr, | 53 | r = radeon_copy_blit(rdev, saddr, daddr, |
60 | size / RADEON_GPU_PAGE_SIZE, | 54 | size / RADEON_GPU_PAGE_SIZE, |
61 | fence); | 55 | &fence); |
62 | break; | 56 | break; |
63 | default: | 57 | default: |
64 | DRM_ERROR("Unknown copy method\n"); | 58 | DRM_ERROR("Unknown copy method\n"); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2914c5761cfc..895e628b60f8 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -64,14 +64,33 @@ void radeon_connector_hotplug(struct drm_connector *connector) | |||
64 | 64 | ||
65 | /* just deal with DP (not eDP) here. */ | 65 | /* just deal with DP (not eDP) here. */ |
66 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | 66 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
67 | int saved_dpms = connector->dpms; | 67 | struct radeon_connector_atom_dig *dig_connector = |
68 | 68 | radeon_connector->con_priv; | |
69 | /* Only turn off the display it it's physically disconnected */ | 69 | |
70 | if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | 70 | /* if existing sink type was not DP no need to retrain */ |
71 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 71 | if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) |
72 | else if (radeon_dp_needs_link_train(radeon_connector)) | 72 | return; |
73 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | 73 | |
74 | connector->dpms = saved_dpms; | 74 | /* first get sink type as it may be reset after (un)plug */ |
75 | dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); | ||
76 | /* don't do anything if sink is not display port, i.e., | ||
77 | * passive dp->(dvi|hdmi) adaptor | ||
78 | */ | ||
79 | if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
80 | int saved_dpms = connector->dpms; | ||
81 | /* Only turn off the display if it's physically disconnected */ | ||
82 | if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { | ||
83 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | ||
84 | } else if (radeon_dp_needs_link_train(radeon_connector)) { | ||
85 | /* set it to OFF so that drm_helper_connector_dpms() | ||
86 | * won't return immediately since the current state | ||
87 | * is ON at this point. | ||
88 | */ | ||
89 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
90 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | ||
91 | } | ||
92 | connector->dpms = saved_dpms; | ||
93 | } | ||
75 | } | 94 | } |
76 | } | 95 | } |
77 | 96 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 142f89462aa4..8a4c49ef0cc4 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -115,36 +115,20 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority | |||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) | 118 | static void radeon_cs_sync_rings(struct radeon_cs_parser *p) |
119 | { | 119 | { |
120 | bool sync_to_ring[RADEON_NUM_RINGS] = { }; | 120 | int i; |
121 | bool need_sync = false; | ||
122 | int i, r; | ||
123 | 121 | ||
124 | for (i = 0; i < p->nrelocs; i++) { | 122 | for (i = 0; i < p->nrelocs; i++) { |
125 | struct radeon_fence *fence; | 123 | struct radeon_fence *a, *b; |
126 | 124 | ||
127 | if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj) | 125 | if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj) |
128 | continue; | 126 | continue; |
129 | 127 | ||
130 | fence = p->relocs[i].robj->tbo.sync_obj; | 128 | a = p->relocs[i].robj->tbo.sync_obj; |
131 | if (fence->ring != p->ring && !radeon_fence_signaled(fence)) { | 129 | b = p->ib.sync_to[a->ring]; |
132 | sync_to_ring[fence->ring] = true; | 130 | p->ib.sync_to[a->ring] = radeon_fence_later(a, b); |
133 | need_sync = true; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | if (!need_sync) { | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | r = radeon_semaphore_create(p->rdev, &p->ib.semaphore); | ||
142 | if (r) { | ||
143 | return r; | ||
144 | } | 131 | } |
145 | |||
146 | return radeon_semaphore_sync_rings(p->rdev, p->ib.semaphore, | ||
147 | sync_to_ring, p->ring); | ||
148 | } | 132 | } |
149 | 133 | ||
150 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ | 134 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ |
@@ -368,16 +352,13 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
368 | DRM_ERROR("Invalid command stream !\n"); | 352 | DRM_ERROR("Invalid command stream !\n"); |
369 | return r; | 353 | return r; |
370 | } | 354 | } |
371 | r = radeon_cs_sync_rings(parser); | 355 | radeon_cs_sync_rings(parser); |
372 | if (r) { | ||
373 | DRM_ERROR("Failed to synchronize rings !\n"); | ||
374 | } | ||
375 | parser->ib.vm_id = 0; | 356 | parser->ib.vm_id = 0; |
376 | r = radeon_ib_schedule(rdev, &parser->ib); | 357 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); |
377 | if (r) { | 358 | if (r) { |
378 | DRM_ERROR("Failed to schedule IB !\n"); | 359 | DRM_ERROR("Failed to schedule IB !\n"); |
379 | } | 360 | } |
380 | return 0; | 361 | return r; |
381 | } | 362 | } |
382 | 363 | ||
383 | static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, | 364 | static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, |
@@ -459,6 +440,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
459 | return r; | 440 | return r; |
460 | } | 441 | } |
461 | 442 | ||
443 | mutex_lock(&rdev->vm_manager.lock); | ||
462 | mutex_lock(&vm->mutex); | 444 | mutex_lock(&vm->mutex); |
463 | r = radeon_vm_bind(rdev, vm); | 445 | r = radeon_vm_bind(rdev, vm); |
464 | if (r) { | 446 | if (r) { |
@@ -468,30 +450,26 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
468 | if (r) { | 450 | if (r) { |
469 | goto out; | 451 | goto out; |
470 | } | 452 | } |
471 | r = radeon_cs_sync_rings(parser); | 453 | radeon_cs_sync_rings(parser); |
472 | if (r) { | 454 | |
473 | DRM_ERROR("Failed to synchronize rings !\n"); | 455 | parser->ib.vm_id = vm->id; |
474 | } | 456 | /* ib pool is bind at 0 in virtual address space, |
457 | * so gpu_addr is the offset inside the pool bo | ||
458 | */ | ||
459 | parser->ib.gpu_addr = parser->ib.sa_bo->soffset; | ||
475 | 460 | ||
476 | if ((rdev->family >= CHIP_TAHITI) && | 461 | if ((rdev->family >= CHIP_TAHITI) && |
477 | (parser->chunk_const_ib_idx != -1)) { | 462 | (parser->chunk_const_ib_idx != -1)) { |
478 | parser->const_ib.vm_id = vm->id; | 463 | parser->const_ib.vm_id = vm->id; |
479 | /* ib pool is bind at 0 in virtual address space to gpu_addr is the | 464 | /* ib pool is bind at 0 in virtual address space, |
480 | * offset inside the pool bo | 465 | * so gpu_addr is the offset inside the pool bo |
481 | */ | 466 | */ |
482 | parser->const_ib.gpu_addr = parser->const_ib.sa_bo->soffset; | 467 | parser->const_ib.gpu_addr = parser->const_ib.sa_bo->soffset; |
483 | r = radeon_ib_schedule(rdev, &parser->const_ib); | 468 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib); |
484 | if (r) | 469 | } else { |
485 | goto out; | 470 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); |
486 | } | 471 | } |
487 | 472 | ||
488 | parser->ib.vm_id = vm->id; | ||
489 | /* ib pool is bind at 0 in virtual address space to gpu_addr is the | ||
490 | * offset inside the pool bo | ||
491 | */ | ||
492 | parser->ib.gpu_addr = parser->ib.sa_bo->soffset; | ||
493 | parser->ib.is_const_ib = false; | ||
494 | r = radeon_ib_schedule(rdev, &parser->ib); | ||
495 | out: | 473 | out: |
496 | if (!r) { | 474 | if (!r) { |
497 | if (vm->fence) { | 475 | if (vm->fence) { |
@@ -499,7 +477,8 @@ out: | |||
499 | } | 477 | } |
500 | vm->fence = radeon_fence_ref(parser->ib.fence); | 478 | vm->fence = radeon_fence_ref(parser->ib.fence); |
501 | } | 479 | } |
502 | mutex_unlock(&fpriv->vm.mutex); | 480 | mutex_unlock(&vm->mutex); |
481 | mutex_unlock(&rdev->vm_manager.lock); | ||
503 | return r; | 482 | return r; |
504 | } | 483 | } |
505 | 484 | ||
@@ -519,9 +498,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
519 | struct radeon_cs_parser parser; | 498 | struct radeon_cs_parser parser; |
520 | int r; | 499 | int r; |
521 | 500 | ||
522 | radeon_mutex_lock(&rdev->cs_mutex); | 501 | down_read(&rdev->exclusive_lock); |
523 | if (!rdev->accel_working) { | 502 | if (!rdev->accel_working) { |
524 | radeon_mutex_unlock(&rdev->cs_mutex); | 503 | up_read(&rdev->exclusive_lock); |
525 | return -EBUSY; | 504 | return -EBUSY; |
526 | } | 505 | } |
527 | /* initialize parser */ | 506 | /* initialize parser */ |
@@ -534,8 +513,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
534 | if (r) { | 513 | if (r) { |
535 | DRM_ERROR("Failed to initialize parser !\n"); | 514 | DRM_ERROR("Failed to initialize parser !\n"); |
536 | radeon_cs_parser_fini(&parser, r); | 515 | radeon_cs_parser_fini(&parser, r); |
516 | up_read(&rdev->exclusive_lock); | ||
537 | r = radeon_cs_handle_lockup(rdev, r); | 517 | r = radeon_cs_handle_lockup(rdev, r); |
538 | radeon_mutex_unlock(&rdev->cs_mutex); | ||
539 | return r; | 518 | return r; |
540 | } | 519 | } |
541 | r = radeon_cs_parser_relocs(&parser); | 520 | r = radeon_cs_parser_relocs(&parser); |
@@ -543,8 +522,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
543 | if (r != -ERESTARTSYS) | 522 | if (r != -ERESTARTSYS) |
544 | DRM_ERROR("Failed to parse relocation %d!\n", r); | 523 | DRM_ERROR("Failed to parse relocation %d!\n", r); |
545 | radeon_cs_parser_fini(&parser, r); | 524 | radeon_cs_parser_fini(&parser, r); |
525 | up_read(&rdev->exclusive_lock); | ||
546 | r = radeon_cs_handle_lockup(rdev, r); | 526 | r = radeon_cs_handle_lockup(rdev, r); |
547 | radeon_mutex_unlock(&rdev->cs_mutex); | ||
548 | return r; | 527 | return r; |
549 | } | 528 | } |
550 | r = radeon_cs_ib_chunk(rdev, &parser); | 529 | r = radeon_cs_ib_chunk(rdev, &parser); |
@@ -557,8 +536,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
557 | } | 536 | } |
558 | out: | 537 | out: |
559 | radeon_cs_parser_fini(&parser, r); | 538 | radeon_cs_parser_fini(&parser, r); |
539 | up_read(&rdev->exclusive_lock); | ||
560 | r = radeon_cs_handle_lockup(rdev, r); | 540 | r = radeon_cs_handle_lockup(rdev, r); |
561 | radeon_mutex_unlock(&rdev->cs_mutex); | ||
562 | return r; | 541 | return r; |
563 | } | 542 | } |
564 | 543 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 42acc6449dd6..711e95ad39bf 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -262,8 +262,14 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, | |||
262 | if (!(cursor_end & 0x7f)) | 262 | if (!(cursor_end & 0x7f)) |
263 | w--; | 263 | w--; |
264 | } | 264 | } |
265 | if (w <= 0) | 265 | if (w <= 0) { |
266 | w = 1; | 266 | w = 1; |
267 | cursor_end = x - xorigin + w; | ||
268 | if (!(cursor_end & 0x7f)) { | ||
269 | x--; | ||
270 | WARN_ON_ONCE(x < 0); | ||
271 | } | ||
272 | } | ||
267 | } | 273 | } |
268 | } | 274 | } |
269 | 275 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 066c98b888a5..742af8244e89 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -96,8 +96,12 @@ static const char radeon_family_name[][16] = { | |||
96 | "LAST", | 96 | "LAST", |
97 | }; | 97 | }; |
98 | 98 | ||
99 | /* | 99 | /** |
100 | * Clear GPU surface registers. | 100 | * radeon_surface_init - Clear GPU surface registers. |
101 | * | ||
102 | * @rdev: radeon_device pointer | ||
103 | * | ||
104 | * Clear GPU surface registers (r1xx-r5xx). | ||
101 | */ | 105 | */ |
102 | void radeon_surface_init(struct radeon_device *rdev) | 106 | void radeon_surface_init(struct radeon_device *rdev) |
103 | { | 107 | { |
@@ -119,6 +123,13 @@ void radeon_surface_init(struct radeon_device *rdev) | |||
119 | /* | 123 | /* |
120 | * GPU scratch registers helpers function. | 124 | * GPU scratch registers helpers function. |
121 | */ | 125 | */ |
126 | /** | ||
127 | * radeon_scratch_init - Init scratch register driver information. | ||
128 | * | ||
129 | * @rdev: radeon_device pointer | ||
130 | * | ||
131 | * Init CP scratch register driver information (r1xx-r5xx) | ||
132 | */ | ||
122 | void radeon_scratch_init(struct radeon_device *rdev) | 133 | void radeon_scratch_init(struct radeon_device *rdev) |
123 | { | 134 | { |
124 | int i; | 135 | int i; |
@@ -136,6 +147,15 @@ void radeon_scratch_init(struct radeon_device *rdev) | |||
136 | } | 147 | } |
137 | } | 148 | } |
138 | 149 | ||
150 | /** | ||
151 | * radeon_scratch_get - Allocate a scratch register | ||
152 | * | ||
153 | * @rdev: radeon_device pointer | ||
154 | * @reg: scratch register mmio offset | ||
155 | * | ||
156 | * Allocate a CP scratch register for use by the driver (all asics). | ||
157 | * Returns 0 on success or -EINVAL on failure. | ||
158 | */ | ||
139 | int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg) | 159 | int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg) |
140 | { | 160 | { |
141 | int i; | 161 | int i; |
@@ -150,6 +170,14 @@ int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg) | |||
150 | return -EINVAL; | 170 | return -EINVAL; |
151 | } | 171 | } |
152 | 172 | ||
173 | /** | ||
174 | * radeon_scratch_free - Free a scratch register | ||
175 | * | ||
176 | * @rdev: radeon_device pointer | ||
177 | * @reg: scratch register mmio offset | ||
178 | * | ||
179 | * Free a CP scratch register allocated for use by the driver (all asics) | ||
180 | */ | ||
153 | void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) | 181 | void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) |
154 | { | 182 | { |
155 | int i; | 183 | int i; |
@@ -162,6 +190,20 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) | |||
162 | } | 190 | } |
163 | } | 191 | } |
164 | 192 | ||
193 | /* | ||
194 | * radeon_wb_*() | ||
195 | * Writeback is the the method by which the the GPU updates special pages | ||
196 | * in memory with the status of certain GPU events (fences, ring pointers, | ||
197 | * etc.). | ||
198 | */ | ||
199 | |||
200 | /** | ||
201 | * radeon_wb_disable - Disable Writeback | ||
202 | * | ||
203 | * @rdev: radeon_device pointer | ||
204 | * | ||
205 | * Disables Writeback (all asics). Used for suspend. | ||
206 | */ | ||
165 | void radeon_wb_disable(struct radeon_device *rdev) | 207 | void radeon_wb_disable(struct radeon_device *rdev) |
166 | { | 208 | { |
167 | int r; | 209 | int r; |
@@ -177,6 +219,14 @@ void radeon_wb_disable(struct radeon_device *rdev) | |||
177 | rdev->wb.enabled = false; | 219 | rdev->wb.enabled = false; |
178 | } | 220 | } |
179 | 221 | ||
222 | /** | ||
223 | * radeon_wb_fini - Disable Writeback and free memory | ||
224 | * | ||
225 | * @rdev: radeon_device pointer | ||
226 | * | ||
227 | * Disables Writeback and frees the Writeback memory (all asics). | ||
228 | * Used at driver shutdown. | ||
229 | */ | ||
180 | void radeon_wb_fini(struct radeon_device *rdev) | 230 | void radeon_wb_fini(struct radeon_device *rdev) |
181 | { | 231 | { |
182 | radeon_wb_disable(rdev); | 232 | radeon_wb_disable(rdev); |
@@ -187,6 +237,15 @@ void radeon_wb_fini(struct radeon_device *rdev) | |||
187 | } | 237 | } |
188 | } | 238 | } |
189 | 239 | ||
240 | /** | ||
241 | * radeon_wb_init- Init Writeback driver info and allocate memory | ||
242 | * | ||
243 | * @rdev: radeon_device pointer | ||
244 | * | ||
245 | * Disables Writeback and frees the Writeback memory (all asics). | ||
246 | * Used at driver startup. | ||
247 | * Returns 0 on success or an -error on failure. | ||
248 | */ | ||
190 | int radeon_wb_init(struct radeon_device *rdev) | 249 | int radeon_wb_init(struct radeon_device *rdev) |
191 | { | 250 | { |
192 | int r; | 251 | int r; |
@@ -355,6 +414,15 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
355 | /* | 414 | /* |
356 | * GPU helpers function. | 415 | * GPU helpers function. |
357 | */ | 416 | */ |
417 | /** | ||
418 | * radeon_card_posted - check if the hw has already been initialized | ||
419 | * | ||
420 | * @rdev: radeon_device pointer | ||
421 | * | ||
422 | * Check if the asic has been initialized (all asics). | ||
423 | * Used at driver startup. | ||
424 | * Returns true if initialized or false if not. | ||
425 | */ | ||
358 | bool radeon_card_posted(struct radeon_device *rdev) | 426 | bool radeon_card_posted(struct radeon_device *rdev) |
359 | { | 427 | { |
360 | uint32_t reg; | 428 | uint32_t reg; |
@@ -404,6 +472,14 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
404 | 472 | ||
405 | } | 473 | } |
406 | 474 | ||
475 | /** | ||
476 | * radeon_update_bandwidth_info - update display bandwidth params | ||
477 | * | ||
478 | * @rdev: radeon_device pointer | ||
479 | * | ||
480 | * Used when sclk/mclk are switched or display modes are set. | ||
481 | * params are used to calculate display watermarks (all asics) | ||
482 | */ | ||
407 | void radeon_update_bandwidth_info(struct radeon_device *rdev) | 483 | void radeon_update_bandwidth_info(struct radeon_device *rdev) |
408 | { | 484 | { |
409 | fixed20_12 a; | 485 | fixed20_12 a; |
@@ -424,6 +500,15 @@ void radeon_update_bandwidth_info(struct radeon_device *rdev) | |||
424 | } | 500 | } |
425 | } | 501 | } |
426 | 502 | ||
503 | /** | ||
504 | * radeon_boot_test_post_card - check and possibly initialize the hw | ||
505 | * | ||
506 | * @rdev: radeon_device pointer | ||
507 | * | ||
508 | * Check if the asic is initialized and if not, attempt to initialize | ||
509 | * it (all asics). | ||
510 | * Returns true if initialized or false if not. | ||
511 | */ | ||
427 | bool radeon_boot_test_post_card(struct radeon_device *rdev) | 512 | bool radeon_boot_test_post_card(struct radeon_device *rdev) |
428 | { | 513 | { |
429 | if (radeon_card_posted(rdev)) | 514 | if (radeon_card_posted(rdev)) |
@@ -442,6 +527,16 @@ bool radeon_boot_test_post_card(struct radeon_device *rdev) | |||
442 | } | 527 | } |
443 | } | 528 | } |
444 | 529 | ||
530 | /** | ||
531 | * radeon_dummy_page_init - init dummy page used by the driver | ||
532 | * | ||
533 | * @rdev: radeon_device pointer | ||
534 | * | ||
535 | * Allocate the dummy page used by the driver (all asics). | ||
536 | * This dummy page is used by the driver as a filler for gart entries | ||
537 | * when pages are taken out of the GART | ||
538 | * Returns 0 on sucess, -ENOMEM on failure. | ||
539 | */ | ||
445 | int radeon_dummy_page_init(struct radeon_device *rdev) | 540 | int radeon_dummy_page_init(struct radeon_device *rdev) |
446 | { | 541 | { |
447 | if (rdev->dummy_page.page) | 542 | if (rdev->dummy_page.page) |
@@ -460,6 +555,13 @@ int radeon_dummy_page_init(struct radeon_device *rdev) | |||
460 | return 0; | 555 | return 0; |
461 | } | 556 | } |
462 | 557 | ||
558 | /** | ||
559 | * radeon_dummy_page_fini - free dummy page used by the driver | ||
560 | * | ||
561 | * @rdev: radeon_device pointer | ||
562 | * | ||
563 | * Frees the dummy page used by the driver (all asics). | ||
564 | */ | ||
463 | void radeon_dummy_page_fini(struct radeon_device *rdev) | 565 | void radeon_dummy_page_fini(struct radeon_device *rdev) |
464 | { | 566 | { |
465 | if (rdev->dummy_page.page == NULL) | 567 | if (rdev->dummy_page.page == NULL) |
@@ -472,6 +574,23 @@ void radeon_dummy_page_fini(struct radeon_device *rdev) | |||
472 | 574 | ||
473 | 575 | ||
474 | /* ATOM accessor methods */ | 576 | /* ATOM accessor methods */ |
577 | /* | ||
578 | * ATOM is an interpreted byte code stored in tables in the vbios. The | ||
579 | * driver registers callbacks to access registers and the interpreter | ||
580 | * in the driver parses the tables and executes then to program specific | ||
581 | * actions (set display modes, asic init, etc.). See radeon_atombios.c, | ||
582 | * atombios.h, and atom.c | ||
583 | */ | ||
584 | |||
585 | /** | ||
586 | * cail_pll_read - read PLL register | ||
587 | * | ||
588 | * @info: atom card_info pointer | ||
589 | * @reg: PLL register offset | ||
590 | * | ||
591 | * Provides a PLL register accessor for the atom interpreter (r4xx+). | ||
592 | * Returns the value of the PLL register. | ||
593 | */ | ||
475 | static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) | 594 | static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) |
476 | { | 595 | { |
477 | struct radeon_device *rdev = info->dev->dev_private; | 596 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -481,6 +600,15 @@ static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) | |||
481 | return r; | 600 | return r; |
482 | } | 601 | } |
483 | 602 | ||
603 | /** | ||
604 | * cail_pll_write - write PLL register | ||
605 | * | ||
606 | * @info: atom card_info pointer | ||
607 | * @reg: PLL register offset | ||
608 | * @val: value to write to the pll register | ||
609 | * | ||
610 | * Provides a PLL register accessor for the atom interpreter (r4xx+). | ||
611 | */ | ||
484 | static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val) | 612 | static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val) |
485 | { | 613 | { |
486 | struct radeon_device *rdev = info->dev->dev_private; | 614 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -488,6 +616,15 @@ static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val) | |||
488 | rdev->pll_wreg(rdev, reg, val); | 616 | rdev->pll_wreg(rdev, reg, val); |
489 | } | 617 | } |
490 | 618 | ||
619 | /** | ||
620 | * cail_mc_read - read MC (Memory Controller) register | ||
621 | * | ||
622 | * @info: atom card_info pointer | ||
623 | * @reg: MC register offset | ||
624 | * | ||
625 | * Provides an MC register accessor for the atom interpreter (r4xx+). | ||
626 | * Returns the value of the MC register. | ||
627 | */ | ||
491 | static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) | 628 | static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) |
492 | { | 629 | { |
493 | struct radeon_device *rdev = info->dev->dev_private; | 630 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -497,6 +634,15 @@ static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) | |||
497 | return r; | 634 | return r; |
498 | } | 635 | } |
499 | 636 | ||
637 | /** | ||
638 | * cail_mc_write - write MC (Memory Controller) register | ||
639 | * | ||
640 | * @info: atom card_info pointer | ||
641 | * @reg: MC register offset | ||
642 | * @val: value to write to the pll register | ||
643 | * | ||
644 | * Provides a MC register accessor for the atom interpreter (r4xx+). | ||
645 | */ | ||
500 | static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) | 646 | static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) |
501 | { | 647 | { |
502 | struct radeon_device *rdev = info->dev->dev_private; | 648 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -504,6 +650,15 @@ static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) | |||
504 | rdev->mc_wreg(rdev, reg, val); | 650 | rdev->mc_wreg(rdev, reg, val); |
505 | } | 651 | } |
506 | 652 | ||
653 | /** | ||
654 | * cail_reg_write - write MMIO register | ||
655 | * | ||
656 | * @info: atom card_info pointer | ||
657 | * @reg: MMIO register offset | ||
658 | * @val: value to write to the pll register | ||
659 | * | ||
660 | * Provides a MMIO register accessor for the atom interpreter (r4xx+). | ||
661 | */ | ||
507 | static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) | 662 | static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) |
508 | { | 663 | { |
509 | struct radeon_device *rdev = info->dev->dev_private; | 664 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -511,6 +666,15 @@ static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) | |||
511 | WREG32(reg*4, val); | 666 | WREG32(reg*4, val); |
512 | } | 667 | } |
513 | 668 | ||
669 | /** | ||
670 | * cail_reg_read - read MMIO register | ||
671 | * | ||
672 | * @info: atom card_info pointer | ||
673 | * @reg: MMIO register offset | ||
674 | * | ||
675 | * Provides an MMIO register accessor for the atom interpreter (r4xx+). | ||
676 | * Returns the value of the MMIO register. | ||
677 | */ | ||
514 | static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) | 678 | static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) |
515 | { | 679 | { |
516 | struct radeon_device *rdev = info->dev->dev_private; | 680 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -520,6 +684,15 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) | |||
520 | return r; | 684 | return r; |
521 | } | 685 | } |
522 | 686 | ||
687 | /** | ||
688 | * cail_ioreg_write - write IO register | ||
689 | * | ||
690 | * @info: atom card_info pointer | ||
691 | * @reg: IO register offset | ||
692 | * @val: value to write to the pll register | ||
693 | * | ||
694 | * Provides a IO register accessor for the atom interpreter (r4xx+). | ||
695 | */ | ||
523 | static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) | 696 | static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) |
524 | { | 697 | { |
525 | struct radeon_device *rdev = info->dev->dev_private; | 698 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -527,6 +700,15 @@ static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) | |||
527 | WREG32_IO(reg*4, val); | 700 | WREG32_IO(reg*4, val); |
528 | } | 701 | } |
529 | 702 | ||
703 | /** | ||
704 | * cail_ioreg_read - read IO register | ||
705 | * | ||
706 | * @info: atom card_info pointer | ||
707 | * @reg: IO register offset | ||
708 | * | ||
709 | * Provides an IO register accessor for the atom interpreter (r4xx+). | ||
710 | * Returns the value of the IO register. | ||
711 | */ | ||
530 | static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | 712 | static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) |
531 | { | 713 | { |
532 | struct radeon_device *rdev = info->dev->dev_private; | 714 | struct radeon_device *rdev = info->dev->dev_private; |
@@ -536,6 +718,16 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | |||
536 | return r; | 718 | return r; |
537 | } | 719 | } |
538 | 720 | ||
721 | /** | ||
722 | * radeon_atombios_init - init the driver info and callbacks for atombios | ||
723 | * | ||
724 | * @rdev: radeon_device pointer | ||
725 | * | ||
726 | * Initializes the driver info and register access callbacks for the | ||
727 | * ATOM interpreter (r4xx+). | ||
728 | * Returns 0 on sucess, -ENOMEM on failure. | ||
729 | * Called at driver startup. | ||
730 | */ | ||
539 | int radeon_atombios_init(struct radeon_device *rdev) | 731 | int radeon_atombios_init(struct radeon_device *rdev) |
540 | { | 732 | { |
541 | struct card_info *atom_card_info = | 733 | struct card_info *atom_card_info = |
@@ -569,6 +761,15 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
569 | return 0; | 761 | return 0; |
570 | } | 762 | } |
571 | 763 | ||
764 | /** | ||
765 | * radeon_atombios_fini - free the driver info and callbacks for atombios | ||
766 | * | ||
767 | * @rdev: radeon_device pointer | ||
768 | * | ||
769 | * Frees the driver info and register access callbacks for the ATOM | ||
770 | * interpreter (r4xx+). | ||
771 | * Called at driver shutdown. | ||
772 | */ | ||
572 | void radeon_atombios_fini(struct radeon_device *rdev) | 773 | void radeon_atombios_fini(struct radeon_device *rdev) |
573 | { | 774 | { |
574 | if (rdev->mode_info.atom_context) { | 775 | if (rdev->mode_info.atom_context) { |
@@ -578,17 +779,50 @@ void radeon_atombios_fini(struct radeon_device *rdev) | |||
578 | kfree(rdev->mode_info.atom_card_info); | 779 | kfree(rdev->mode_info.atom_card_info); |
579 | } | 780 | } |
580 | 781 | ||
782 | /* COMBIOS */ | ||
783 | /* | ||
784 | * COMBIOS is the bios format prior to ATOM. It provides | ||
785 | * command tables similar to ATOM, but doesn't have a unified | ||
786 | * parser. See radeon_combios.c | ||
787 | */ | ||
788 | |||
789 | /** | ||
790 | * radeon_combios_init - init the driver info for combios | ||
791 | * | ||
792 | * @rdev: radeon_device pointer | ||
793 | * | ||
794 | * Initializes the driver info for combios (r1xx-r3xx). | ||
795 | * Returns 0 on sucess. | ||
796 | * Called at driver startup. | ||
797 | */ | ||
581 | int radeon_combios_init(struct radeon_device *rdev) | 798 | int radeon_combios_init(struct radeon_device *rdev) |
582 | { | 799 | { |
583 | radeon_combios_initialize_bios_scratch_regs(rdev->ddev); | 800 | radeon_combios_initialize_bios_scratch_regs(rdev->ddev); |
584 | return 0; | 801 | return 0; |
585 | } | 802 | } |
586 | 803 | ||
804 | /** | ||
805 | * radeon_combios_fini - free the driver info for combios | ||
806 | * | ||
807 | * @rdev: radeon_device pointer | ||
808 | * | ||
809 | * Frees the driver info for combios (r1xx-r3xx). | ||
810 | * Called at driver shutdown. | ||
811 | */ | ||
587 | void radeon_combios_fini(struct radeon_device *rdev) | 812 | void radeon_combios_fini(struct radeon_device *rdev) |
588 | { | 813 | { |
589 | } | 814 | } |
590 | 815 | ||
591 | /* if we get transitioned to only one device, tak VGA back */ | 816 | /* if we get transitioned to only one device, take VGA back */ |
817 | /** | ||
818 | * radeon_vga_set_decode - enable/disable vga decode | ||
819 | * | ||
820 | * @cookie: radeon_device pointer | ||
821 | * @state: enable/disable vga decode | ||
822 | * | ||
823 | * Enable/disable vga decode (all asics). | ||
824 | * Returns VGA resource flags. | ||
825 | */ | ||
592 | static unsigned int radeon_vga_set_decode(void *cookie, bool state) | 826 | static unsigned int radeon_vga_set_decode(void *cookie, bool state) |
593 | { | 827 | { |
594 | struct radeon_device *rdev = cookie; | 828 | struct radeon_device *rdev = cookie; |
@@ -600,6 +834,14 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) | |||
600 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; | 834 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; |
601 | } | 835 | } |
602 | 836 | ||
837 | /** | ||
838 | * radeon_check_arguments - validate module params | ||
839 | * | ||
840 | * @rdev: radeon_device pointer | ||
841 | * | ||
842 | * Validates certain module parameters and updates | ||
843 | * the associated values used by the driver (all asics). | ||
844 | */ | ||
603 | void radeon_check_arguments(struct radeon_device *rdev) | 845 | void radeon_check_arguments(struct radeon_device *rdev) |
604 | { | 846 | { |
605 | /* vramlimit must be a power of two */ | 847 | /* vramlimit must be a power of two */ |
@@ -666,6 +908,15 @@ void radeon_check_arguments(struct radeon_device *rdev) | |||
666 | } | 908 | } |
667 | } | 909 | } |
668 | 910 | ||
911 | /** | ||
912 | * radeon_switcheroo_set_state - set switcheroo state | ||
913 | * | ||
914 | * @pdev: pci dev pointer | ||
915 | * @state: vga switcheroo state | ||
916 | * | ||
917 | * Callback for the switcheroo driver. Suspends or resumes the | ||
918 | * the asics before or after it is powered up using ACPI methods. | ||
919 | */ | ||
669 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) | 920 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) |
670 | { | 921 | { |
671 | struct drm_device *dev = pci_get_drvdata(pdev); | 922 | struct drm_device *dev = pci_get_drvdata(pdev); |
@@ -686,6 +937,15 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
686 | } | 937 | } |
687 | } | 938 | } |
688 | 939 | ||
940 | /** | ||
941 | * radeon_switcheroo_can_switch - see if switcheroo state can change | ||
942 | * | ||
943 | * @pdev: pci dev pointer | ||
944 | * | ||
945 | * Callback for the switcheroo driver. Check of the switcheroo | ||
946 | * state can be changed. | ||
947 | * Returns true if the state can be changed, false if not. | ||
948 | */ | ||
689 | static bool radeon_switcheroo_can_switch(struct pci_dev *pdev) | 949 | static bool radeon_switcheroo_can_switch(struct pci_dev *pdev) |
690 | { | 950 | { |
691 | struct drm_device *dev = pci_get_drvdata(pdev); | 951 | struct drm_device *dev = pci_get_drvdata(pdev); |
@@ -703,6 +963,18 @@ static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { | |||
703 | .can_switch = radeon_switcheroo_can_switch, | 963 | .can_switch = radeon_switcheroo_can_switch, |
704 | }; | 964 | }; |
705 | 965 | ||
966 | /** | ||
967 | * radeon_device_init - initialize the driver | ||
968 | * | ||
969 | * @rdev: radeon_device pointer | ||
970 | * @pdev: drm dev pointer | ||
971 | * @pdev: pci dev pointer | ||
972 | * @flags: driver flags | ||
973 | * | ||
974 | * Initializes the driver info and hw (all asics). | ||
975 | * Returns 0 for success or an error on failure. | ||
976 | * Called at driver startup. | ||
977 | */ | ||
706 | int radeon_device_init(struct radeon_device *rdev, | 978 | int radeon_device_init(struct radeon_device *rdev, |
707 | struct drm_device *ddev, | 979 | struct drm_device *ddev, |
708 | struct pci_dev *pdev, | 980 | struct pci_dev *pdev, |
@@ -721,6 +993,10 @@ int radeon_device_init(struct radeon_device *rdev, | |||
721 | rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; | 993 | rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; |
722 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 994 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
723 | rdev->accel_working = false; | 995 | rdev->accel_working = false; |
996 | /* set up ring ids */ | ||
997 | for (i = 0; i < RADEON_NUM_RINGS; i++) { | ||
998 | rdev->ring[i].idx = i; | ||
999 | } | ||
724 | 1000 | ||
725 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", | 1001 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", |
726 | radeon_family_name[rdev->family], pdev->vendor, pdev->device, | 1002 | radeon_family_name[rdev->family], pdev->vendor, pdev->device, |
@@ -728,20 +1004,20 @@ int radeon_device_init(struct radeon_device *rdev, | |||
728 | 1004 | ||
729 | /* mutex initialization are all done here so we | 1005 | /* mutex initialization are all done here so we |
730 | * can recall function without having locking issues */ | 1006 | * can recall function without having locking issues */ |
731 | radeon_mutex_init(&rdev->cs_mutex); | ||
732 | mutex_init(&rdev->ring_lock); | 1007 | mutex_init(&rdev->ring_lock); |
733 | mutex_init(&rdev->dc_hw_i2c_mutex); | 1008 | mutex_init(&rdev->dc_hw_i2c_mutex); |
734 | if (rdev->family >= CHIP_R600) | 1009 | atomic_set(&rdev->ih.lock, 0); |
735 | spin_lock_init(&rdev->ih.lock); | ||
736 | mutex_init(&rdev->gem.mutex); | 1010 | mutex_init(&rdev->gem.mutex); |
737 | mutex_init(&rdev->pm.mutex); | 1011 | mutex_init(&rdev->pm.mutex); |
738 | mutex_init(&rdev->vram_mutex); | 1012 | init_rwsem(&rdev->pm.mclk_lock); |
1013 | init_rwsem(&rdev->exclusive_lock); | ||
739 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1014 | init_waitqueue_head(&rdev->irq.vblank_queue); |
740 | init_waitqueue_head(&rdev->irq.idle_queue); | 1015 | init_waitqueue_head(&rdev->irq.idle_queue); |
741 | r = radeon_gem_init(rdev); | 1016 | r = radeon_gem_init(rdev); |
742 | if (r) | 1017 | if (r) |
743 | return r; | 1018 | return r; |
744 | /* initialize vm here */ | 1019 | /* initialize vm here */ |
1020 | mutex_init(&rdev->vm_manager.lock); | ||
745 | rdev->vm_manager.use_bitmap = 1; | 1021 | rdev->vm_manager.use_bitmap = 1; |
746 | rdev->vm_manager.max_pfn = 1 << 20; | 1022 | rdev->vm_manager.max_pfn = 1 << 20; |
747 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); | 1023 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); |
@@ -822,6 +1098,10 @@ int radeon_device_init(struct radeon_device *rdev, | |||
822 | if (r) | 1098 | if (r) |
823 | return r; | 1099 | return r; |
824 | 1100 | ||
1101 | r = radeon_ib_ring_tests(rdev); | ||
1102 | if (r) | ||
1103 | DRM_ERROR("ib ring test failed (%d).\n", r); | ||
1104 | |||
825 | if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { | 1105 | if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { |
826 | /* Acceleration not working on AGP card try again | 1106 | /* Acceleration not working on AGP card try again |
827 | * with fallback to PCI or PCIE GART | 1107 | * with fallback to PCI or PCIE GART |
@@ -847,6 +1127,14 @@ int radeon_device_init(struct radeon_device *rdev, | |||
847 | 1127 | ||
848 | static void radeon_debugfs_remove_files(struct radeon_device *rdev); | 1128 | static void radeon_debugfs_remove_files(struct radeon_device *rdev); |
849 | 1129 | ||
1130 | /** | ||
1131 | * radeon_device_fini - tear down the driver | ||
1132 | * | ||
1133 | * @rdev: radeon_device pointer | ||
1134 | * | ||
1135 | * Tear down the driver info (all asics). | ||
1136 | * Called at driver shutdown. | ||
1137 | */ | ||
850 | void radeon_device_fini(struct radeon_device *rdev) | 1138 | void radeon_device_fini(struct radeon_device *rdev) |
851 | { | 1139 | { |
852 | DRM_INFO("radeon: finishing device.\n"); | 1140 | DRM_INFO("radeon: finishing device.\n"); |
@@ -868,6 +1156,16 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
868 | /* | 1156 | /* |
869 | * Suspend & resume. | 1157 | * Suspend & resume. |
870 | */ | 1158 | */ |
1159 | /** | ||
1160 | * radeon_suspend_kms - initiate device suspend | ||
1161 | * | ||
1162 | * @pdev: drm dev pointer | ||
1163 | * @state: suspend state | ||
1164 | * | ||
1165 | * Puts the hw in the suspend state (all asics). | ||
1166 | * Returns 0 for success or an error on failure. | ||
1167 | * Called at driver suspend. | ||
1168 | */ | ||
871 | int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | 1169 | int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) |
872 | { | 1170 | { |
873 | struct radeon_device *rdev; | 1171 | struct radeon_device *rdev; |
@@ -942,10 +1240,20 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
942 | return 0; | 1240 | return 0; |
943 | } | 1241 | } |
944 | 1242 | ||
1243 | /** | ||
1244 | * radeon_resume_kms - initiate device resume | ||
1245 | * | ||
1246 | * @pdev: drm dev pointer | ||
1247 | * | ||
1248 | * Bring the hw back to operating state (all asics). | ||
1249 | * Returns 0 for success or an error on failure. | ||
1250 | * Called at driver resume. | ||
1251 | */ | ||
945 | int radeon_resume_kms(struct drm_device *dev) | 1252 | int radeon_resume_kms(struct drm_device *dev) |
946 | { | 1253 | { |
947 | struct drm_connector *connector; | 1254 | struct drm_connector *connector; |
948 | struct radeon_device *rdev = dev->dev_private; | 1255 | struct radeon_device *rdev = dev->dev_private; |
1256 | int r; | ||
949 | 1257 | ||
950 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 1258 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
951 | return 0; | 1259 | return 0; |
@@ -960,6 +1268,11 @@ int radeon_resume_kms(struct drm_device *dev) | |||
960 | /* resume AGP if in use */ | 1268 | /* resume AGP if in use */ |
961 | radeon_agp_resume(rdev); | 1269 | radeon_agp_resume(rdev); |
962 | radeon_resume(rdev); | 1270 | radeon_resume(rdev); |
1271 | |||
1272 | r = radeon_ib_ring_tests(rdev); | ||
1273 | if (r) | ||
1274 | DRM_ERROR("ib ring test failed (%d).\n", r); | ||
1275 | |||
963 | radeon_pm_resume(rdev); | 1276 | radeon_pm_resume(rdev); |
964 | radeon_restore_bios_scratch_regs(rdev); | 1277 | radeon_restore_bios_scratch_regs(rdev); |
965 | 1278 | ||
@@ -984,30 +1297,77 @@ int radeon_resume_kms(struct drm_device *dev) | |||
984 | return 0; | 1297 | return 0; |
985 | } | 1298 | } |
986 | 1299 | ||
1300 | /** | ||
1301 | * radeon_gpu_reset - reset the asic | ||
1302 | * | ||
1303 | * @rdev: radeon device pointer | ||
1304 | * | ||
1305 | * Attempt the reset the GPU if it has hung (all asics). | ||
1306 | * Returns 0 for success or an error on failure. | ||
1307 | */ | ||
987 | int radeon_gpu_reset(struct radeon_device *rdev) | 1308 | int radeon_gpu_reset(struct radeon_device *rdev) |
988 | { | 1309 | { |
989 | int r; | 1310 | unsigned ring_sizes[RADEON_NUM_RINGS]; |
1311 | uint32_t *ring_data[RADEON_NUM_RINGS]; | ||
1312 | |||
1313 | bool saved = false; | ||
1314 | |||
1315 | int i, r; | ||
990 | int resched; | 1316 | int resched; |
991 | 1317 | ||
1318 | down_write(&rdev->exclusive_lock); | ||
992 | radeon_save_bios_scratch_regs(rdev); | 1319 | radeon_save_bios_scratch_regs(rdev); |
993 | /* block TTM */ | 1320 | /* block TTM */ |
994 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 1321 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
995 | radeon_suspend(rdev); | 1322 | radeon_suspend(rdev); |
996 | 1323 | ||
1324 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
1325 | ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i], | ||
1326 | &ring_data[i]); | ||
1327 | if (ring_sizes[i]) { | ||
1328 | saved = true; | ||
1329 | dev_info(rdev->dev, "Saved %d dwords of commands " | ||
1330 | "on ring %d.\n", ring_sizes[i], i); | ||
1331 | } | ||
1332 | } | ||
1333 | |||
1334 | retry: | ||
997 | r = radeon_asic_reset(rdev); | 1335 | r = radeon_asic_reset(rdev); |
998 | if (!r) { | 1336 | if (!r) { |
999 | dev_info(rdev->dev, "GPU reset succeed\n"); | 1337 | dev_info(rdev->dev, "GPU reset succeeded, trying to resume\n"); |
1000 | radeon_resume(rdev); | 1338 | radeon_resume(rdev); |
1001 | radeon_restore_bios_scratch_regs(rdev); | ||
1002 | drm_helper_resume_force_mode(rdev->ddev); | ||
1003 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | ||
1004 | } | 1339 | } |
1005 | 1340 | ||
1341 | radeon_restore_bios_scratch_regs(rdev); | ||
1342 | drm_helper_resume_force_mode(rdev->ddev); | ||
1343 | |||
1344 | if (!r) { | ||
1345 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
1346 | radeon_ring_restore(rdev, &rdev->ring[i], | ||
1347 | ring_sizes[i], ring_data[i]); | ||
1348 | } | ||
1349 | |||
1350 | r = radeon_ib_ring_tests(rdev); | ||
1351 | if (r) { | ||
1352 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); | ||
1353 | if (saved) { | ||
1354 | radeon_suspend(rdev); | ||
1355 | goto retry; | ||
1356 | } | ||
1357 | } | ||
1358 | } else { | ||
1359 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
1360 | kfree(ring_data[i]); | ||
1361 | } | ||
1362 | } | ||
1363 | |||
1364 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | ||
1006 | if (r) { | 1365 | if (r) { |
1007 | /* bad news, how to tell it to userspace ? */ | 1366 | /* bad news, how to tell it to userspace ? */ |
1008 | dev_info(rdev->dev, "GPU reset failed\n"); | 1367 | dev_info(rdev->dev, "GPU reset failed\n"); |
1009 | } | 1368 | } |
1010 | 1369 | ||
1370 | up_write(&rdev->exclusive_lock); | ||
1011 | return r; | 1371 | return r; |
1012 | } | 1372 | } |
1013 | 1373 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 64a008d14493..7ddef8f30d0e 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1401,7 +1401,7 @@ void radeon_modeset_fini(struct radeon_device *rdev) | |||
1401 | radeon_i2c_fini(rdev); | 1401 | radeon_i2c_fini(rdev); |
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | static bool is_hdtv_mode(struct drm_display_mode *mode) | 1404 | static bool is_hdtv_mode(const struct drm_display_mode *mode) |
1405 | { | 1405 | { |
1406 | /* try and guess if this is a tv or a monitor */ | 1406 | /* try and guess if this is a tv or a monitor */ |
1407 | if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ | 1407 | if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ |
@@ -1414,7 +1414,7 @@ static bool is_hdtv_mode(struct drm_display_mode *mode) | |||
1414 | } | 1414 | } |
1415 | 1415 | ||
1416 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 1416 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
1417 | struct drm_display_mode *mode, | 1417 | const struct drm_display_mode *mode, |
1418 | struct drm_display_mode *adjusted_mode) | 1418 | struct drm_display_mode *adjusted_mode) |
1419 | { | 1419 | { |
1420 | struct drm_device *dev = crtc->dev; | 1420 | struct drm_device *dev = crtc->dev; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 2c4d53fd20c5..dcea6f01ae4e 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -133,7 +133,7 @@ int radeon_tv = 1; | |||
133 | int radeon_audio = 0; | 133 | int radeon_audio = 0; |
134 | int radeon_disp_priority = 0; | 134 | int radeon_disp_priority = 0; |
135 | int radeon_hw_i2c = 0; | 135 | int radeon_hw_i2c = 0; |
136 | int radeon_pcie_gen2 = 0; | 136 | int radeon_pcie_gen2 = -1; |
137 | int radeon_msi = -1; | 137 | int radeon_msi = -1; |
138 | int radeon_lockup_timeout = 10000; | 138 | int radeon_lockup_timeout = 10000; |
139 | 139 | ||
@@ -179,7 +179,7 @@ module_param_named(disp_priority, radeon_disp_priority, int, 0444); | |||
179 | MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); | 179 | MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); |
180 | module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); | 180 | module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); |
181 | 181 | ||
182 | MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); | 182 | MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (-1 = auto, 0 = disable, 1 = enable)"); |
183 | module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); | 183 | module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); |
184 | 184 | ||
185 | MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); | 185 | MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); |
@@ -262,7 +262,6 @@ static struct drm_driver driver_old = { | |||
262 | .irq_postinstall = radeon_driver_irq_postinstall, | 262 | .irq_postinstall = radeon_driver_irq_postinstall, |
263 | .irq_uninstall = radeon_driver_irq_uninstall, | 263 | .irq_uninstall = radeon_driver_irq_uninstall, |
264 | .irq_handler = radeon_driver_irq_handler, | 264 | .irq_handler = radeon_driver_irq_handler, |
265 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
266 | .ioctls = radeon_ioctls, | 265 | .ioctls = radeon_ioctls, |
267 | .dma_ioctl = radeon_cp_buffers, | 266 | .dma_ioctl = radeon_cp_buffers, |
268 | .fops = &radeon_driver_old_fops, | 267 | .fops = &radeon_driver_old_fops, |
@@ -365,7 +364,6 @@ static struct drm_driver kms_driver = { | |||
365 | .irq_postinstall = radeon_driver_irq_postinstall_kms, | 364 | .irq_postinstall = radeon_driver_irq_postinstall_kms, |
366 | .irq_uninstall = radeon_driver_irq_uninstall_kms, | 365 | .irq_uninstall = radeon_driver_irq_uninstall_kms, |
367 | .irq_handler = radeon_driver_irq_handler_kms, | 366 | .irq_handler = radeon_driver_irq_handler_kms, |
368 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
369 | .ioctls = radeon_ioctls_kms, | 367 | .ioctls = radeon_ioctls_kms, |
370 | .gem_init_object = radeon_gem_object_init, | 368 | .gem_init_object = radeon_gem_object_init, |
371 | .gem_free_object = radeon_gem_object_free, | 369 | .gem_free_object = radeon_gem_object_free, |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 11f5f402d22c..7b737b9339ad 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -40,39 +40,95 @@ | |||
40 | #include "radeon.h" | 40 | #include "radeon.h" |
41 | #include "radeon_trace.h" | 41 | #include "radeon_trace.h" |
42 | 42 | ||
43 | /* | ||
44 | * Fences | ||
45 | * Fences mark an event in the GPUs pipeline and are used | ||
46 | * for GPU/CPU synchronization. When the fence is written, | ||
47 | * it is expected that all buffers associated with that fence | ||
48 | * are no longer in use by the associated ring on the GPU and | ||
49 | * that the the relevant GPU caches have been flushed. Whether | ||
50 | * we use a scratch register or memory location depends on the asic | ||
51 | * and whether writeback is enabled. | ||
52 | */ | ||
53 | |||
54 | /** | ||
55 | * radeon_fence_write - write a fence value | ||
56 | * | ||
57 | * @rdev: radeon_device pointer | ||
58 | * @seq: sequence number to write | ||
59 | * @ring: ring index the fence is associated with | ||
60 | * | ||
61 | * Writes a fence value to memory or a scratch register (all asics). | ||
62 | */ | ||
43 | static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) | 63 | static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) |
44 | { | 64 | { |
45 | if (rdev->wb.enabled) { | 65 | struct radeon_fence_driver *drv = &rdev->fence_drv[ring]; |
46 | *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq); | 66 | if (likely(rdev->wb.enabled || !drv->scratch_reg)) { |
67 | *drv->cpu_addr = cpu_to_le32(seq); | ||
47 | } else { | 68 | } else { |
48 | WREG32(rdev->fence_drv[ring].scratch_reg, seq); | 69 | WREG32(drv->scratch_reg, seq); |
49 | } | 70 | } |
50 | } | 71 | } |
51 | 72 | ||
73 | /** | ||
74 | * radeon_fence_read - read a fence value | ||
75 | * | ||
76 | * @rdev: radeon_device pointer | ||
77 | * @ring: ring index the fence is associated with | ||
78 | * | ||
79 | * Reads a fence value from memory or a scratch register (all asics). | ||
80 | * Returns the value of the fence read from memory or register. | ||
81 | */ | ||
52 | static u32 radeon_fence_read(struct radeon_device *rdev, int ring) | 82 | static u32 radeon_fence_read(struct radeon_device *rdev, int ring) |
53 | { | 83 | { |
84 | struct radeon_fence_driver *drv = &rdev->fence_drv[ring]; | ||
54 | u32 seq = 0; | 85 | u32 seq = 0; |
55 | 86 | ||
56 | if (rdev->wb.enabled) { | 87 | if (likely(rdev->wb.enabled || !drv->scratch_reg)) { |
57 | seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr); | 88 | seq = le32_to_cpu(*drv->cpu_addr); |
58 | } else { | 89 | } else { |
59 | seq = RREG32(rdev->fence_drv[ring].scratch_reg); | 90 | seq = RREG32(drv->scratch_reg); |
60 | } | 91 | } |
61 | return seq; | 92 | return seq; |
62 | } | 93 | } |
63 | 94 | ||
64 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) | 95 | /** |
96 | * radeon_fence_emit - emit a fence on the requested ring | ||
97 | * | ||
98 | * @rdev: radeon_device pointer | ||
99 | * @fence: radeon fence object | ||
100 | * @ring: ring index the fence is associated with | ||
101 | * | ||
102 | * Emits a fence command on the requested ring (all asics). | ||
103 | * Returns 0 on success, -ENOMEM on failure. | ||
104 | */ | ||
105 | int radeon_fence_emit(struct radeon_device *rdev, | ||
106 | struct radeon_fence **fence, | ||
107 | int ring) | ||
65 | { | 108 | { |
66 | /* we are protected by the ring emission mutex */ | 109 | /* we are protected by the ring emission mutex */ |
67 | if (fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { | 110 | *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); |
68 | return 0; | 111 | if ((*fence) == NULL) { |
112 | return -ENOMEM; | ||
69 | } | 113 | } |
70 | fence->seq = ++rdev->fence_drv[fence->ring].seq; | 114 | kref_init(&((*fence)->kref)); |
71 | radeon_fence_ring_emit(rdev, fence->ring, fence); | 115 | (*fence)->rdev = rdev; |
72 | trace_radeon_fence_emit(rdev->ddev, fence->seq); | 116 | (*fence)->seq = ++rdev->fence_drv[ring].sync_seq[ring]; |
117 | (*fence)->ring = ring; | ||
118 | radeon_fence_ring_emit(rdev, ring, *fence); | ||
119 | trace_radeon_fence_emit(rdev->ddev, (*fence)->seq); | ||
73 | return 0; | 120 | return 0; |
74 | } | 121 | } |
75 | 122 | ||
123 | /** | ||
124 | * radeon_fence_process - process a fence | ||
125 | * | ||
126 | * @rdev: radeon_device pointer | ||
127 | * @ring: ring index the fence is associated with | ||
128 | * | ||
129 | * Checks the current fence value and wakes the fence queue | ||
130 | * if the sequence number has increased (all asics). | ||
131 | */ | ||
76 | void radeon_fence_process(struct radeon_device *rdev, int ring) | 132 | void radeon_fence_process(struct radeon_device *rdev, int ring) |
77 | { | 133 | { |
78 | uint64_t seq, last_seq; | 134 | uint64_t seq, last_seq; |
@@ -133,30 +189,35 @@ void radeon_fence_process(struct radeon_device *rdev, int ring) | |||
133 | } | 189 | } |
134 | } | 190 | } |
135 | 191 | ||
192 | /** | ||
193 | * radeon_fence_destroy - destroy a fence | ||
194 | * | ||
195 | * @kref: fence kref | ||
196 | * | ||
197 | * Frees the fence object (all asics). | ||
198 | */ | ||
136 | static void radeon_fence_destroy(struct kref *kref) | 199 | static void radeon_fence_destroy(struct kref *kref) |
137 | { | 200 | { |
138 | struct radeon_fence *fence; | 201 | struct radeon_fence *fence; |
139 | 202 | ||
140 | fence = container_of(kref, struct radeon_fence, kref); | 203 | fence = container_of(kref, struct radeon_fence, kref); |
141 | fence->seq = RADEON_FENCE_NOTEMITED_SEQ; | ||
142 | kfree(fence); | 204 | kfree(fence); |
143 | } | 205 | } |
144 | 206 | ||
145 | int radeon_fence_create(struct radeon_device *rdev, | 207 | /** |
146 | struct radeon_fence **fence, | 208 | * radeon_fence_seq_signaled - check if a fence sequeuce number has signaled |
147 | int ring) | 209 | * |
148 | { | 210 | * @rdev: radeon device pointer |
149 | *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); | 211 | * @seq: sequence number |
150 | if ((*fence) == NULL) { | 212 | * @ring: ring index the fence is associated with |
151 | return -ENOMEM; | 213 | * |
152 | } | 214 | * Check if the last singled fence sequnce number is >= the requested |
153 | kref_init(&((*fence)->kref)); | 215 | * sequence number (all asics). |
154 | (*fence)->rdev = rdev; | 216 | * Returns true if the fence has signaled (current fence value |
155 | (*fence)->seq = RADEON_FENCE_NOTEMITED_SEQ; | 217 | * is >= requested value) or false if it has not (current fence |
156 | (*fence)->ring = ring; | 218 | * value is < the requested value. Helper function for |
157 | return 0; | 219 | * radeon_fence_signaled(). |
158 | } | 220 | */ |
159 | |||
160 | static bool radeon_fence_seq_signaled(struct radeon_device *rdev, | 221 | static bool radeon_fence_seq_signaled(struct radeon_device *rdev, |
161 | u64 seq, unsigned ring) | 222 | u64 seq, unsigned ring) |
162 | { | 223 | { |
@@ -171,15 +232,19 @@ static bool radeon_fence_seq_signaled(struct radeon_device *rdev, | |||
171 | return false; | 232 | return false; |
172 | } | 233 | } |
173 | 234 | ||
235 | /** | ||
236 | * radeon_fence_signaled - check if a fence has signaled | ||
237 | * | ||
238 | * @fence: radeon fence object | ||
239 | * | ||
240 | * Check if the requested fence has signaled (all asics). | ||
241 | * Returns true if the fence has signaled or false if it has not. | ||
242 | */ | ||
174 | bool radeon_fence_signaled(struct radeon_fence *fence) | 243 | bool radeon_fence_signaled(struct radeon_fence *fence) |
175 | { | 244 | { |
176 | if (!fence) { | 245 | if (!fence) { |
177 | return true; | 246 | return true; |
178 | } | 247 | } |
179 | if (fence->seq == RADEON_FENCE_NOTEMITED_SEQ) { | ||
180 | WARN(1, "Querying an unemitted fence : %p !\n", fence); | ||
181 | return true; | ||
182 | } | ||
183 | if (fence->seq == RADEON_FENCE_SIGNALED_SEQ) { | 248 | if (fence->seq == RADEON_FENCE_SIGNALED_SEQ) { |
184 | return true; | 249 | return true; |
185 | } | 250 | } |
@@ -190,6 +255,24 @@ bool radeon_fence_signaled(struct radeon_fence *fence) | |||
190 | return false; | 255 | return false; |
191 | } | 256 | } |
192 | 257 | ||
258 | /** | ||
259 | * radeon_fence_wait_seq - wait for a specific sequence number | ||
260 | * | ||
261 | * @rdev: radeon device pointer | ||
262 | * @target_seq: sequence number we want to wait for | ||
263 | * @ring: ring index the fence is associated with | ||
264 | * @intr: use interruptable sleep | ||
265 | * @lock_ring: whether the ring should be locked or not | ||
266 | * | ||
267 | * Wait for the requested sequence number to be written (all asics). | ||
268 | * @intr selects whether to use interruptable (true) or non-interruptable | ||
269 | * (false) sleep when waiting for the sequence number. Helper function | ||
270 | * for radeon_fence_wait(), et al. | ||
271 | * Returns 0 if the sequence number has passed, error for all other cases. | ||
272 | * -EDEADLK is returned when a GPU lockup has been detected and the ring is | ||
273 | * marked as not ready so no further jobs get scheduled until a successful | ||
274 | * reset. | ||
275 | */ | ||
193 | static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, | 276 | static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, |
194 | unsigned ring, bool intr, bool lock_ring) | 277 | unsigned ring, bool intr, bool lock_ring) |
195 | { | 278 | { |
@@ -285,6 +368,17 @@ static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, | |||
285 | return 0; | 368 | return 0; |
286 | } | 369 | } |
287 | 370 | ||
371 | /** | ||
372 | * radeon_fence_wait - wait for a fence to signal | ||
373 | * | ||
374 | * @fence: radeon fence object | ||
375 | * @intr: use interruptable sleep | ||
376 | * | ||
377 | * Wait for the requested fence to signal (all asics). | ||
378 | * @intr selects whether to use interruptable (true) or non-interruptable | ||
379 | * (false) sleep when waiting for the fence. | ||
380 | * Returns 0 if the fence has passed, error for all other cases. | ||
381 | */ | ||
288 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) | 382 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) |
289 | { | 383 | { |
290 | int r; | 384 | int r; |
@@ -315,6 +409,20 @@ bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) | |||
315 | return false; | 409 | return false; |
316 | } | 410 | } |
317 | 411 | ||
412 | /** | ||
413 | * radeon_fence_wait_any_seq - wait for a sequence number on any ring | ||
414 | * | ||
415 | * @rdev: radeon device pointer | ||
416 | * @target_seq: sequence number(s) we want to wait for | ||
417 | * @intr: use interruptable sleep | ||
418 | * | ||
419 | * Wait for the requested sequence number(s) to be written by any ring | ||
420 | * (all asics). Sequnce number array is indexed by ring id. | ||
421 | * @intr selects whether to use interruptable (true) or non-interruptable | ||
422 | * (false) sleep when waiting for the sequence number. Helper function | ||
423 | * for radeon_fence_wait_any(), et al. | ||
424 | * Returns 0 if the sequence number has passed, error for all other cases. | ||
425 | */ | ||
318 | static int radeon_fence_wait_any_seq(struct radeon_device *rdev, | 426 | static int radeon_fence_wait_any_seq(struct radeon_device *rdev, |
319 | u64 *target_seq, bool intr) | 427 | u64 *target_seq, bool intr) |
320 | { | 428 | { |
@@ -343,7 +451,7 @@ static int radeon_fence_wait_any_seq(struct radeon_device *rdev, | |||
343 | 451 | ||
344 | /* nothing to wait for ? */ | 452 | /* nothing to wait for ? */ |
345 | if (ring == RADEON_NUM_RINGS) { | 453 | if (ring == RADEON_NUM_RINGS) { |
346 | return 0; | 454 | return -ENOENT; |
347 | } | 455 | } |
348 | 456 | ||
349 | while (!radeon_fence_any_seq_signaled(rdev, target_seq)) { | 457 | while (!radeon_fence_any_seq_signaled(rdev, target_seq)) { |
@@ -424,6 +532,19 @@ static int radeon_fence_wait_any_seq(struct radeon_device *rdev, | |||
424 | return 0; | 532 | return 0; |
425 | } | 533 | } |
426 | 534 | ||
535 | /** | ||
536 | * radeon_fence_wait_any - wait for a fence to signal on any ring | ||
537 | * | ||
538 | * @rdev: radeon device pointer | ||
539 | * @fences: radeon fence object(s) | ||
540 | * @intr: use interruptable sleep | ||
541 | * | ||
542 | * Wait for any requested fence to signal (all asics). Fence | ||
543 | * array is indexed by ring id. @intr selects whether to use | ||
544 | * interruptable (true) or non-interruptable (false) sleep when | ||
545 | * waiting for the fences. Used by the suballocator. | ||
546 | * Returns 0 if any fence has passed, error for all other cases. | ||
547 | */ | ||
427 | int radeon_fence_wait_any(struct radeon_device *rdev, | 548 | int radeon_fence_wait_any(struct radeon_device *rdev, |
428 | struct radeon_fence **fences, | 549 | struct radeon_fence **fences, |
429 | bool intr) | 550 | bool intr) |
@@ -444,9 +565,7 @@ int radeon_fence_wait_any(struct radeon_device *rdev, | |||
444 | return 0; | 565 | return 0; |
445 | } | 566 | } |
446 | 567 | ||
447 | if (fences[i]->seq < RADEON_FENCE_NOTEMITED_SEQ) { | 568 | seq[i] = fences[i]->seq; |
448 | seq[i] = fences[i]->seq; | ||
449 | } | ||
450 | } | 569 | } |
451 | 570 | ||
452 | r = radeon_fence_wait_any_seq(rdev, seq, intr); | 571 | r = radeon_fence_wait_any_seq(rdev, seq, intr); |
@@ -456,16 +575,22 @@ int radeon_fence_wait_any(struct radeon_device *rdev, | |||
456 | return 0; | 575 | return 0; |
457 | } | 576 | } |
458 | 577 | ||
578 | /** | ||
579 | * radeon_fence_wait_next_locked - wait for the next fence to signal | ||
580 | * | ||
581 | * @rdev: radeon device pointer | ||
582 | * @ring: ring index the fence is associated with | ||
583 | * | ||
584 | * Wait for the next fence on the requested ring to signal (all asics). | ||
585 | * Returns 0 if the next fence has passed, error for all other cases. | ||
586 | * Caller must hold ring lock. | ||
587 | */ | ||
459 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) | 588 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) |
460 | { | 589 | { |
461 | uint64_t seq; | 590 | uint64_t seq; |
462 | 591 | ||
463 | /* We are not protected by ring lock when reading current seq but | ||
464 | * it's ok as worst case is we return to early while we could have | ||
465 | * wait. | ||
466 | */ | ||
467 | seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL; | 592 | seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL; |
468 | if (seq >= rdev->fence_drv[ring].seq) { | 593 | if (seq >= rdev->fence_drv[ring].sync_seq[ring]) { |
469 | /* nothing to wait for, last_seq is | 594 | /* nothing to wait for, last_seq is |
470 | already the last emited fence */ | 595 | already the last emited fence */ |
471 | return -ENOENT; | 596 | return -ENOENT; |
@@ -473,23 +598,59 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) | |||
473 | return radeon_fence_wait_seq(rdev, seq, ring, false, false); | 598 | return radeon_fence_wait_seq(rdev, seq, ring, false, false); |
474 | } | 599 | } |
475 | 600 | ||
476 | int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) | 601 | /** |
602 | * radeon_fence_wait_empty_locked - wait for all fences to signal | ||
603 | * | ||
604 | * @rdev: radeon device pointer | ||
605 | * @ring: ring index the fence is associated with | ||
606 | * | ||
607 | * Wait for all fences on the requested ring to signal (all asics). | ||
608 | * Returns 0 if the fences have passed, error for all other cases. | ||
609 | * Caller must hold ring lock. | ||
610 | */ | ||
611 | void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) | ||
477 | { | 612 | { |
478 | /* We are not protected by ring lock when reading current seq | 613 | uint64_t seq = rdev->fence_drv[ring].sync_seq[ring]; |
479 | * but it's ok as wait empty is call from place where no more | 614 | |
480 | * activity can be scheduled so there won't be concurrent access | 615 | while(1) { |
481 | * to seq value. | 616 | int r; |
482 | */ | 617 | r = radeon_fence_wait_seq(rdev, seq, ring, false, false); |
483 | return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].seq, | 618 | if (r == -EDEADLK) { |
484 | ring, false, false); | 619 | mutex_unlock(&rdev->ring_lock); |
620 | r = radeon_gpu_reset(rdev); | ||
621 | mutex_lock(&rdev->ring_lock); | ||
622 | if (!r) | ||
623 | continue; | ||
624 | } | ||
625 | if (r) { | ||
626 | dev_err(rdev->dev, "error waiting for ring to become" | ||
627 | " idle (%d)\n", r); | ||
628 | } | ||
629 | return; | ||
630 | } | ||
485 | } | 631 | } |
486 | 632 | ||
633 | /** | ||
634 | * radeon_fence_ref - take a ref on a fence | ||
635 | * | ||
636 | * @fence: radeon fence object | ||
637 | * | ||
638 | * Take a reference on a fence (all asics). | ||
639 | * Returns the fence. | ||
640 | */ | ||
487 | struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) | 641 | struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) |
488 | { | 642 | { |
489 | kref_get(&fence->kref); | 643 | kref_get(&fence->kref); |
490 | return fence; | 644 | return fence; |
491 | } | 645 | } |
492 | 646 | ||
647 | /** | ||
648 | * radeon_fence_unref - remove a ref on a fence | ||
649 | * | ||
650 | * @fence: radeon fence object | ||
651 | * | ||
652 | * Remove a reference on a fence (all asics). | ||
653 | */ | ||
493 | void radeon_fence_unref(struct radeon_fence **fence) | 654 | void radeon_fence_unref(struct radeon_fence **fence) |
494 | { | 655 | { |
495 | struct radeon_fence *tmp = *fence; | 656 | struct radeon_fence *tmp = *fence; |
@@ -500,6 +661,16 @@ void radeon_fence_unref(struct radeon_fence **fence) | |||
500 | } | 661 | } |
501 | } | 662 | } |
502 | 663 | ||
664 | /** | ||
665 | * radeon_fence_count_emitted - get the count of emitted fences | ||
666 | * | ||
667 | * @rdev: radeon device pointer | ||
668 | * @ring: ring index the fence is associated with | ||
669 | * | ||
670 | * Get the number of fences emitted on the requested ring (all asics). | ||
671 | * Returns the number of emitted fences on the ring. Used by the | ||
672 | * dynpm code to ring track activity. | ||
673 | */ | ||
503 | unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring) | 674 | unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring) |
504 | { | 675 | { |
505 | uint64_t emitted; | 676 | uint64_t emitted; |
@@ -508,7 +679,8 @@ unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring) | |||
508 | * but it's ok to report slightly wrong fence count here. | 679 | * but it's ok to report slightly wrong fence count here. |
509 | */ | 680 | */ |
510 | radeon_fence_process(rdev, ring); | 681 | radeon_fence_process(rdev, ring); |
511 | emitted = rdev->fence_drv[ring].seq - atomic64_read(&rdev->fence_drv[ring].last_seq); | 682 | emitted = rdev->fence_drv[ring].sync_seq[ring] |
683 | - atomic64_read(&rdev->fence_drv[ring].last_seq); | ||
512 | /* to avoid 32bits warp around */ | 684 | /* to avoid 32bits warp around */ |
513 | if (emitted > 0x10000000) { | 685 | if (emitted > 0x10000000) { |
514 | emitted = 0x10000000; | 686 | emitted = 0x10000000; |
@@ -516,6 +688,83 @@ unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring) | |||
516 | return (unsigned)emitted; | 688 | return (unsigned)emitted; |
517 | } | 689 | } |
518 | 690 | ||
691 | /** | ||
692 | * radeon_fence_need_sync - do we need a semaphore | ||
693 | * | ||
694 | * @fence: radeon fence object | ||
695 | * @dst_ring: which ring to check against | ||
696 | * | ||
697 | * Check if the fence needs to be synced against another ring | ||
698 | * (all asics). If so, we need to emit a semaphore. | ||
699 | * Returns true if we need to sync with another ring, false if | ||
700 | * not. | ||
701 | */ | ||
702 | bool radeon_fence_need_sync(struct radeon_fence *fence, int dst_ring) | ||
703 | { | ||
704 | struct radeon_fence_driver *fdrv; | ||
705 | |||
706 | if (!fence) { | ||
707 | return false; | ||
708 | } | ||
709 | |||
710 | if (fence->ring == dst_ring) { | ||
711 | return false; | ||
712 | } | ||
713 | |||
714 | /* we are protected by the ring mutex */ | ||
715 | fdrv = &fence->rdev->fence_drv[dst_ring]; | ||
716 | if (fence->seq <= fdrv->sync_seq[fence->ring]) { | ||
717 | return false; | ||
718 | } | ||
719 | |||
720 | return true; | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * radeon_fence_note_sync - record the sync point | ||
725 | * | ||
726 | * @fence: radeon fence object | ||
727 | * @dst_ring: which ring to check against | ||
728 | * | ||
729 | * Note the sequence number at which point the fence will | ||
730 | * be synced with the requested ring (all asics). | ||
731 | */ | ||
732 | void radeon_fence_note_sync(struct radeon_fence *fence, int dst_ring) | ||
733 | { | ||
734 | struct radeon_fence_driver *dst, *src; | ||
735 | unsigned i; | ||
736 | |||
737 | if (!fence) { | ||
738 | return; | ||
739 | } | ||
740 | |||
741 | if (fence->ring == dst_ring) { | ||
742 | return; | ||
743 | } | ||
744 | |||
745 | /* we are protected by the ring mutex */ | ||
746 | src = &fence->rdev->fence_drv[fence->ring]; | ||
747 | dst = &fence->rdev->fence_drv[dst_ring]; | ||
748 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
749 | if (i == dst_ring) { | ||
750 | continue; | ||
751 | } | ||
752 | dst->sync_seq[i] = max(dst->sync_seq[i], src->sync_seq[i]); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | /** | ||
757 | * radeon_fence_driver_start_ring - make the fence driver | ||
758 | * ready for use on the requested ring. | ||
759 | * | ||
760 | * @rdev: radeon device pointer | ||
761 | * @ring: ring index to start the fence driver on | ||
762 | * | ||
763 | * Make the fence driver ready for processing (all asics). | ||
764 | * Not all asics have all rings, so each asic will only | ||
765 | * start the fence driver on the rings it has. | ||
766 | * Returns 0 for success, errors for failure. | ||
767 | */ | ||
519 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) | 768 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) |
520 | { | 769 | { |
521 | uint64_t index; | 770 | uint64_t index; |
@@ -537,24 +786,49 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) | |||
537 | } | 786 | } |
538 | rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; | 787 | rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; |
539 | rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; | 788 | rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; |
540 | radeon_fence_write(rdev, rdev->fence_drv[ring].seq, ring); | 789 | radeon_fence_write(rdev, atomic64_read(&rdev->fence_drv[ring].last_seq), ring); |
541 | rdev->fence_drv[ring].initialized = true; | 790 | rdev->fence_drv[ring].initialized = true; |
542 | dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n", | 791 | dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n", |
543 | ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); | 792 | ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); |
544 | return 0; | 793 | return 0; |
545 | } | 794 | } |
546 | 795 | ||
796 | /** | ||
797 | * radeon_fence_driver_init_ring - init the fence driver | ||
798 | * for the requested ring. | ||
799 | * | ||
800 | * @rdev: radeon device pointer | ||
801 | * @ring: ring index to start the fence driver on | ||
802 | * | ||
803 | * Init the fence driver for the requested ring (all asics). | ||
804 | * Helper function for radeon_fence_driver_init(). | ||
805 | */ | ||
547 | static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) | 806 | static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) |
548 | { | 807 | { |
808 | int i; | ||
809 | |||
549 | rdev->fence_drv[ring].scratch_reg = -1; | 810 | rdev->fence_drv[ring].scratch_reg = -1; |
550 | rdev->fence_drv[ring].cpu_addr = NULL; | 811 | rdev->fence_drv[ring].cpu_addr = NULL; |
551 | rdev->fence_drv[ring].gpu_addr = 0; | 812 | rdev->fence_drv[ring].gpu_addr = 0; |
552 | rdev->fence_drv[ring].seq = 0; | 813 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
814 | rdev->fence_drv[ring].sync_seq[i] = 0; | ||
553 | atomic64_set(&rdev->fence_drv[ring].last_seq, 0); | 815 | atomic64_set(&rdev->fence_drv[ring].last_seq, 0); |
554 | rdev->fence_drv[ring].last_activity = jiffies; | 816 | rdev->fence_drv[ring].last_activity = jiffies; |
555 | rdev->fence_drv[ring].initialized = false; | 817 | rdev->fence_drv[ring].initialized = false; |
556 | } | 818 | } |
557 | 819 | ||
820 | /** | ||
821 | * radeon_fence_driver_init - init the fence driver | ||
822 | * for all possible rings. | ||
823 | * | ||
824 | * @rdev: radeon device pointer | ||
825 | * | ||
826 | * Init the fence driver for all possible rings (all asics). | ||
827 | * Not all asics have all rings, so each asic will only | ||
828 | * start the fence driver on the rings it has using | ||
829 | * radeon_fence_driver_start_ring(). | ||
830 | * Returns 0 for success. | ||
831 | */ | ||
558 | int radeon_fence_driver_init(struct radeon_device *rdev) | 832 | int radeon_fence_driver_init(struct radeon_device *rdev) |
559 | { | 833 | { |
560 | int ring; | 834 | int ring; |
@@ -569,6 +843,14 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
569 | return 0; | 843 | return 0; |
570 | } | 844 | } |
571 | 845 | ||
846 | /** | ||
847 | * radeon_fence_driver_fini - tear down the fence driver | ||
848 | * for all possible rings. | ||
849 | * | ||
850 | * @rdev: radeon device pointer | ||
851 | * | ||
852 | * Tear down the fence driver for all possible rings (all asics). | ||
853 | */ | ||
572 | void radeon_fence_driver_fini(struct radeon_device *rdev) | 854 | void radeon_fence_driver_fini(struct radeon_device *rdev) |
573 | { | 855 | { |
574 | int ring; | 856 | int ring; |
@@ -595,7 +877,7 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data) | |||
595 | struct drm_info_node *node = (struct drm_info_node *)m->private; | 877 | struct drm_info_node *node = (struct drm_info_node *)m->private; |
596 | struct drm_device *dev = node->minor->dev; | 878 | struct drm_device *dev = node->minor->dev; |
597 | struct radeon_device *rdev = dev->dev_private; | 879 | struct radeon_device *rdev = dev->dev_private; |
598 | int i; | 880 | int i, j; |
599 | 881 | ||
600 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 882 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
601 | if (!rdev->fence_drv[i].initialized) | 883 | if (!rdev->fence_drv[i].initialized) |
@@ -604,8 +886,14 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data) | |||
604 | seq_printf(m, "--- ring %d ---\n", i); | 886 | seq_printf(m, "--- ring %d ---\n", i); |
605 | seq_printf(m, "Last signaled fence 0x%016llx\n", | 887 | seq_printf(m, "Last signaled fence 0x%016llx\n", |
606 | (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq)); | 888 | (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq)); |
607 | seq_printf(m, "Last emitted 0x%016llx\n", | 889 | seq_printf(m, "Last emitted 0x%016llx\n", |
608 | rdev->fence_drv[i].seq); | 890 | rdev->fence_drv[i].sync_seq[i]); |
891 | |||
892 | for (j = 0; j < RADEON_NUM_RINGS; ++j) { | ||
893 | if (i != j && rdev->fence_drv[j].initialized) | ||
894 | seq_printf(m, "Last sync to ring %d 0x%016llx\n", | ||
895 | j, rdev->fence_drv[i].sync_seq[j]); | ||
896 | } | ||
609 | } | 897 | } |
610 | return 0; | 898 | return 0; |
611 | } | 899 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 84b648a7ddd8..b3720054614d 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -31,8 +31,38 @@ | |||
31 | #include "radeon_reg.h" | 31 | #include "radeon_reg.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * GART | ||
35 | * The GART (Graphics Aperture Remapping Table) is an aperture | ||
36 | * in the GPU's address space. System pages can be mapped into | ||
37 | * the aperture and look like contiguous pages from the GPU's | ||
38 | * perspective. A page table maps the pages in the aperture | ||
39 | * to the actual backing pages in system memory. | ||
40 | * | ||
41 | * Radeon GPUs support both an internal GART, as described above, | ||
42 | * and AGP. AGP works similarly, but the GART table is configured | ||
43 | * and maintained by the northbridge rather than the driver. | ||
44 | * Radeon hw has a separate AGP aperture that is programmed to | ||
45 | * point to the AGP aperture provided by the northbridge and the | ||
46 | * requests are passed through to the northbridge aperture. | ||
47 | * Both AGP and internal GART can be used at the same time, however | ||
48 | * that is not currently supported by the driver. | ||
49 | * | ||
50 | * This file handles the common internal GART management. | ||
51 | */ | ||
52 | |||
53 | /* | ||
34 | * Common GART table functions. | 54 | * Common GART table functions. |
35 | */ | 55 | */ |
56 | /** | ||
57 | * radeon_gart_table_ram_alloc - allocate system ram for gart page table | ||
58 | * | ||
59 | * @rdev: radeon_device pointer | ||
60 | * | ||
61 | * Allocate system memory for GART page table | ||
62 | * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the | ||
63 | * gart table to be in system memory. | ||
64 | * Returns 0 for success, -ENOMEM for failure. | ||
65 | */ | ||
36 | int radeon_gart_table_ram_alloc(struct radeon_device *rdev) | 66 | int radeon_gart_table_ram_alloc(struct radeon_device *rdev) |
37 | { | 67 | { |
38 | void *ptr; | 68 | void *ptr; |
@@ -54,6 +84,15 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev) | |||
54 | return 0; | 84 | return 0; |
55 | } | 85 | } |
56 | 86 | ||
87 | /** | ||
88 | * radeon_gart_table_ram_free - free system ram for gart page table | ||
89 | * | ||
90 | * @rdev: radeon_device pointer | ||
91 | * | ||
92 | * Free system memory for GART page table | ||
93 | * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the | ||
94 | * gart table to be in system memory. | ||
95 | */ | ||
57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) | 96 | void radeon_gart_table_ram_free(struct radeon_device *rdev) |
58 | { | 97 | { |
59 | if (rdev->gart.ptr == NULL) { | 98 | if (rdev->gart.ptr == NULL) { |
@@ -73,6 +112,16 @@ void radeon_gart_table_ram_free(struct radeon_device *rdev) | |||
73 | rdev->gart.table_addr = 0; | 112 | rdev->gart.table_addr = 0; |
74 | } | 113 | } |
75 | 114 | ||
115 | /** | ||
116 | * radeon_gart_table_vram_alloc - allocate vram for gart page table | ||
117 | * | ||
118 | * @rdev: radeon_device pointer | ||
119 | * | ||
120 | * Allocate video memory for GART page table | ||
121 | * (pcie r4xx, r5xx+). These asics require the | ||
122 | * gart table to be in video memory. | ||
123 | * Returns 0 for success, error for failure. | ||
124 | */ | ||
76 | int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | 125 | int radeon_gart_table_vram_alloc(struct radeon_device *rdev) |
77 | { | 126 | { |
78 | int r; | 127 | int r; |
@@ -88,6 +137,16 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
88 | return 0; | 137 | return 0; |
89 | } | 138 | } |
90 | 139 | ||
140 | /** | ||
141 | * radeon_gart_table_vram_pin - pin gart page table in vram | ||
142 | * | ||
143 | * @rdev: radeon_device pointer | ||
144 | * | ||
145 | * Pin the GART page table in vram so it will not be moved | ||
146 | * by the memory manager (pcie r4xx, r5xx+). These asics require the | ||
147 | * gart table to be in video memory. | ||
148 | * Returns 0 for success, error for failure. | ||
149 | */ | ||
91 | int radeon_gart_table_vram_pin(struct radeon_device *rdev) | 150 | int radeon_gart_table_vram_pin(struct radeon_device *rdev) |
92 | { | 151 | { |
93 | uint64_t gpu_addr; | 152 | uint64_t gpu_addr; |
@@ -110,6 +169,14 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) | |||
110 | return r; | 169 | return r; |
111 | } | 170 | } |
112 | 171 | ||
172 | /** | ||
173 | * radeon_gart_table_vram_unpin - unpin gart page table in vram | ||
174 | * | ||
175 | * @rdev: radeon_device pointer | ||
176 | * | ||
177 | * Unpin the GART page table in vram (pcie r4xx, r5xx+). | ||
178 | * These asics require the gart table to be in video memory. | ||
179 | */ | ||
113 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev) | 180 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev) |
114 | { | 181 | { |
115 | int r; | 182 | int r; |
@@ -126,6 +193,15 @@ void radeon_gart_table_vram_unpin(struct radeon_device *rdev) | |||
126 | } | 193 | } |
127 | } | 194 | } |
128 | 195 | ||
196 | /** | ||
197 | * radeon_gart_table_vram_free - free gart page table vram | ||
198 | * | ||
199 | * @rdev: radeon_device pointer | ||
200 | * | ||
201 | * Free the video memory used for the GART page table | ||
202 | * (pcie r4xx, r5xx+). These asics require the gart table to | ||
203 | * be in video memory. | ||
204 | */ | ||
129 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | 205 | void radeon_gart_table_vram_free(struct radeon_device *rdev) |
130 | { | 206 | { |
131 | if (rdev->gart.robj == NULL) { | 207 | if (rdev->gart.robj == NULL) { |
@@ -135,12 +211,19 @@ void radeon_gart_table_vram_free(struct radeon_device *rdev) | |||
135 | radeon_bo_unref(&rdev->gart.robj); | 211 | radeon_bo_unref(&rdev->gart.robj); |
136 | } | 212 | } |
137 | 213 | ||
138 | |||
139 | |||
140 | |||
141 | /* | 214 | /* |
142 | * Common gart functions. | 215 | * Common gart functions. |
143 | */ | 216 | */ |
217 | /** | ||
218 | * radeon_gart_unbind - unbind pages from the gart page table | ||
219 | * | ||
220 | * @rdev: radeon_device pointer | ||
221 | * @offset: offset into the GPU's gart aperture | ||
222 | * @pages: number of pages to unbind | ||
223 | * | ||
224 | * Unbinds the requested pages from the gart page table and | ||
225 | * replaces them with the dummy page (all asics). | ||
226 | */ | ||
144 | void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | 227 | void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, |
145 | int pages) | 228 | int pages) |
146 | { | 229 | { |
@@ -172,6 +255,19 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
172 | radeon_gart_tlb_flush(rdev); | 255 | radeon_gart_tlb_flush(rdev); |
173 | } | 256 | } |
174 | 257 | ||
258 | /** | ||
259 | * radeon_gart_bind - bind pages into the gart page table | ||
260 | * | ||
261 | * @rdev: radeon_device pointer | ||
262 | * @offset: offset into the GPU's gart aperture | ||
263 | * @pages: number of pages to bind | ||
264 | * @pagelist: pages to bind | ||
265 | * @dma_addr: DMA addresses of pages | ||
266 | * | ||
267 | * Binds the requested pages to the gart page table | ||
268 | * (all asics). | ||
269 | * Returns 0 for success, -EINVAL for failure. | ||
270 | */ | ||
175 | int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | 271 | int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, |
176 | int pages, struct page **pagelist, dma_addr_t *dma_addr) | 272 | int pages, struct page **pagelist, dma_addr_t *dma_addr) |
177 | { | 273 | { |
@@ -203,6 +299,14 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
203 | return 0; | 299 | return 0; |
204 | } | 300 | } |
205 | 301 | ||
302 | /** | ||
303 | * radeon_gart_restore - bind all pages in the gart page table | ||
304 | * | ||
305 | * @rdev: radeon_device pointer | ||
306 | * | ||
307 | * Binds all pages in the gart page table (all asics). | ||
308 | * Used to rebuild the gart table on device startup or resume. | ||
309 | */ | ||
206 | void radeon_gart_restore(struct radeon_device *rdev) | 310 | void radeon_gart_restore(struct radeon_device *rdev) |
207 | { | 311 | { |
208 | int i, j, t; | 312 | int i, j, t; |
@@ -222,6 +326,14 @@ void radeon_gart_restore(struct radeon_device *rdev) | |||
222 | radeon_gart_tlb_flush(rdev); | 326 | radeon_gart_tlb_flush(rdev); |
223 | } | 327 | } |
224 | 328 | ||
329 | /** | ||
330 | * radeon_gart_init - init the driver info for managing the gart | ||
331 | * | ||
332 | * @rdev: radeon_device pointer | ||
333 | * | ||
334 | * Allocate the dummy page and init the gart driver info (all asics). | ||
335 | * Returns 0 for success, error for failure. | ||
336 | */ | ||
225 | int radeon_gart_init(struct radeon_device *rdev) | 337 | int radeon_gart_init(struct radeon_device *rdev) |
226 | { | 338 | { |
227 | int r, i; | 339 | int r, i; |
@@ -262,6 +374,13 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
262 | return 0; | 374 | return 0; |
263 | } | 375 | } |
264 | 376 | ||
377 | /** | ||
378 | * radeon_gart_fini - tear down the driver info for managing the gart | ||
379 | * | ||
380 | * @rdev: radeon_device pointer | ||
381 | * | ||
382 | * Tear down the gart driver info and free the dummy page (all asics). | ||
383 | */ | ||
265 | void radeon_gart_fini(struct radeon_device *rdev) | 384 | void radeon_gart_fini(struct radeon_device *rdev) |
266 | { | 385 | { |
267 | if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { | 386 | if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { |
@@ -278,35 +397,104 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
278 | } | 397 | } |
279 | 398 | ||
280 | /* | 399 | /* |
400 | * GPUVM | ||
401 | * GPUVM is similar to the legacy gart on older asics, however | ||
402 | * rather than there being a single global gart table | ||
403 | * for the entire GPU, there are multiple VM page tables active | ||
404 | * at any given time. The VM page tables can contain a mix | ||
405 | * vram pages and system memory pages and system memory pages | ||
406 | * can be mapped as snooped (cached system pages) or unsnooped | ||
407 | * (uncached system pages). | ||
408 | * Each VM has an ID associated with it and there is a page table | ||
409 | * associated with each VMID. When execting a command buffer, | ||
410 | * the kernel tells the the ring what VMID to use for that command | ||
411 | * buffer. VMIDs are allocated dynamically as commands are submitted. | ||
412 | * The userspace drivers maintain their own address space and the kernel | ||
413 | * sets up their pages tables accordingly when they submit their | ||
414 | * command buffers and a VMID is assigned. | ||
415 | * Cayman/Trinity support up to 8 active VMs at any given time; | ||
416 | * SI supports 16. | ||
417 | */ | ||
418 | |||
419 | /* | ||
281 | * vm helpers | 420 | * vm helpers |
282 | * | 421 | * |
283 | * TODO bind a default page at vm initialization for default address | 422 | * TODO bind a default page at vm initialization for default address |
284 | */ | 423 | */ |
424 | |||
425 | /** | ||
426 | * radeon_vm_manager_init - init the vm manager | ||
427 | * | ||
428 | * @rdev: radeon_device pointer | ||
429 | * | ||
430 | * Init the vm manager (cayman+). | ||
431 | * Returns 0 for success, error for failure. | ||
432 | */ | ||
285 | int radeon_vm_manager_init(struct radeon_device *rdev) | 433 | int radeon_vm_manager_init(struct radeon_device *rdev) |
286 | { | 434 | { |
435 | struct radeon_vm *vm; | ||
436 | struct radeon_bo_va *bo_va; | ||
287 | int r; | 437 | int r; |
288 | 438 | ||
289 | rdev->vm_manager.enabled = false; | 439 | if (!rdev->vm_manager.enabled) { |
440 | /* mark first vm as always in use, it's the system one */ | ||
441 | /* allocate enough for 2 full VM pts */ | ||
442 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, | ||
443 | rdev->vm_manager.max_pfn * 8 * 2, | ||
444 | RADEON_GEM_DOMAIN_VRAM); | ||
445 | if (r) { | ||
446 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", | ||
447 | (rdev->vm_manager.max_pfn * 8) >> 10); | ||
448 | return r; | ||
449 | } | ||
290 | 450 | ||
291 | /* mark first vm as always in use, it's the system one */ | 451 | r = rdev->vm_manager.funcs->init(rdev); |
292 | /* allocate enough for 2 full VM pts */ | 452 | if (r) |
293 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, | 453 | return r; |
294 | rdev->vm_manager.max_pfn * 8 * 2, | 454 | |
295 | RADEON_GEM_DOMAIN_VRAM); | 455 | rdev->vm_manager.enabled = true; |
296 | if (r) { | 456 | |
297 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", | 457 | r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); |
298 | (rdev->vm_manager.max_pfn * 8) >> 10); | 458 | if (r) |
299 | return r; | 459 | return r; |
300 | } | 460 | } |
301 | 461 | ||
302 | r = rdev->vm_manager.funcs->init(rdev); | 462 | /* restore page table */ |
303 | if (r == 0) | 463 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { |
304 | rdev->vm_manager.enabled = true; | 464 | if (vm->id == -1) |
465 | continue; | ||
305 | 466 | ||
306 | return r; | 467 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
468 | struct ttm_mem_reg *mem = NULL; | ||
469 | if (bo_va->valid) | ||
470 | mem = &bo_va->bo->tbo.mem; | ||
471 | |||
472 | bo_va->valid = false; | ||
473 | r = radeon_vm_bo_update_pte(rdev, vm, bo_va->bo, mem); | ||
474 | if (r) { | ||
475 | DRM_ERROR("Failed to update pte for vm %d!\n", vm->id); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id); | ||
480 | if (r) { | ||
481 | DRM_ERROR("Failed to bind vm %d!\n", vm->id); | ||
482 | } | ||
483 | } | ||
484 | return 0; | ||
307 | } | 485 | } |
308 | 486 | ||
309 | /* cs mutex must be lock */ | 487 | /* global mutex must be lock */ |
488 | /** | ||
489 | * radeon_vm_unbind_locked - unbind a specific vm | ||
490 | * | ||
491 | * @rdev: radeon_device pointer | ||
492 | * @vm: vm to unbind | ||
493 | * | ||
494 | * Unbind the requested vm (cayman+). | ||
495 | * Wait for use of the VM to finish, then unbind the page table, | ||
496 | * and free the page table memory. | ||
497 | */ | ||
310 | static void radeon_vm_unbind_locked(struct radeon_device *rdev, | 498 | static void radeon_vm_unbind_locked(struct radeon_device *rdev, |
311 | struct radeon_vm *vm) | 499 | struct radeon_vm *vm) |
312 | { | 500 | { |
@@ -317,10 +505,21 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, | |||
317 | } | 505 | } |
318 | 506 | ||
319 | /* wait for vm use to end */ | 507 | /* wait for vm use to end */ |
320 | if (vm->fence) { | 508 | while (vm->fence) { |
321 | radeon_fence_wait(vm->fence, false); | 509 | int r; |
322 | radeon_fence_unref(&vm->fence); | 510 | r = radeon_fence_wait(vm->fence, false); |
511 | if (r) | ||
512 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
513 | if (r == -EDEADLK) { | ||
514 | mutex_unlock(&rdev->vm_manager.lock); | ||
515 | r = radeon_gpu_reset(rdev); | ||
516 | mutex_lock(&rdev->vm_manager.lock); | ||
517 | if (!r) | ||
518 | continue; | ||
519 | } | ||
520 | break; | ||
323 | } | 521 | } |
522 | radeon_fence_unref(&vm->fence); | ||
324 | 523 | ||
325 | /* hw unbind */ | 524 | /* hw unbind */ |
326 | rdev->vm_manager.funcs->unbind(rdev, vm); | 525 | rdev->vm_manager.funcs->unbind(rdev, vm); |
@@ -335,39 +534,42 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, | |||
335 | } | 534 | } |
336 | } | 535 | } |
337 | 536 | ||
537 | /** | ||
538 | * radeon_vm_manager_fini - tear down the vm manager | ||
539 | * | ||
540 | * @rdev: radeon_device pointer | ||
541 | * | ||
542 | * Tear down the VM manager (cayman+). | ||
543 | */ | ||
338 | void radeon_vm_manager_fini(struct radeon_device *rdev) | 544 | void radeon_vm_manager_fini(struct radeon_device *rdev) |
339 | { | 545 | { |
340 | if (rdev->vm_manager.sa_manager.bo == NULL) | ||
341 | return; | ||
342 | radeon_vm_manager_suspend(rdev); | ||
343 | rdev->vm_manager.funcs->fini(rdev); | ||
344 | radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager); | ||
345 | rdev->vm_manager.enabled = false; | ||
346 | } | ||
347 | |||
348 | int radeon_vm_manager_start(struct radeon_device *rdev) | ||
349 | { | ||
350 | if (rdev->vm_manager.sa_manager.bo == NULL) { | ||
351 | return -EINVAL; | ||
352 | } | ||
353 | return radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); | ||
354 | } | ||
355 | |||
356 | int radeon_vm_manager_suspend(struct radeon_device *rdev) | ||
357 | { | ||
358 | struct radeon_vm *vm, *tmp; | 546 | struct radeon_vm *vm, *tmp; |
359 | 547 | ||
360 | radeon_mutex_lock(&rdev->cs_mutex); | 548 | if (!rdev->vm_manager.enabled) |
549 | return; | ||
550 | |||
551 | mutex_lock(&rdev->vm_manager.lock); | ||
361 | /* unbind all active vm */ | 552 | /* unbind all active vm */ |
362 | list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { | 553 | list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { |
363 | radeon_vm_unbind_locked(rdev, vm); | 554 | radeon_vm_unbind_locked(rdev, vm); |
364 | } | 555 | } |
365 | rdev->vm_manager.funcs->fini(rdev); | 556 | rdev->vm_manager.funcs->fini(rdev); |
366 | radeon_mutex_unlock(&rdev->cs_mutex); | 557 | mutex_unlock(&rdev->vm_manager.lock); |
367 | return radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); | 558 | |
559 | radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); | ||
560 | radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager); | ||
561 | rdev->vm_manager.enabled = false; | ||
368 | } | 562 | } |
369 | 563 | ||
370 | /* cs mutex must be lock */ | 564 | /* global mutex must be locked */ |
565 | /** | ||
566 | * radeon_vm_unbind - locked version of unbind | ||
567 | * | ||
568 | * @rdev: radeon_device pointer | ||
569 | * @vm: vm to unbind | ||
570 | * | ||
571 | * Locked version that wraps radeon_vm_unbind_locked (cayman+). | ||
572 | */ | ||
371 | void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) | 573 | void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) |
372 | { | 574 | { |
373 | mutex_lock(&vm->mutex); | 575 | mutex_lock(&vm->mutex); |
@@ -375,7 +577,19 @@ void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) | |||
375 | mutex_unlock(&vm->mutex); | 577 | mutex_unlock(&vm->mutex); |
376 | } | 578 | } |
377 | 579 | ||
378 | /* cs mutex must be lock & vm mutex must be lock */ | 580 | /* global and local mutex must be locked */ |
581 | /** | ||
582 | * radeon_vm_bind - bind a page table to a VMID | ||
583 | * | ||
584 | * @rdev: radeon_device pointer | ||
585 | * @vm: vm to bind | ||
586 | * | ||
587 | * Bind the requested vm (cayman+). | ||
588 | * Suballocate memory for the page table, allocate a VMID | ||
589 | * and bind the page table to it, and finally start to populate | ||
590 | * the page table. | ||
591 | * Returns 0 for success, error for failure. | ||
592 | */ | ||
379 | int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) | 593 | int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) |
380 | { | 594 | { |
381 | struct radeon_vm *vm_evict; | 595 | struct radeon_vm *vm_evict; |
@@ -438,6 +652,20 @@ retry_id: | |||
438 | } | 652 | } |
439 | 653 | ||
440 | /* object have to be reserved */ | 654 | /* object have to be reserved */ |
655 | /** | ||
656 | * radeon_vm_bo_add - add a bo to a specific vm | ||
657 | * | ||
658 | * @rdev: radeon_device pointer | ||
659 | * @vm: requested vm | ||
660 | * @bo: radeon buffer object | ||
661 | * @offset: requested offset of the buffer in the VM address space | ||
662 | * @flags: attributes of pages (read/write/valid/etc.) | ||
663 | * | ||
664 | * Add @bo into the requested vm (cayman+). | ||
665 | * Add @bo to the list of bos associated with the vm and validate | ||
666 | * the offset requested within the vm address space. | ||
667 | * Returns 0 for success, error for failure. | ||
668 | */ | ||
441 | int radeon_vm_bo_add(struct radeon_device *rdev, | 669 | int radeon_vm_bo_add(struct radeon_device *rdev, |
442 | struct radeon_vm *vm, | 670 | struct radeon_vm *vm, |
443 | struct radeon_bo *bo, | 671 | struct radeon_bo *bo, |
@@ -479,7 +707,7 @@ int radeon_vm_bo_add(struct radeon_device *rdev, | |||
479 | if (last_pfn > vm->last_pfn) { | 707 | if (last_pfn > vm->last_pfn) { |
480 | /* release mutex and lock in right order */ | 708 | /* release mutex and lock in right order */ |
481 | mutex_unlock(&vm->mutex); | 709 | mutex_unlock(&vm->mutex); |
482 | radeon_mutex_lock(&rdev->cs_mutex); | 710 | mutex_lock(&rdev->vm_manager.lock); |
483 | mutex_lock(&vm->mutex); | 711 | mutex_lock(&vm->mutex); |
484 | /* and check again */ | 712 | /* and check again */ |
485 | if (last_pfn > vm->last_pfn) { | 713 | if (last_pfn > vm->last_pfn) { |
@@ -488,7 +716,7 @@ int radeon_vm_bo_add(struct radeon_device *rdev, | |||
488 | radeon_vm_unbind_locked(rdev, vm); | 716 | radeon_vm_unbind_locked(rdev, vm); |
489 | vm->last_pfn = (last_pfn + align) & ~align; | 717 | vm->last_pfn = (last_pfn + align) & ~align; |
490 | } | 718 | } |
491 | radeon_mutex_unlock(&rdev->cs_mutex); | 719 | mutex_unlock(&rdev->vm_manager.lock); |
492 | } | 720 | } |
493 | head = &vm->va; | 721 | head = &vm->va; |
494 | last_offset = 0; | 722 | last_offset = 0; |
@@ -515,6 +743,17 @@ int radeon_vm_bo_add(struct radeon_device *rdev, | |||
515 | return 0; | 743 | return 0; |
516 | } | 744 | } |
517 | 745 | ||
746 | /** | ||
747 | * radeon_vm_get_addr - get the physical address of the page | ||
748 | * | ||
749 | * @rdev: radeon_device pointer | ||
750 | * @mem: ttm mem | ||
751 | * @pfn: pfn | ||
752 | * | ||
753 | * Look up the physical address of the page that the pte resolves | ||
754 | * to (cayman+). | ||
755 | * Returns the physical address of the page. | ||
756 | */ | ||
518 | static u64 radeon_vm_get_addr(struct radeon_device *rdev, | 757 | static u64 radeon_vm_get_addr(struct radeon_device *rdev, |
519 | struct ttm_mem_reg *mem, | 758 | struct ttm_mem_reg *mem, |
520 | unsigned pfn) | 759 | unsigned pfn) |
@@ -543,7 +782,18 @@ static u64 radeon_vm_get_addr(struct radeon_device *rdev, | |||
543 | return addr; | 782 | return addr; |
544 | } | 783 | } |
545 | 784 | ||
546 | /* object have to be reserved & cs mutex took & vm mutex took */ | 785 | /* object have to be reserved & global and local mutex must be locked */ |
786 | /** | ||
787 | * radeon_vm_bo_update_pte - map a bo into the vm page table | ||
788 | * | ||
789 | * @rdev: radeon_device pointer | ||
790 | * @vm: requested vm | ||
791 | * @bo: radeon buffer object | ||
792 | * @mem: ttm mem | ||
793 | * | ||
794 | * Fill in the page table entries for @bo (cayman+). | ||
795 | * Returns 0 for success, -EINVAL for failure. | ||
796 | */ | ||
547 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, | 797 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, |
548 | struct radeon_vm *vm, | 798 | struct radeon_vm *vm, |
549 | struct radeon_bo *bo, | 799 | struct radeon_bo *bo, |
@@ -592,6 +842,18 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
592 | } | 842 | } |
593 | 843 | ||
594 | /* object have to be reserved */ | 844 | /* object have to be reserved */ |
845 | /** | ||
846 | * radeon_vm_bo_rmv - remove a bo to a specific vm | ||
847 | * | ||
848 | * @rdev: radeon_device pointer | ||
849 | * @vm: requested vm | ||
850 | * @bo: radeon buffer object | ||
851 | * | ||
852 | * Remove @bo from the requested vm (cayman+). | ||
853 | * Remove @bo from the list of bos associated with the vm and | ||
854 | * remove the ptes for @bo in the page table. | ||
855 | * Returns 0 for success. | ||
856 | */ | ||
595 | int radeon_vm_bo_rmv(struct radeon_device *rdev, | 857 | int radeon_vm_bo_rmv(struct radeon_device *rdev, |
596 | struct radeon_vm *vm, | 858 | struct radeon_vm *vm, |
597 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
@@ -602,10 +864,10 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
602 | if (bo_va == NULL) | 864 | if (bo_va == NULL) |
603 | return 0; | 865 | return 0; |
604 | 866 | ||
605 | radeon_mutex_lock(&rdev->cs_mutex); | 867 | mutex_lock(&rdev->vm_manager.lock); |
606 | mutex_lock(&vm->mutex); | 868 | mutex_lock(&vm->mutex); |
607 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
608 | radeon_mutex_unlock(&rdev->cs_mutex); | 870 | mutex_unlock(&rdev->vm_manager.lock); |
609 | list_del(&bo_va->vm_list); | 871 | list_del(&bo_va->vm_list); |
610 | mutex_unlock(&vm->mutex); | 872 | mutex_unlock(&vm->mutex); |
611 | list_del(&bo_va->bo_list); | 873 | list_del(&bo_va->bo_list); |
@@ -614,6 +876,15 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
614 | return 0; | 876 | return 0; |
615 | } | 877 | } |
616 | 878 | ||
879 | /** | ||
880 | * radeon_vm_bo_invalidate - mark the bo as invalid | ||
881 | * | ||
882 | * @rdev: radeon_device pointer | ||
883 | * @vm: requested vm | ||
884 | * @bo: radeon buffer object | ||
885 | * | ||
886 | * Mark @bo as invalid (cayman+). | ||
887 | */ | ||
617 | void radeon_vm_bo_invalidate(struct radeon_device *rdev, | 888 | void radeon_vm_bo_invalidate(struct radeon_device *rdev, |
618 | struct radeon_bo *bo) | 889 | struct radeon_bo *bo) |
619 | { | 890 | { |
@@ -625,6 +896,17 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, | |||
625 | } | 896 | } |
626 | } | 897 | } |
627 | 898 | ||
899 | /** | ||
900 | * radeon_vm_init - initialize a vm instance | ||
901 | * | ||
902 | * @rdev: radeon_device pointer | ||
903 | * @vm: requested vm | ||
904 | * | ||
905 | * Init @vm (cayman+). | ||
906 | * Map the IB pool and any other shared objects into the VM | ||
907 | * by default as it's used by all VMs. | ||
908 | * Returns 0 for success, error for failure. | ||
909 | */ | ||
628 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | 910 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) |
629 | { | 911 | { |
630 | int r; | 912 | int r; |
@@ -651,15 +933,24 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
651 | return r; | 933 | return r; |
652 | } | 934 | } |
653 | 935 | ||
936 | /** | ||
937 | * radeon_vm_init - tear down a vm instance | ||
938 | * | ||
939 | * @rdev: radeon_device pointer | ||
940 | * @vm: requested vm | ||
941 | * | ||
942 | * Tear down @vm (cayman+). | ||
943 | * Unbind the VM and remove all bos from the vm bo list | ||
944 | */ | ||
654 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | 945 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) |
655 | { | 946 | { |
656 | struct radeon_bo_va *bo_va, *tmp; | 947 | struct radeon_bo_va *bo_va, *tmp; |
657 | int r; | 948 | int r; |
658 | 949 | ||
659 | radeon_mutex_lock(&rdev->cs_mutex); | 950 | mutex_lock(&rdev->vm_manager.lock); |
660 | mutex_lock(&vm->mutex); | 951 | mutex_lock(&vm->mutex); |
661 | radeon_vm_unbind_locked(rdev, vm); | 952 | radeon_vm_unbind_locked(rdev, vm); |
662 | radeon_mutex_unlock(&rdev->cs_mutex); | 953 | mutex_unlock(&rdev->vm_manager.lock); |
663 | 954 | ||
664 | /* remove all bo */ | 955 | /* remove all bo */ |
665 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 21ec9f5653ce..84d045245739 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -159,11 +159,9 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
159 | static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) | 159 | static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) |
160 | { | 160 | { |
161 | if (r == -EDEADLK) { | 161 | if (r == -EDEADLK) { |
162 | radeon_mutex_lock(&rdev->cs_mutex); | ||
163 | r = radeon_gpu_reset(rdev); | 162 | r = radeon_gpu_reset(rdev); |
164 | if (!r) | 163 | if (!r) |
165 | r = -EAGAIN; | 164 | r = -EAGAIN; |
166 | radeon_mutex_unlock(&rdev->cs_mutex); | ||
167 | } | 165 | } |
168 | return r; | 166 | return r; |
169 | } | 167 | } |
@@ -217,12 +215,14 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
217 | uint32_t handle; | 215 | uint32_t handle; |
218 | int r; | 216 | int r; |
219 | 217 | ||
218 | down_read(&rdev->exclusive_lock); | ||
220 | /* create a gem object to contain this object in */ | 219 | /* create a gem object to contain this object in */ |
221 | args->size = roundup(args->size, PAGE_SIZE); | 220 | args->size = roundup(args->size, PAGE_SIZE); |
222 | r = radeon_gem_object_create(rdev, args->size, args->alignment, | 221 | r = radeon_gem_object_create(rdev, args->size, args->alignment, |
223 | args->initial_domain, false, | 222 | args->initial_domain, false, |
224 | false, &gobj); | 223 | false, &gobj); |
225 | if (r) { | 224 | if (r) { |
225 | up_read(&rdev->exclusive_lock); | ||
226 | r = radeon_gem_handle_lockup(rdev, r); | 226 | r = radeon_gem_handle_lockup(rdev, r); |
227 | return r; | 227 | return r; |
228 | } | 228 | } |
@@ -230,10 +230,12 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
230 | /* drop reference from allocate - handle holds it now */ | 230 | /* drop reference from allocate - handle holds it now */ |
231 | drm_gem_object_unreference_unlocked(gobj); | 231 | drm_gem_object_unreference_unlocked(gobj); |
232 | if (r) { | 232 | if (r) { |
233 | up_read(&rdev->exclusive_lock); | ||
233 | r = radeon_gem_handle_lockup(rdev, r); | 234 | r = radeon_gem_handle_lockup(rdev, r); |
234 | return r; | 235 | return r; |
235 | } | 236 | } |
236 | args->handle = handle; | 237 | args->handle = handle; |
238 | up_read(&rdev->exclusive_lock); | ||
237 | return 0; | 239 | return 0; |
238 | } | 240 | } |
239 | 241 | ||
@@ -242,6 +244,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
242 | { | 244 | { |
243 | /* transition the BO to a domain - | 245 | /* transition the BO to a domain - |
244 | * just validate the BO into a certain domain */ | 246 | * just validate the BO into a certain domain */ |
247 | struct radeon_device *rdev = dev->dev_private; | ||
245 | struct drm_radeon_gem_set_domain *args = data; | 248 | struct drm_radeon_gem_set_domain *args = data; |
246 | struct drm_gem_object *gobj; | 249 | struct drm_gem_object *gobj; |
247 | struct radeon_bo *robj; | 250 | struct radeon_bo *robj; |
@@ -249,10 +252,12 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
249 | 252 | ||
250 | /* for now if someone requests domain CPU - | 253 | /* for now if someone requests domain CPU - |
251 | * just make sure the buffer is finished with */ | 254 | * just make sure the buffer is finished with */ |
255 | down_read(&rdev->exclusive_lock); | ||
252 | 256 | ||
253 | /* just do a BO wait for now */ | 257 | /* just do a BO wait for now */ |
254 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 258 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
255 | if (gobj == NULL) { | 259 | if (gobj == NULL) { |
260 | up_read(&rdev->exclusive_lock); | ||
256 | return -ENOENT; | 261 | return -ENOENT; |
257 | } | 262 | } |
258 | robj = gem_to_radeon_bo(gobj); | 263 | robj = gem_to_radeon_bo(gobj); |
@@ -260,6 +265,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
260 | r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); | 265 | r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); |
261 | 266 | ||
262 | drm_gem_object_unreference_unlocked(gobj); | 267 | drm_gem_object_unreference_unlocked(gobj); |
268 | up_read(&rdev->exclusive_lock); | ||
263 | r = radeon_gem_handle_lockup(robj->rdev, r); | 269 | r = radeon_gem_handle_lockup(robj->rdev, r); |
264 | return r; | 270 | return r; |
265 | } | 271 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 5df58d1aba06..afaa1727abd2 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -32,6 +32,17 @@ | |||
32 | #include "radeon.h" | 32 | #include "radeon.h" |
33 | #include "atom.h" | 33 | #include "atom.h" |
34 | 34 | ||
35 | #define RADEON_WAIT_IDLE_TIMEOUT 200 | ||
36 | |||
37 | /** | ||
38 | * radeon_driver_irq_handler_kms - irq handler for KMS | ||
39 | * | ||
40 | * @DRM_IRQ_ARGS: args | ||
41 | * | ||
42 | * This is the irq handler for the radeon KMS driver (all asics). | ||
43 | * radeon_irq_process is a macro that points to the per-asic | ||
44 | * irq handler callback. | ||
45 | */ | ||
35 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | 46 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) |
36 | { | 47 | { |
37 | struct drm_device *dev = (struct drm_device *) arg; | 48 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -43,6 +54,17 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | |||
43 | /* | 54 | /* |
44 | * Handle hotplug events outside the interrupt handler proper. | 55 | * Handle hotplug events outside the interrupt handler proper. |
45 | */ | 56 | */ |
57 | /** | ||
58 | * radeon_hotplug_work_func - display hotplug work handler | ||
59 | * | ||
60 | * @work: work struct | ||
61 | * | ||
62 | * This is the hot plug event work handler (all asics). | ||
63 | * The work gets scheduled from the irq handler if there | ||
64 | * was a hot plug interrupt. It walks the connector table | ||
65 | * and calls the hotplug handler for each one, then sends | ||
66 | * a drm hotplug event to alert userspace. | ||
67 | */ | ||
46 | static void radeon_hotplug_work_func(struct work_struct *work) | 68 | static void radeon_hotplug_work_func(struct work_struct *work) |
47 | { | 69 | { |
48 | struct radeon_device *rdev = container_of(work, struct radeon_device, | 70 | struct radeon_device *rdev = container_of(work, struct radeon_device, |
@@ -59,61 +81,94 @@ static void radeon_hotplug_work_func(struct work_struct *work) | |||
59 | drm_helper_hpd_irq_event(dev); | 81 | drm_helper_hpd_irq_event(dev); |
60 | } | 82 | } |
61 | 83 | ||
84 | /** | ||
85 | * radeon_driver_irq_preinstall_kms - drm irq preinstall callback | ||
86 | * | ||
87 | * @dev: drm dev pointer | ||
88 | * | ||
89 | * Gets the hw ready to enable irqs (all asics). | ||
90 | * This function disables all interrupt sources on the GPU. | ||
91 | */ | ||
62 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | 92 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) |
63 | { | 93 | { |
64 | struct radeon_device *rdev = dev->dev_private; | 94 | struct radeon_device *rdev = dev->dev_private; |
95 | unsigned long irqflags; | ||
65 | unsigned i; | 96 | unsigned i; |
66 | 97 | ||
98 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
67 | /* Disable *all* interrupts */ | 99 | /* Disable *all* interrupts */ |
68 | for (i = 0; i < RADEON_NUM_RINGS; i++) | 100 | for (i = 0; i < RADEON_NUM_RINGS; i++) |
69 | rdev->irq.sw_int[i] = false; | 101 | atomic_set(&rdev->irq.ring_int[i], 0); |
70 | rdev->irq.gui_idle = false; | 102 | rdev->irq.gui_idle = false; |
71 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) | 103 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
72 | rdev->irq.hpd[i] = false; | 104 | rdev->irq.hpd[i] = false; |
73 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | 105 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
74 | rdev->irq.crtc_vblank_int[i] = false; | 106 | rdev->irq.crtc_vblank_int[i] = false; |
75 | rdev->irq.pflip[i] = false; | 107 | atomic_set(&rdev->irq.pflip[i], 0); |
76 | rdev->irq.afmt[i] = false; | 108 | rdev->irq.afmt[i] = false; |
77 | } | 109 | } |
78 | radeon_irq_set(rdev); | 110 | radeon_irq_set(rdev); |
111 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
79 | /* Clear bits */ | 112 | /* Clear bits */ |
80 | radeon_irq_process(rdev); | 113 | radeon_irq_process(rdev); |
81 | } | 114 | } |
82 | 115 | ||
116 | /** | ||
117 | * radeon_driver_irq_postinstall_kms - drm irq preinstall callback | ||
118 | * | ||
119 | * @dev: drm dev pointer | ||
120 | * | ||
121 | * Handles stuff to be done after enabling irqs (all asics). | ||
122 | * Returns 0 on success. | ||
123 | */ | ||
83 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev) | 124 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev) |
84 | { | 125 | { |
85 | struct radeon_device *rdev = dev->dev_private; | ||
86 | unsigned i; | ||
87 | |||
88 | dev->max_vblank_count = 0x001fffff; | 126 | dev->max_vblank_count = 0x001fffff; |
89 | for (i = 0; i < RADEON_NUM_RINGS; i++) | ||
90 | rdev->irq.sw_int[i] = true; | ||
91 | radeon_irq_set(rdev); | ||
92 | return 0; | 127 | return 0; |
93 | } | 128 | } |
94 | 129 | ||
130 | /** | ||
131 | * radeon_driver_irq_uninstall_kms - drm irq uninstall callback | ||
132 | * | ||
133 | * @dev: drm dev pointer | ||
134 | * | ||
135 | * This function disables all interrupt sources on the GPU (all asics). | ||
136 | */ | ||
95 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | 137 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev) |
96 | { | 138 | { |
97 | struct radeon_device *rdev = dev->dev_private; | 139 | struct radeon_device *rdev = dev->dev_private; |
140 | unsigned long irqflags; | ||
98 | unsigned i; | 141 | unsigned i; |
99 | 142 | ||
100 | if (rdev == NULL) { | 143 | if (rdev == NULL) { |
101 | return; | 144 | return; |
102 | } | 145 | } |
146 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
103 | /* Disable *all* interrupts */ | 147 | /* Disable *all* interrupts */ |
104 | for (i = 0; i < RADEON_NUM_RINGS; i++) | 148 | for (i = 0; i < RADEON_NUM_RINGS; i++) |
105 | rdev->irq.sw_int[i] = false; | 149 | atomic_set(&rdev->irq.ring_int[i], 0); |
106 | rdev->irq.gui_idle = false; | 150 | rdev->irq.gui_idle = false; |
107 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) | 151 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
108 | rdev->irq.hpd[i] = false; | 152 | rdev->irq.hpd[i] = false; |
109 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | 153 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
110 | rdev->irq.crtc_vblank_int[i] = false; | 154 | rdev->irq.crtc_vblank_int[i] = false; |
111 | rdev->irq.pflip[i] = false; | 155 | atomic_set(&rdev->irq.pflip[i], 0); |
112 | rdev->irq.afmt[i] = false; | 156 | rdev->irq.afmt[i] = false; |
113 | } | 157 | } |
114 | radeon_irq_set(rdev); | 158 | radeon_irq_set(rdev); |
159 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
115 | } | 160 | } |
116 | 161 | ||
162 | /** | ||
163 | * radeon_msi_ok - asic specific msi checks | ||
164 | * | ||
165 | * @rdev: radeon device pointer | ||
166 | * | ||
167 | * Handles asic specific MSI checks to determine if | ||
168 | * MSIs should be enabled on a particular chip (all asics). | ||
169 | * Returns true if MSIs should be enabled, false if MSIs | ||
170 | * should not be enabled. | ||
171 | */ | ||
117 | static bool radeon_msi_ok(struct radeon_device *rdev) | 172 | static bool radeon_msi_ok(struct radeon_device *rdev) |
118 | { | 173 | { |
119 | /* RV370/RV380 was first asic with MSI support */ | 174 | /* RV370/RV380 was first asic with MSI support */ |
@@ -166,17 +221,22 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
166 | return true; | 221 | return true; |
167 | } | 222 | } |
168 | 223 | ||
224 | /** | ||
225 | * radeon_irq_kms_init - init driver interrupt info | ||
226 | * | ||
227 | * @rdev: radeon device pointer | ||
228 | * | ||
229 | * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics). | ||
230 | * Returns 0 for success, error for failure. | ||
231 | */ | ||
169 | int radeon_irq_kms_init(struct radeon_device *rdev) | 232 | int radeon_irq_kms_init(struct radeon_device *rdev) |
170 | { | 233 | { |
171 | int i; | ||
172 | int r = 0; | 234 | int r = 0; |
173 | 235 | ||
174 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | 236 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
175 | INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); | 237 | INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); |
176 | 238 | ||
177 | spin_lock_init(&rdev->irq.sw_lock); | 239 | spin_lock_init(&rdev->irq.lock); |
178 | for (i = 0; i < rdev->num_crtc; i++) | ||
179 | spin_lock_init(&rdev->irq.pflip_lock[i]); | ||
180 | r = drm_vblank_init(rdev->ddev, rdev->num_crtc); | 240 | r = drm_vblank_init(rdev->ddev, rdev->num_crtc); |
181 | if (r) { | 241 | if (r) { |
182 | return r; | 242 | return r; |
@@ -201,6 +261,13 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
201 | return 0; | 261 | return 0; |
202 | } | 262 | } |
203 | 263 | ||
264 | /** | ||
265 | * radeon_irq_kms_fini - tear down driver interrrupt info | ||
266 | * | ||
267 | * @rdev: radeon device pointer | ||
268 | * | ||
269 | * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). | ||
270 | */ | ||
204 | void radeon_irq_kms_fini(struct radeon_device *rdev) | 271 | void radeon_irq_kms_fini(struct radeon_device *rdev) |
205 | { | 272 | { |
206 | drm_vblank_cleanup(rdev->ddev); | 273 | drm_vblank_cleanup(rdev->ddev); |
@@ -213,31 +280,63 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) | |||
213 | flush_work_sync(&rdev->hotplug_work); | 280 | flush_work_sync(&rdev->hotplug_work); |
214 | } | 281 | } |
215 | 282 | ||
283 | /** | ||
284 | * radeon_irq_kms_sw_irq_get - enable software interrupt | ||
285 | * | ||
286 | * @rdev: radeon device pointer | ||
287 | * @ring: ring whose interrupt you want to enable | ||
288 | * | ||
289 | * Enables the software interrupt for a specific ring (all asics). | ||
290 | * The software interrupt is generally used to signal a fence on | ||
291 | * a particular ring. | ||
292 | */ | ||
216 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring) | 293 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring) |
217 | { | 294 | { |
218 | unsigned long irqflags; | 295 | unsigned long irqflags; |
219 | 296 | ||
220 | spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); | 297 | if (!rdev->ddev->irq_enabled) |
221 | if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount[ring] == 1)) { | 298 | return; |
222 | rdev->irq.sw_int[ring] = true; | 299 | |
300 | if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) { | ||
301 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
223 | radeon_irq_set(rdev); | 302 | radeon_irq_set(rdev); |
303 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
224 | } | 304 | } |
225 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); | ||
226 | } | 305 | } |
227 | 306 | ||
307 | /** | ||
308 | * radeon_irq_kms_sw_irq_put - disable software interrupt | ||
309 | * | ||
310 | * @rdev: radeon device pointer | ||
311 | * @ring: ring whose interrupt you want to disable | ||
312 | * | ||
313 | * Disables the software interrupt for a specific ring (all asics). | ||
314 | * The software interrupt is generally used to signal a fence on | ||
315 | * a particular ring. | ||
316 | */ | ||
228 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) | 317 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) |
229 | { | 318 | { |
230 | unsigned long irqflags; | 319 | unsigned long irqflags; |
231 | 320 | ||
232 | spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); | 321 | if (!rdev->ddev->irq_enabled) |
233 | BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount[ring] <= 0); | 322 | return; |
234 | if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount[ring] == 0)) { | 323 | |
235 | rdev->irq.sw_int[ring] = false; | 324 | if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) { |
325 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
236 | radeon_irq_set(rdev); | 326 | radeon_irq_set(rdev); |
327 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
237 | } | 328 | } |
238 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); | ||
239 | } | 329 | } |
240 | 330 | ||
331 | /** | ||
332 | * radeon_irq_kms_pflip_irq_get - enable pageflip interrupt | ||
333 | * | ||
334 | * @rdev: radeon device pointer | ||
335 | * @crtc: crtc whose interrupt you want to enable | ||
336 | * | ||
337 | * Enables the pageflip interrupt for a specific crtc (all asics). | ||
338 | * For pageflips we use the vblank interrupt source. | ||
339 | */ | ||
241 | void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) | 340 | void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) |
242 | { | 341 | { |
243 | unsigned long irqflags; | 342 | unsigned long irqflags; |
@@ -245,14 +344,25 @@ void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) | |||
245 | if (crtc < 0 || crtc >= rdev->num_crtc) | 344 | if (crtc < 0 || crtc >= rdev->num_crtc) |
246 | return; | 345 | return; |
247 | 346 | ||
248 | spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); | 347 | if (!rdev->ddev->irq_enabled) |
249 | if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == 1)) { | 348 | return; |
250 | rdev->irq.pflip[crtc] = true; | 349 | |
350 | if (atomic_inc_return(&rdev->irq.pflip[crtc]) == 1) { | ||
351 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
251 | radeon_irq_set(rdev); | 352 | radeon_irq_set(rdev); |
353 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
252 | } | 354 | } |
253 | spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); | ||
254 | } | 355 | } |
255 | 356 | ||
357 | /** | ||
358 | * radeon_irq_kms_pflip_irq_put - disable pageflip interrupt | ||
359 | * | ||
360 | * @rdev: radeon device pointer | ||
361 | * @crtc: crtc whose interrupt you want to disable | ||
362 | * | ||
363 | * Disables the pageflip interrupt for a specific crtc (all asics). | ||
364 | * For pageflips we use the vblank interrupt source. | ||
365 | */ | ||
256 | void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) | 366 | void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) |
257 | { | 367 | { |
258 | unsigned long irqflags; | 368 | unsigned long irqflags; |
@@ -260,12 +370,121 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) | |||
260 | if (crtc < 0 || crtc >= rdev->num_crtc) | 370 | if (crtc < 0 || crtc >= rdev->num_crtc) |
261 | return; | 371 | return; |
262 | 372 | ||
263 | spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); | 373 | if (!rdev->ddev->irq_enabled) |
264 | BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); | 374 | return; |
265 | if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { | 375 | |
266 | rdev->irq.pflip[crtc] = false; | 376 | if (atomic_dec_and_test(&rdev->irq.pflip[crtc])) { |
377 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
267 | radeon_irq_set(rdev); | 378 | radeon_irq_set(rdev); |
379 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
268 | } | 380 | } |
269 | spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); | ||
270 | } | 381 | } |
271 | 382 | ||
383 | /** | ||
384 | * radeon_irq_kms_enable_afmt - enable audio format change interrupt | ||
385 | * | ||
386 | * @rdev: radeon device pointer | ||
387 | * @block: afmt block whose interrupt you want to enable | ||
388 | * | ||
389 | * Enables the afmt change interrupt for a specific afmt block (all asics). | ||
390 | */ | ||
391 | void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block) | ||
392 | { | ||
393 | unsigned long irqflags; | ||
394 | |||
395 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
396 | rdev->irq.afmt[block] = true; | ||
397 | radeon_irq_set(rdev); | ||
398 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
399 | |||
400 | } | ||
401 | |||
402 | /** | ||
403 | * radeon_irq_kms_disable_afmt - disable audio format change interrupt | ||
404 | * | ||
405 | * @rdev: radeon device pointer | ||
406 | * @block: afmt block whose interrupt you want to disable | ||
407 | * | ||
408 | * Disables the afmt change interrupt for a specific afmt block (all asics). | ||
409 | */ | ||
410 | void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block) | ||
411 | { | ||
412 | unsigned long irqflags; | ||
413 | |||
414 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
415 | rdev->irq.afmt[block] = false; | ||
416 | radeon_irq_set(rdev); | ||
417 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * radeon_irq_kms_enable_hpd - enable hotplug detect interrupt | ||
422 | * | ||
423 | * @rdev: radeon device pointer | ||
424 | * @hpd_mask: mask of hpd pins you want to enable. | ||
425 | * | ||
426 | * Enables the hotplug detect interrupt for a specific hpd pin (all asics). | ||
427 | */ | ||
428 | void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) | ||
429 | { | ||
430 | unsigned long irqflags; | ||
431 | int i; | ||
432 | |||
433 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
434 | for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) | ||
435 | rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); | ||
436 | radeon_irq_set(rdev); | ||
437 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
438 | } | ||
439 | |||
440 | /** | ||
441 | * radeon_irq_kms_disable_hpd - disable hotplug detect interrupt | ||
442 | * | ||
443 | * @rdev: radeon device pointer | ||
444 | * @hpd_mask: mask of hpd pins you want to disable. | ||
445 | * | ||
446 | * Disables the hotplug detect interrupt for a specific hpd pin (all asics). | ||
447 | */ | ||
448 | void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) | ||
449 | { | ||
450 | unsigned long irqflags; | ||
451 | int i; | ||
452 | |||
453 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
454 | for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) | ||
455 | rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); | ||
456 | radeon_irq_set(rdev); | ||
457 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * radeon_irq_kms_wait_gui_idle - waits for drawing engine to be idle | ||
462 | * | ||
463 | * @rdev: radeon device pointer | ||
464 | * | ||
465 | * Enabled the GUI idle interrupt and waits for it to fire (r6xx+). | ||
466 | * This is currently used to make sure the 3D engine is idle for power | ||
467 | * management, but should be replaces with proper fence waits. | ||
468 | * GUI idle interrupts don't work very well on pre-r6xx hw and it also | ||
469 | * does not take into account other aspects of the chip that may be busy. | ||
470 | * DO NOT USE GOING FORWARD. | ||
471 | */ | ||
472 | int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev) | ||
473 | { | ||
474 | unsigned long irqflags; | ||
475 | int r; | ||
476 | |||
477 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
478 | rdev->irq.gui_idle = true; | ||
479 | radeon_irq_set(rdev); | ||
480 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
481 | |||
482 | r = wait_event_timeout(rdev->irq.idle_queue, radeon_gui_idle(rdev), | ||
483 | msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); | ||
484 | |||
485 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
486 | rdev->irq.gui_idle = false; | ||
487 | radeon_irq_set(rdev); | ||
488 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
489 | return r; | ||
490 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 5c58d7d90cb2..1d73f16b5d97 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -33,6 +33,17 @@ | |||
33 | #include <linux/vga_switcheroo.h> | 33 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | 35 | ||
36 | /** | ||
37 | * radeon_driver_unload_kms - Main unload function for KMS. | ||
38 | * | ||
39 | * @dev: drm dev pointer | ||
40 | * | ||
41 | * This is the main unload function for KMS (all asics). | ||
42 | * It calls radeon_modeset_fini() to tear down the | ||
43 | * displays, and radeon_device_fini() to tear down | ||
44 | * the rest of the device (CP, writeback, etc.). | ||
45 | * Returns 0 on success. | ||
46 | */ | ||
36 | int radeon_driver_unload_kms(struct drm_device *dev) | 47 | int radeon_driver_unload_kms(struct drm_device *dev) |
37 | { | 48 | { |
38 | struct radeon_device *rdev = dev->dev_private; | 49 | struct radeon_device *rdev = dev->dev_private; |
@@ -46,6 +57,19 @@ int radeon_driver_unload_kms(struct drm_device *dev) | |||
46 | return 0; | 57 | return 0; |
47 | } | 58 | } |
48 | 59 | ||
60 | /** | ||
61 | * radeon_driver_load_kms - Main load function for KMS. | ||
62 | * | ||
63 | * @dev: drm dev pointer | ||
64 | * @flags: device flags | ||
65 | * | ||
66 | * This is the main load function for KMS (all asics). | ||
67 | * It calls radeon_device_init() to set up the non-display | ||
68 | * parts of the chip (asic init, CP, writeback, etc.), and | ||
69 | * radeon_modeset_init() to set up the display parts | ||
70 | * (crtcs, encoders, hotplug detect, etc.). | ||
71 | * Returns 0 on success, error on failure. | ||
72 | */ | ||
49 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | 73 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) |
50 | { | 74 | { |
51 | struct radeon_device *rdev; | 75 | struct radeon_device *rdev; |
@@ -96,6 +120,16 @@ out: | |||
96 | return r; | 120 | return r; |
97 | } | 121 | } |
98 | 122 | ||
123 | /** | ||
124 | * radeon_set_filp_rights - Set filp right. | ||
125 | * | ||
126 | * @dev: drm dev pointer | ||
127 | * @owner: drm file | ||
128 | * @applier: drm file | ||
129 | * @value: value | ||
130 | * | ||
131 | * Sets the filp rights for the device (all asics). | ||
132 | */ | ||
99 | static void radeon_set_filp_rights(struct drm_device *dev, | 133 | static void radeon_set_filp_rights(struct drm_device *dev, |
100 | struct drm_file **owner, | 134 | struct drm_file **owner, |
101 | struct drm_file *applier, | 135 | struct drm_file *applier, |
@@ -118,6 +152,18 @@ static void radeon_set_filp_rights(struct drm_device *dev, | |||
118 | /* | 152 | /* |
119 | * Userspace get information ioctl | 153 | * Userspace get information ioctl |
120 | */ | 154 | */ |
155 | /** | ||
156 | * radeon_info_ioctl - answer a device specific request. | ||
157 | * | ||
158 | * @rdev: radeon device pointer | ||
159 | * @data: request object | ||
160 | * @filp: drm filp | ||
161 | * | ||
162 | * This function is used to pass device specific parameters to the userspace | ||
163 | * drivers. Examples include: pci device id, pipeline parms, tiling params, | ||
164 | * etc. (all asics). | ||
165 | * Returns 0 on success, -EINVAL on failure. | ||
166 | */ | ||
121 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 167 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
122 | { | 168 | { |
123 | struct radeon_device *rdev = dev->dev_private; | 169 | struct radeon_device *rdev = dev->dev_private; |
@@ -301,16 +347,40 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
301 | /* | 347 | /* |
302 | * Outdated mess for old drm with Xorg being in charge (void function now). | 348 | * Outdated mess for old drm with Xorg being in charge (void function now). |
303 | */ | 349 | */ |
350 | /** | ||
351 | * radeon_driver_firstopen_kms - drm callback for first open | ||
352 | * | ||
353 | * @dev: drm dev pointer | ||
354 | * | ||
355 | * Nothing to be done for KMS (all asics). | ||
356 | * Returns 0 on success. | ||
357 | */ | ||
304 | int radeon_driver_firstopen_kms(struct drm_device *dev) | 358 | int radeon_driver_firstopen_kms(struct drm_device *dev) |
305 | { | 359 | { |
306 | return 0; | 360 | return 0; |
307 | } | 361 | } |
308 | 362 | ||
363 | /** | ||
364 | * radeon_driver_firstopen_kms - drm callback for last close | ||
365 | * | ||
366 | * @dev: drm dev pointer | ||
367 | * | ||
368 | * Switch vga switcheroo state after last close (all asics). | ||
369 | */ | ||
309 | void radeon_driver_lastclose_kms(struct drm_device *dev) | 370 | void radeon_driver_lastclose_kms(struct drm_device *dev) |
310 | { | 371 | { |
311 | vga_switcheroo_process_delayed_switch(); | 372 | vga_switcheroo_process_delayed_switch(); |
312 | } | 373 | } |
313 | 374 | ||
375 | /** | ||
376 | * radeon_driver_open_kms - drm callback for open | ||
377 | * | ||
378 | * @dev: drm dev pointer | ||
379 | * @file_priv: drm file | ||
380 | * | ||
381 | * On device open, init vm on cayman+ (all asics). | ||
382 | * Returns 0 on success, error on failure. | ||
383 | */ | ||
314 | int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | 384 | int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) |
315 | { | 385 | { |
316 | struct radeon_device *rdev = dev->dev_private; | 386 | struct radeon_device *rdev = dev->dev_private; |
@@ -339,6 +409,14 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
339 | return 0; | 409 | return 0; |
340 | } | 410 | } |
341 | 411 | ||
412 | /** | ||
413 | * radeon_driver_postclose_kms - drm callback for post close | ||
414 | * | ||
415 | * @dev: drm dev pointer | ||
416 | * @file_priv: drm file | ||
417 | * | ||
418 | * On device post close, tear down vm on cayman+ (all asics). | ||
419 | */ | ||
342 | void radeon_driver_postclose_kms(struct drm_device *dev, | 420 | void radeon_driver_postclose_kms(struct drm_device *dev, |
343 | struct drm_file *file_priv) | 421 | struct drm_file *file_priv) |
344 | { | 422 | { |
@@ -354,6 +432,15 @@ void radeon_driver_postclose_kms(struct drm_device *dev, | |||
354 | } | 432 | } |
355 | } | 433 | } |
356 | 434 | ||
435 | /** | ||
436 | * radeon_driver_preclose_kms - drm callback for pre close | ||
437 | * | ||
438 | * @dev: drm dev pointer | ||
439 | * @file_priv: drm file | ||
440 | * | ||
441 | * On device pre close, tear down hyperz and cmask filps on r1xx-r5xx | ||
442 | * (all asics). | ||
443 | */ | ||
357 | void radeon_driver_preclose_kms(struct drm_device *dev, | 444 | void radeon_driver_preclose_kms(struct drm_device *dev, |
358 | struct drm_file *file_priv) | 445 | struct drm_file *file_priv) |
359 | { | 446 | { |
@@ -367,6 +454,15 @@ void radeon_driver_preclose_kms(struct drm_device *dev, | |||
367 | /* | 454 | /* |
368 | * VBlank related functions. | 455 | * VBlank related functions. |
369 | */ | 456 | */ |
457 | /** | ||
458 | * radeon_get_vblank_counter_kms - get frame count | ||
459 | * | ||
460 | * @dev: drm dev pointer | ||
461 | * @crtc: crtc to get the frame count from | ||
462 | * | ||
463 | * Gets the frame count on the requested crtc (all asics). | ||
464 | * Returns frame count on success, -EINVAL on failure. | ||
465 | */ | ||
370 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | 466 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) |
371 | { | 467 | { |
372 | struct radeon_device *rdev = dev->dev_private; | 468 | struct radeon_device *rdev = dev->dev_private; |
@@ -379,34 +475,70 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | |||
379 | return radeon_get_vblank_counter(rdev, crtc); | 475 | return radeon_get_vblank_counter(rdev, crtc); |
380 | } | 476 | } |
381 | 477 | ||
478 | /** | ||
479 | * radeon_enable_vblank_kms - enable vblank interrupt | ||
480 | * | ||
481 | * @dev: drm dev pointer | ||
482 | * @crtc: crtc to enable vblank interrupt for | ||
483 | * | ||
484 | * Enable the interrupt on the requested crtc (all asics). | ||
485 | * Returns 0 on success, -EINVAL on failure. | ||
486 | */ | ||
382 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) | 487 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) |
383 | { | 488 | { |
384 | struct radeon_device *rdev = dev->dev_private; | 489 | struct radeon_device *rdev = dev->dev_private; |
490 | unsigned long irqflags; | ||
491 | int r; | ||
385 | 492 | ||
386 | if (crtc < 0 || crtc >= rdev->num_crtc) { | 493 | if (crtc < 0 || crtc >= rdev->num_crtc) { |
387 | DRM_ERROR("Invalid crtc %d\n", crtc); | 494 | DRM_ERROR("Invalid crtc %d\n", crtc); |
388 | return -EINVAL; | 495 | return -EINVAL; |
389 | } | 496 | } |
390 | 497 | ||
498 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
391 | rdev->irq.crtc_vblank_int[crtc] = true; | 499 | rdev->irq.crtc_vblank_int[crtc] = true; |
392 | 500 | r = radeon_irq_set(rdev); | |
393 | return radeon_irq_set(rdev); | 501 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
502 | return r; | ||
394 | } | 503 | } |
395 | 504 | ||
505 | /** | ||
506 | * radeon_disable_vblank_kms - disable vblank interrupt | ||
507 | * | ||
508 | * @dev: drm dev pointer | ||
509 | * @crtc: crtc to disable vblank interrupt for | ||
510 | * | ||
511 | * Disable the interrupt on the requested crtc (all asics). | ||
512 | */ | ||
396 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | 513 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) |
397 | { | 514 | { |
398 | struct radeon_device *rdev = dev->dev_private; | 515 | struct radeon_device *rdev = dev->dev_private; |
516 | unsigned long irqflags; | ||
399 | 517 | ||
400 | if (crtc < 0 || crtc >= rdev->num_crtc) { | 518 | if (crtc < 0 || crtc >= rdev->num_crtc) { |
401 | DRM_ERROR("Invalid crtc %d\n", crtc); | 519 | DRM_ERROR("Invalid crtc %d\n", crtc); |
402 | return; | 520 | return; |
403 | } | 521 | } |
404 | 522 | ||
523 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
405 | rdev->irq.crtc_vblank_int[crtc] = false; | 524 | rdev->irq.crtc_vblank_int[crtc] = false; |
406 | |||
407 | radeon_irq_set(rdev); | 525 | radeon_irq_set(rdev); |
526 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
408 | } | 527 | } |
409 | 528 | ||
529 | /** | ||
530 | * radeon_get_vblank_timestamp_kms - get vblank timestamp | ||
531 | * | ||
532 | * @dev: drm dev pointer | ||
533 | * @crtc: crtc to get the timestamp for | ||
534 | * @max_error: max error | ||
535 | * @vblank_time: time value | ||
536 | * @flags: flags passed to the driver | ||
537 | * | ||
538 | * Gets the timestamp on the requested crtc based on the | ||
539 | * scanout position. (all asics). | ||
540 | * Returns postive status flags on success, negative error on failure. | ||
541 | */ | ||
410 | int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, | 542 | int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, |
411 | int *max_error, | 543 | int *max_error, |
412 | struct timeval *vblank_time, | 544 | struct timeval *vblank_time, |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 210317c7045e..d5fd615897ec 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -990,7 +990,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
990 | } | 990 | } |
991 | 991 | ||
992 | static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, | 992 | static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, |
993 | struct drm_display_mode *mode, | 993 | const struct drm_display_mode *mode, |
994 | struct drm_display_mode *adjusted_mode) | 994 | struct drm_display_mode *adjusted_mode) |
995 | { | 995 | { |
996 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 996 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index a0c82229e8f0..670e9910f869 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -244,7 +244,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
244 | } | 244 | } |
245 | 245 | ||
246 | static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, | 246 | static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, |
247 | struct drm_display_mode *mode, | 247 | const struct drm_display_mode *mode, |
248 | struct drm_display_mode *adjusted_mode) | 248 | struct drm_display_mode *adjusted_mode) |
249 | { | 249 | { |
250 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 250 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 5b10ffd7bb2f..f380d59c5763 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -488,7 +488,7 @@ extern void radeon_connector_hotplug(struct drm_connector *connector); | |||
488 | extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, | 488 | extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, |
489 | struct drm_display_mode *mode); | 489 | struct drm_display_mode *mode); |
490 | extern void radeon_dp_set_link_config(struct drm_connector *connector, | 490 | extern void radeon_dp_set_link_config(struct drm_connector *connector, |
491 | struct drm_display_mode *mode); | 491 | const struct drm_display_mode *mode); |
492 | extern void radeon_dp_link_train(struct drm_encoder *encoder, | 492 | extern void radeon_dp_link_train(struct drm_encoder *encoder, |
493 | struct drm_connector *connector); | 493 | struct drm_connector *connector); |
494 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | 494 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); |
@@ -678,7 +678,7 @@ void radeon_enc_destroy(struct drm_encoder *encoder); | |||
678 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); | 678 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); |
679 | void radeon_combios_asic_init(struct drm_device *dev); | 679 | void radeon_combios_asic_init(struct drm_device *dev); |
680 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 680 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
681 | struct drm_display_mode *mode, | 681 | const struct drm_display_mode *mode, |
682 | struct drm_display_mode *adjusted_mode); | 682 | struct drm_display_mode *adjusted_mode); |
683 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 683 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
684 | struct drm_display_mode *adjusted_mode); | 684 | struct drm_display_mode *adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 830f1a7b486f..1f1a4c803c1d 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -115,9 +115,7 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
115 | 115 | ||
116 | size = ALIGN(size, PAGE_SIZE); | 116 | size = ALIGN(size, PAGE_SIZE); |
117 | 117 | ||
118 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 118 | rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; |
119 | rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; | ||
120 | } | ||
121 | if (kernel) { | 119 | if (kernel) { |
122 | type = ttm_bo_type_kernel; | 120 | type = ttm_bo_type_kernel; |
123 | } else if (sg) { | 121 | } else if (sg) { |
@@ -138,7 +136,6 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
138 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, | 136 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, |
139 | sizeof(struct radeon_bo)); | 137 | sizeof(struct radeon_bo)); |
140 | 138 | ||
141 | retry: | ||
142 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 139 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
143 | if (bo == NULL) | 140 | if (bo == NULL) |
144 | return -ENOMEM; | 141 | return -ENOMEM; |
@@ -152,13 +149,15 @@ retry: | |||
152 | bo->surface_reg = -1; | 149 | bo->surface_reg = -1; |
153 | INIT_LIST_HEAD(&bo->list); | 150 | INIT_LIST_HEAD(&bo->list); |
154 | INIT_LIST_HEAD(&bo->va); | 151 | INIT_LIST_HEAD(&bo->va); |
152 | |||
153 | retry: | ||
155 | radeon_ttm_placement_from_domain(bo, domain); | 154 | radeon_ttm_placement_from_domain(bo, domain); |
156 | /* Kernel allocation are uninterruptible */ | 155 | /* Kernel allocation are uninterruptible */ |
157 | mutex_lock(&rdev->vram_mutex); | 156 | down_read(&rdev->pm.mclk_lock); |
158 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, | 157 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, |
159 | &bo->placement, page_align, 0, !kernel, NULL, | 158 | &bo->placement, page_align, 0, !kernel, NULL, |
160 | acc_size, sg, &radeon_ttm_bo_destroy); | 159 | acc_size, sg, &radeon_ttm_bo_destroy); |
161 | mutex_unlock(&rdev->vram_mutex); | 160 | up_read(&rdev->pm.mclk_lock); |
162 | if (unlikely(r != 0)) { | 161 | if (unlikely(r != 0)) { |
163 | if (r != -ERESTARTSYS) { | 162 | if (r != -ERESTARTSYS) { |
164 | if (domain == RADEON_GEM_DOMAIN_VRAM) { | 163 | if (domain == RADEON_GEM_DOMAIN_VRAM) { |
@@ -219,9 +218,9 @@ void radeon_bo_unref(struct radeon_bo **bo) | |||
219 | return; | 218 | return; |
220 | rdev = (*bo)->rdev; | 219 | rdev = (*bo)->rdev; |
221 | tbo = &((*bo)->tbo); | 220 | tbo = &((*bo)->tbo); |
222 | mutex_lock(&rdev->vram_mutex); | 221 | down_read(&rdev->pm.mclk_lock); |
223 | ttm_bo_unref(&tbo); | 222 | ttm_bo_unref(&tbo); |
224 | mutex_unlock(&rdev->vram_mutex); | 223 | up_read(&rdev->pm.mclk_lock); |
225 | if (tbo == NULL) | 224 | if (tbo == NULL) |
226 | *bo = NULL; | 225 | *bo = NULL; |
227 | } | 226 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 5b37e283ec38..7ae606600107 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #define RADEON_IDLE_LOOP_MS 100 | 34 | #define RADEON_IDLE_LOOP_MS 100 |
35 | #define RADEON_RECLOCK_DELAY_MS 200 | 35 | #define RADEON_RECLOCK_DELAY_MS 200 |
36 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 | 36 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 |
37 | #define RADEON_WAIT_IDLE_TIMEOUT 200 | ||
38 | 37 | ||
39 | static const char *radeon_pm_state_type_name[5] = { | 38 | static const char *radeon_pm_state_type_name[5] = { |
40 | "Default", | 39 | "Default", |
@@ -251,21 +250,14 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
251 | return; | 250 | return; |
252 | 251 | ||
253 | mutex_lock(&rdev->ddev->struct_mutex); | 252 | mutex_lock(&rdev->ddev->struct_mutex); |
254 | mutex_lock(&rdev->vram_mutex); | 253 | down_write(&rdev->pm.mclk_lock); |
255 | mutex_lock(&rdev->ring_lock); | 254 | mutex_lock(&rdev->ring_lock); |
256 | 255 | ||
257 | /* gui idle int has issues on older chips it seems */ | 256 | /* gui idle int has issues on older chips it seems */ |
258 | if (rdev->family >= CHIP_R600) { | 257 | if (rdev->family >= CHIP_R600) { |
259 | if (rdev->irq.installed) { | 258 | if (rdev->irq.installed) { |
260 | /* wait for GPU idle */ | 259 | /* wait for GPU to become idle */ |
261 | rdev->pm.gui_idle = false; | 260 | radeon_irq_kms_wait_gui_idle(rdev); |
262 | rdev->irq.gui_idle = true; | ||
263 | radeon_irq_set(rdev); | ||
264 | wait_event_interruptible_timeout( | ||
265 | rdev->irq.idle_queue, rdev->pm.gui_idle, | ||
266 | msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); | ||
267 | rdev->irq.gui_idle = false; | ||
268 | radeon_irq_set(rdev); | ||
269 | } | 261 | } |
270 | } else { | 262 | } else { |
271 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 263 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
@@ -303,7 +295,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
303 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; | 295 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
304 | 296 | ||
305 | mutex_unlock(&rdev->ring_lock); | 297 | mutex_unlock(&rdev->ring_lock); |
306 | mutex_unlock(&rdev->vram_mutex); | 298 | up_write(&rdev->pm.mclk_lock); |
307 | mutex_unlock(&rdev->ddev->struct_mutex); | 299 | mutex_unlock(&rdev->ddev->struct_mutex); |
308 | } | 300 | } |
309 | 301 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 983658c91358..ec79b3750430 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -35,47 +35,97 @@ | |||
35 | #include "atom.h" | 35 | #include "atom.h" |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * IB. | 38 | * IB |
39 | * IBs (Indirect Buffers) and areas of GPU accessible memory where | ||
40 | * commands are stored. You can put a pointer to the IB in the | ||
41 | * command ring and the hw will fetch the commands from the IB | ||
42 | * and execute them. Generally userspace acceleration drivers | ||
43 | * produce command buffers which are send to the kernel and | ||
44 | * put in IBs for execution by the requested ring. | ||
39 | */ | 45 | */ |
40 | int radeon_debugfs_sa_init(struct radeon_device *rdev); | 46 | int radeon_debugfs_sa_init(struct radeon_device *rdev); |
41 | 47 | ||
48 | /** | ||
49 | * radeon_ib_get - request an IB (Indirect Buffer) | ||
50 | * | ||
51 | * @rdev: radeon_device pointer | ||
52 | * @ring: ring index the IB is associated with | ||
53 | * @ib: IB object returned | ||
54 | * @size: requested IB size | ||
55 | * | ||
56 | * Request an IB (all asics). IBs are allocated using the | ||
57 | * suballocator. | ||
58 | * Returns 0 on success, error on failure. | ||
59 | */ | ||
42 | int radeon_ib_get(struct radeon_device *rdev, int ring, | 60 | int radeon_ib_get(struct radeon_device *rdev, int ring, |
43 | struct radeon_ib *ib, unsigned size) | 61 | struct radeon_ib *ib, unsigned size) |
44 | { | 62 | { |
45 | int r; | 63 | int i, r; |
46 | 64 | ||
47 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true); | 65 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true); |
48 | if (r) { | 66 | if (r) { |
49 | dev_err(rdev->dev, "failed to get a new IB (%d)\n", r); | 67 | dev_err(rdev->dev, "failed to get a new IB (%d)\n", r); |
50 | return r; | 68 | return r; |
51 | } | 69 | } |
52 | r = radeon_fence_create(rdev, &ib->fence, ring); | 70 | |
71 | r = radeon_semaphore_create(rdev, &ib->semaphore); | ||
53 | if (r) { | 72 | if (r) { |
54 | dev_err(rdev->dev, "failed to create fence for new IB (%d)\n", r); | ||
55 | radeon_sa_bo_free(rdev, &ib->sa_bo, NULL); | ||
56 | return r; | 73 | return r; |
57 | } | 74 | } |
58 | 75 | ||
76 | ib->ring = ring; | ||
77 | ib->fence = NULL; | ||
59 | ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo); | 78 | ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo); |
60 | ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); | 79 | ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); |
61 | ib->vm_id = 0; | 80 | ib->vm_id = 0; |
62 | ib->is_const_ib = false; | 81 | ib->is_const_ib = false; |
63 | ib->semaphore = NULL; | 82 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
83 | ib->sync_to[i] = NULL; | ||
64 | 84 | ||
65 | return 0; | 85 | return 0; |
66 | } | 86 | } |
67 | 87 | ||
88 | /** | ||
89 | * radeon_ib_free - free an IB (Indirect Buffer) | ||
90 | * | ||
91 | * @rdev: radeon_device pointer | ||
92 | * @ib: IB object to free | ||
93 | * | ||
94 | * Free an IB (all asics). | ||
95 | */ | ||
68 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) | 96 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) |
69 | { | 97 | { |
70 | radeon_semaphore_free(rdev, ib->semaphore, ib->fence); | 98 | radeon_semaphore_free(rdev, &ib->semaphore, ib->fence); |
71 | radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); | 99 | radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); |
72 | radeon_fence_unref(&ib->fence); | 100 | radeon_fence_unref(&ib->fence); |
73 | } | 101 | } |
74 | 102 | ||
75 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | 103 | /** |
104 | * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring | ||
105 | * | ||
106 | * @rdev: radeon_device pointer | ||
107 | * @ib: IB object to schedule | ||
108 | * @const_ib: Const IB to schedule (SI only) | ||
109 | * | ||
110 | * Schedule an IB on the associated ring (all asics). | ||
111 | * Returns 0 on success, error on failure. | ||
112 | * | ||
113 | * On SI, there are two parallel engines fed from the primary ring, | ||
114 | * the CE (Constant Engine) and the DE (Drawing Engine). Since | ||
115 | * resource descriptors have moved to memory, the CE allows you to | ||
116 | * prime the caches while the DE is updating register state so that | ||
117 | * the resource descriptors will be already in cache when the draw is | ||
118 | * processed. To accomplish this, the userspace driver submits two | ||
119 | * IBs, one for the CE and one for the DE. If there is a CE IB (called | ||
120 | * a CONST_IB), it will be put on the ring prior to the DE IB. Prior | ||
121 | * to SI there was just a DE IB. | ||
122 | */ | ||
123 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | ||
124 | struct radeon_ib *const_ib) | ||
76 | { | 125 | { |
77 | struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; | 126 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
78 | int r = 0; | 127 | bool need_sync = false; |
128 | int i, r = 0; | ||
79 | 129 | ||
80 | if (!ib->length_dw || !ring->ready) { | 130 | if (!ib->length_dw || !ring->ready) { |
81 | /* TODO: Nothings in the ib we should report. */ | 131 | /* TODO: Nothings in the ib we should report. */ |
@@ -84,17 +134,51 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
84 | } | 134 | } |
85 | 135 | ||
86 | /* 64 dwords should be enough for fence too */ | 136 | /* 64 dwords should be enough for fence too */ |
87 | r = radeon_ring_lock(rdev, ring, 64); | 137 | r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8); |
88 | if (r) { | 138 | if (r) { |
89 | dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); | 139 | dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); |
90 | return r; | 140 | return r; |
91 | } | 141 | } |
92 | radeon_ring_ib_execute(rdev, ib->fence->ring, ib); | 142 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
93 | radeon_fence_emit(rdev, ib->fence); | 143 | struct radeon_fence *fence = ib->sync_to[i]; |
144 | if (radeon_fence_need_sync(fence, ib->ring)) { | ||
145 | need_sync = true; | ||
146 | radeon_semaphore_sync_rings(rdev, ib->semaphore, | ||
147 | fence->ring, ib->ring); | ||
148 | radeon_fence_note_sync(fence, ib->ring); | ||
149 | } | ||
150 | } | ||
151 | /* immediately free semaphore when we don't need to sync */ | ||
152 | if (!need_sync) { | ||
153 | radeon_semaphore_free(rdev, &ib->semaphore, NULL); | ||
154 | } | ||
155 | if (const_ib) { | ||
156 | radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); | ||
157 | radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); | ||
158 | } | ||
159 | radeon_ring_ib_execute(rdev, ib->ring, ib); | ||
160 | r = radeon_fence_emit(rdev, &ib->fence, ib->ring); | ||
161 | if (r) { | ||
162 | dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r); | ||
163 | radeon_ring_unlock_undo(rdev, ring); | ||
164 | return r; | ||
165 | } | ||
166 | if (const_ib) { | ||
167 | const_ib->fence = radeon_fence_ref(ib->fence); | ||
168 | } | ||
94 | radeon_ring_unlock_commit(rdev, ring); | 169 | radeon_ring_unlock_commit(rdev, ring); |
95 | return 0; | 170 | return 0; |
96 | } | 171 | } |
97 | 172 | ||
173 | /** | ||
174 | * radeon_ib_pool_init - Init the IB (Indirect Buffer) pool | ||
175 | * | ||
176 | * @rdev: radeon_device pointer | ||
177 | * | ||
178 | * Initialize the suballocator to manage a pool of memory | ||
179 | * for use as IBs (all asics). | ||
180 | * Returns 0 on success, error on failure. | ||
181 | */ | ||
98 | int radeon_ib_pool_init(struct radeon_device *rdev) | 182 | int radeon_ib_pool_init(struct radeon_device *rdev) |
99 | { | 183 | { |
100 | int r; | 184 | int r; |
@@ -108,6 +192,12 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
108 | if (r) { | 192 | if (r) { |
109 | return r; | 193 | return r; |
110 | } | 194 | } |
195 | |||
196 | r = radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo); | ||
197 | if (r) { | ||
198 | return r; | ||
199 | } | ||
200 | |||
111 | rdev->ib_pool_ready = true; | 201 | rdev->ib_pool_ready = true; |
112 | if (radeon_debugfs_sa_init(rdev)) { | 202 | if (radeon_debugfs_sa_init(rdev)) { |
113 | dev_err(rdev->dev, "failed to register debugfs file for SA\n"); | 203 | dev_err(rdev->dev, "failed to register debugfs file for SA\n"); |
@@ -115,24 +205,33 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
115 | return 0; | 205 | return 0; |
116 | } | 206 | } |
117 | 207 | ||
208 | /** | ||
209 | * radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool | ||
210 | * | ||
211 | * @rdev: radeon_device pointer | ||
212 | * | ||
213 | * Tear down the suballocator managing the pool of memory | ||
214 | * for use as IBs (all asics). | ||
215 | */ | ||
118 | void radeon_ib_pool_fini(struct radeon_device *rdev) | 216 | void radeon_ib_pool_fini(struct radeon_device *rdev) |
119 | { | 217 | { |
120 | if (rdev->ib_pool_ready) { | 218 | if (rdev->ib_pool_ready) { |
219 | radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo); | ||
121 | radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo); | 220 | radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo); |
122 | rdev->ib_pool_ready = false; | 221 | rdev->ib_pool_ready = false; |
123 | } | 222 | } |
124 | } | 223 | } |
125 | 224 | ||
126 | int radeon_ib_pool_start(struct radeon_device *rdev) | 225 | /** |
127 | { | 226 | * radeon_ib_ring_tests - test IBs on the rings |
128 | return radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo); | 227 | * |
129 | } | 228 | * @rdev: radeon_device pointer |
130 | 229 | * | |
131 | int radeon_ib_pool_suspend(struct radeon_device *rdev) | 230 | * Test an IB (Indirect Buffer) on each ring. |
132 | { | 231 | * If the test fails, disable the ring. |
133 | return radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo); | 232 | * Returns 0 on success, error if the primary GFX ring |
134 | } | 233 | * IB test fails. |
135 | 234 | */ | |
136 | int radeon_ib_ring_tests(struct radeon_device *rdev) | 235 | int radeon_ib_ring_tests(struct radeon_device *rdev) |
137 | { | 236 | { |
138 | unsigned i; | 237 | unsigned i; |
@@ -164,10 +263,28 @@ int radeon_ib_ring_tests(struct radeon_device *rdev) | |||
164 | } | 263 | } |
165 | 264 | ||
166 | /* | 265 | /* |
167 | * Ring. | 266 | * Rings |
267 | * Most engines on the GPU are fed via ring buffers. Ring | ||
268 | * buffers are areas of GPU accessible memory that the host | ||
269 | * writes commands into and the GPU reads commands out of. | ||
270 | * There is a rptr (read pointer) that determines where the | ||
271 | * GPU is currently reading, and a wptr (write pointer) | ||
272 | * which determines where the host has written. When the | ||
273 | * pointers are equal, the ring is idle. When the host | ||
274 | * writes commands to the ring buffer, it increments the | ||
275 | * wptr. The GPU then starts fetching commands and executes | ||
276 | * them until the pointers are equal again. | ||
168 | */ | 277 | */ |
169 | int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring); | 278 | int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring); |
170 | 279 | ||
280 | /** | ||
281 | * radeon_ring_write - write a value to the ring | ||
282 | * | ||
283 | * @ring: radeon_ring structure holding ring information | ||
284 | * @v: dword (dw) value to write | ||
285 | * | ||
286 | * Write a value to the requested ring buffer (all asics). | ||
287 | */ | ||
171 | void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | 288 | void radeon_ring_write(struct radeon_ring *ring, uint32_t v) |
172 | { | 289 | { |
173 | #if DRM_DEBUG_CODE | 290 | #if DRM_DEBUG_CODE |
@@ -181,21 +298,37 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | |||
181 | ring->ring_free_dw--; | 298 | ring->ring_free_dw--; |
182 | } | 299 | } |
183 | 300 | ||
184 | int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) | 301 | /** |
302 | * radeon_ring_supports_scratch_reg - check if the ring supports | ||
303 | * writing to scratch registers | ||
304 | * | ||
305 | * @rdev: radeon_device pointer | ||
306 | * @ring: radeon_ring structure holding ring information | ||
307 | * | ||
308 | * Check if a specific ring supports writing to scratch registers (all asics). | ||
309 | * Returns true if the ring supports writing to scratch regs, false if not. | ||
310 | */ | ||
311 | bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, | ||
312 | struct radeon_ring *ring) | ||
185 | { | 313 | { |
186 | /* r1xx-r5xx only has CP ring */ | 314 | switch (ring->idx) { |
187 | if (rdev->family < CHIP_R600) | 315 | case RADEON_RING_TYPE_GFX_INDEX: |
188 | return RADEON_RING_TYPE_GFX_INDEX; | 316 | case CAYMAN_RING_TYPE_CP1_INDEX: |
189 | 317 | case CAYMAN_RING_TYPE_CP2_INDEX: | |
190 | if (rdev->family >= CHIP_CAYMAN) { | 318 | return true; |
191 | if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]) | 319 | default: |
192 | return CAYMAN_RING_TYPE_CP1_INDEX; | 320 | return false; |
193 | else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]) | ||
194 | return CAYMAN_RING_TYPE_CP2_INDEX; | ||
195 | } | 321 | } |
196 | return RADEON_RING_TYPE_GFX_INDEX; | ||
197 | } | 322 | } |
198 | 323 | ||
324 | /** | ||
325 | * radeon_ring_free_size - update the free size | ||
326 | * | ||
327 | * @rdev: radeon_device pointer | ||
328 | * @ring: radeon_ring structure holding ring information | ||
329 | * | ||
330 | * Update the free dw slots in the ring buffer (all asics). | ||
331 | */ | ||
199 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) | 332 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) |
200 | { | 333 | { |
201 | u32 rptr; | 334 | u32 rptr; |
@@ -214,7 +347,16 @@ void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) | |||
214 | } | 347 | } |
215 | } | 348 | } |
216 | 349 | ||
217 | 350 | /** | |
351 | * radeon_ring_alloc - allocate space on the ring buffer | ||
352 | * | ||
353 | * @rdev: radeon_device pointer | ||
354 | * @ring: radeon_ring structure holding ring information | ||
355 | * @ndw: number of dwords to allocate in the ring buffer | ||
356 | * | ||
357 | * Allocate @ndw dwords in the ring buffer (all asics). | ||
358 | * Returns 0 on success, error on failure. | ||
359 | */ | ||
218 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) | 360 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) |
219 | { | 361 | { |
220 | int r; | 362 | int r; |
@@ -227,7 +369,7 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi | |||
227 | if (ndw < ring->ring_free_dw) { | 369 | if (ndw < ring->ring_free_dw) { |
228 | break; | 370 | break; |
229 | } | 371 | } |
230 | r = radeon_fence_wait_next_locked(rdev, radeon_ring_index(rdev, ring)); | 372 | r = radeon_fence_wait_next_locked(rdev, ring->idx); |
231 | if (r) | 373 | if (r) |
232 | return r; | 374 | return r; |
233 | } | 375 | } |
@@ -236,6 +378,17 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi | |||
236 | return 0; | 378 | return 0; |
237 | } | 379 | } |
238 | 380 | ||
381 | /** | ||
382 | * radeon_ring_lock - lock the ring and allocate space on it | ||
383 | * | ||
384 | * @rdev: radeon_device pointer | ||
385 | * @ring: radeon_ring structure holding ring information | ||
386 | * @ndw: number of dwords to allocate in the ring buffer | ||
387 | * | ||
388 | * Lock the ring and allocate @ndw dwords in the ring buffer | ||
389 | * (all asics). | ||
390 | * Returns 0 on success, error on failure. | ||
391 | */ | ||
239 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) | 392 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) |
240 | { | 393 | { |
241 | int r; | 394 | int r; |
@@ -249,15 +402,20 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
249 | return 0; | 402 | return 0; |
250 | } | 403 | } |
251 | 404 | ||
405 | /** | ||
406 | * radeon_ring_commit - tell the GPU to execute the new | ||
407 | * commands on the ring buffer | ||
408 | * | ||
409 | * @rdev: radeon_device pointer | ||
410 | * @ring: radeon_ring structure holding ring information | ||
411 | * | ||
412 | * Update the wptr (write pointer) to tell the GPU to | ||
413 | * execute new commands on the ring buffer (all asics). | ||
414 | */ | ||
252 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) | 415 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) |
253 | { | 416 | { |
254 | unsigned count_dw_pad; | ||
255 | unsigned i; | ||
256 | |||
257 | /* We pad to match fetch size */ | 417 | /* We pad to match fetch size */ |
258 | count_dw_pad = (ring->align_mask + 1) - | 418 | while (ring->wptr & ring->align_mask) { |
259 | (ring->wptr & ring->align_mask); | ||
260 | for (i = 0; i < count_dw_pad; i++) { | ||
261 | radeon_ring_write(ring, ring->nop); | 419 | radeon_ring_write(ring, ring->nop); |
262 | } | 420 | } |
263 | DRM_MEMORYBARRIER(); | 421 | DRM_MEMORYBARRIER(); |
@@ -265,23 +423,55 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) | |||
265 | (void)RREG32(ring->wptr_reg); | 423 | (void)RREG32(ring->wptr_reg); |
266 | } | 424 | } |
267 | 425 | ||
426 | /** | ||
427 | * radeon_ring_unlock_commit - tell the GPU to execute the new | ||
428 | * commands on the ring buffer and unlock it | ||
429 | * | ||
430 | * @rdev: radeon_device pointer | ||
431 | * @ring: radeon_ring structure holding ring information | ||
432 | * | ||
433 | * Call radeon_ring_commit() then unlock the ring (all asics). | ||
434 | */ | ||
268 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) | 435 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) |
269 | { | 436 | { |
270 | radeon_ring_commit(rdev, ring); | 437 | radeon_ring_commit(rdev, ring); |
271 | mutex_unlock(&rdev->ring_lock); | 438 | mutex_unlock(&rdev->ring_lock); |
272 | } | 439 | } |
273 | 440 | ||
441 | /** | ||
442 | * radeon_ring_undo - reset the wptr | ||
443 | * | ||
444 | * @ring: radeon_ring structure holding ring information | ||
445 | * | ||
446 | * Reset the driver's copy of the wtpr (all asics). | ||
447 | */ | ||
274 | void radeon_ring_undo(struct radeon_ring *ring) | 448 | void radeon_ring_undo(struct radeon_ring *ring) |
275 | { | 449 | { |
276 | ring->wptr = ring->wptr_old; | 450 | ring->wptr = ring->wptr_old; |
277 | } | 451 | } |
278 | 452 | ||
453 | /** | ||
454 | * radeon_ring_unlock_undo - reset the wptr and unlock the ring | ||
455 | * | ||
456 | * @ring: radeon_ring structure holding ring information | ||
457 | * | ||
458 | * Call radeon_ring_undo() then unlock the ring (all asics). | ||
459 | */ | ||
279 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) | 460 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) |
280 | { | 461 | { |
281 | radeon_ring_undo(ring); | 462 | radeon_ring_undo(ring); |
282 | mutex_unlock(&rdev->ring_lock); | 463 | mutex_unlock(&rdev->ring_lock); |
283 | } | 464 | } |
284 | 465 | ||
466 | /** | ||
467 | * radeon_ring_force_activity - add some nop packets to the ring | ||
468 | * | ||
469 | * @rdev: radeon_device pointer | ||
470 | * @ring: radeon_ring structure holding ring information | ||
471 | * | ||
472 | * Add some nop packets to the ring to force activity (all asics). | ||
473 | * Used for lockup detection to see if the rptr is advancing. | ||
474 | */ | ||
285 | void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring) | 475 | void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring) |
286 | { | 476 | { |
287 | int r; | 477 | int r; |
@@ -296,6 +486,13 @@ void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring * | |||
296 | } | 486 | } |
297 | } | 487 | } |
298 | 488 | ||
489 | /** | ||
490 | * radeon_ring_force_activity - update lockup variables | ||
491 | * | ||
492 | * @ring: radeon_ring structure holding ring information | ||
493 | * | ||
494 | * Update the last rptr value and timestamp (all asics). | ||
495 | */ | ||
299 | void radeon_ring_lockup_update(struct radeon_ring *ring) | 496 | void radeon_ring_lockup_update(struct radeon_ring *ring) |
300 | { | 497 | { |
301 | ring->last_rptr = ring->rptr; | 498 | ring->last_rptr = ring->rptr; |
@@ -349,6 +546,116 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *rin | |||
349 | return false; | 546 | return false; |
350 | } | 547 | } |
351 | 548 | ||
549 | /** | ||
550 | * radeon_ring_backup - Back up the content of a ring | ||
551 | * | ||
552 | * @rdev: radeon_device pointer | ||
553 | * @ring: the ring we want to back up | ||
554 | * | ||
555 | * Saves all unprocessed commits from a ring, returns the number of dwords saved. | ||
556 | */ | ||
557 | unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, | ||
558 | uint32_t **data) | ||
559 | { | ||
560 | unsigned size, ptr, i; | ||
561 | |||
562 | /* just in case lock the ring */ | ||
563 | mutex_lock(&rdev->ring_lock); | ||
564 | *data = NULL; | ||
565 | |||
566 | if (ring->ring_obj == NULL) { | ||
567 | mutex_unlock(&rdev->ring_lock); | ||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | /* it doesn't make sense to save anything if all fences are signaled */ | ||
572 | if (!radeon_fence_count_emitted(rdev, ring->idx)) { | ||
573 | mutex_unlock(&rdev->ring_lock); | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | /* calculate the number of dw on the ring */ | ||
578 | if (ring->rptr_save_reg) | ||
579 | ptr = RREG32(ring->rptr_save_reg); | ||
580 | else if (rdev->wb.enabled) | ||
581 | ptr = le32_to_cpu(*ring->next_rptr_cpu_addr); | ||
582 | else { | ||
583 | /* no way to read back the next rptr */ | ||
584 | mutex_unlock(&rdev->ring_lock); | ||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | size = ring->wptr + (ring->ring_size / 4); | ||
589 | size -= ptr; | ||
590 | size &= ring->ptr_mask; | ||
591 | if (size == 0) { | ||
592 | mutex_unlock(&rdev->ring_lock); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* and then save the content of the ring */ | ||
597 | *data = kmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); | ||
598 | if (!*data) { | ||
599 | mutex_unlock(&rdev->ring_lock); | ||
600 | return 0; | ||
601 | } | ||
602 | for (i = 0; i < size; ++i) { | ||
603 | (*data)[i] = ring->ring[ptr++]; | ||
604 | ptr &= ring->ptr_mask; | ||
605 | } | ||
606 | |||
607 | mutex_unlock(&rdev->ring_lock); | ||
608 | return size; | ||
609 | } | ||
610 | |||
611 | /** | ||
612 | * radeon_ring_restore - append saved commands to the ring again | ||
613 | * | ||
614 | * @rdev: radeon_device pointer | ||
615 | * @ring: ring to append commands to | ||
616 | * @size: number of dwords we want to write | ||
617 | * @data: saved commands | ||
618 | * | ||
619 | * Allocates space on the ring and restore the previously saved commands. | ||
620 | */ | ||
621 | int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, | ||
622 | unsigned size, uint32_t *data) | ||
623 | { | ||
624 | int i, r; | ||
625 | |||
626 | if (!size || !data) | ||
627 | return 0; | ||
628 | |||
629 | /* restore the saved ring content */ | ||
630 | r = radeon_ring_lock(rdev, ring, size); | ||
631 | if (r) | ||
632 | return r; | ||
633 | |||
634 | for (i = 0; i < size; ++i) { | ||
635 | radeon_ring_write(ring, data[i]); | ||
636 | } | ||
637 | |||
638 | radeon_ring_unlock_commit(rdev, ring); | ||
639 | kfree(data); | ||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | /** | ||
644 | * radeon_ring_init - init driver ring struct. | ||
645 | * | ||
646 | * @rdev: radeon_device pointer | ||
647 | * @ring: radeon_ring structure holding ring information | ||
648 | * @ring_size: size of the ring | ||
649 | * @rptr_offs: offset of the rptr writeback location in the WB buffer | ||
650 | * @rptr_reg: MMIO offset of the rptr register | ||
651 | * @wptr_reg: MMIO offset of the wptr register | ||
652 | * @ptr_reg_shift: bit offset of the rptr/wptr values | ||
653 | * @ptr_reg_mask: bit mask of the rptr/wptr values | ||
654 | * @nop: nop packet for this ring | ||
655 | * | ||
656 | * Initialize the driver information for the selected ring (all asics). | ||
657 | * Returns 0 on success, error on failure. | ||
658 | */ | ||
352 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, | 659 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, |
353 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, | 660 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, |
354 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) | 661 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) |
@@ -391,12 +698,25 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
391 | } | 698 | } |
392 | ring->ptr_mask = (ring->ring_size / 4) - 1; | 699 | ring->ptr_mask = (ring->ring_size / 4) - 1; |
393 | ring->ring_free_dw = ring->ring_size / 4; | 700 | ring->ring_free_dw = ring->ring_size / 4; |
701 | if (rdev->wb.enabled) { | ||
702 | u32 index = RADEON_WB_RING0_NEXT_RPTR + (ring->idx * 4); | ||
703 | ring->next_rptr_gpu_addr = rdev->wb.gpu_addr + index; | ||
704 | ring->next_rptr_cpu_addr = &rdev->wb.wb[index/4]; | ||
705 | } | ||
394 | if (radeon_debugfs_ring_init(rdev, ring)) { | 706 | if (radeon_debugfs_ring_init(rdev, ring)) { |
395 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 707 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
396 | } | 708 | } |
397 | return 0; | 709 | return 0; |
398 | } | 710 | } |
399 | 711 | ||
712 | /** | ||
713 | * radeon_ring_fini - tear down the driver ring struct. | ||
714 | * | ||
715 | * @rdev: radeon_device pointer | ||
716 | * @ring: radeon_ring structure holding ring information | ||
717 | * | ||
718 | * Tear down the driver information for the selected ring (all asics). | ||
719 | */ | ||
400 | void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) | 720 | void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) |
401 | { | 721 | { |
402 | int r; | 722 | int r; |
@@ -438,6 +758,10 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) | |||
438 | count = (ring->ring_size / 4) - ring->ring_free_dw; | 758 | count = (ring->ring_size / 4) - ring->ring_free_dw; |
439 | seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); | 759 | seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); |
440 | seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); | 760 | seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); |
761 | if (ring->rptr_save_reg) { | ||
762 | seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg, | ||
763 | RREG32(ring->rptr_save_reg)); | ||
764 | } | ||
441 | seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); | 765 | seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); |
442 | seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); | 766 | seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); |
443 | seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); | 767 | seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); |
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index 32059b745728..4e771240fdd0 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c | |||
@@ -54,7 +54,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev, | |||
54 | { | 54 | { |
55 | int i, r; | 55 | int i, r; |
56 | 56 | ||
57 | spin_lock_init(&sa_manager->lock); | 57 | init_waitqueue_head(&sa_manager->wq); |
58 | sa_manager->bo = NULL; | 58 | sa_manager->bo = NULL; |
59 | sa_manager->size = size; | 59 | sa_manager->size = size; |
60 | sa_manager->domain = domain; | 60 | sa_manager->domain = domain; |
@@ -211,6 +211,39 @@ static bool radeon_sa_bo_try_alloc(struct radeon_sa_manager *sa_manager, | |||
211 | return false; | 211 | return false; |
212 | } | 212 | } |
213 | 213 | ||
214 | /** | ||
215 | * radeon_sa_event - Check if we can stop waiting | ||
216 | * | ||
217 | * @sa_manager: pointer to the sa_manager | ||
218 | * @size: number of bytes we want to allocate | ||
219 | * @align: alignment we need to match | ||
220 | * | ||
221 | * Check if either there is a fence we can wait for or | ||
222 | * enough free memory to satisfy the allocation directly | ||
223 | */ | ||
224 | static bool radeon_sa_event(struct radeon_sa_manager *sa_manager, | ||
225 | unsigned size, unsigned align) | ||
226 | { | ||
227 | unsigned soffset, eoffset, wasted; | ||
228 | int i; | ||
229 | |||
230 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
231 | if (!list_empty(&sa_manager->flist[i])) { | ||
232 | return true; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | soffset = radeon_sa_bo_hole_soffset(sa_manager); | ||
237 | eoffset = radeon_sa_bo_hole_eoffset(sa_manager); | ||
238 | wasted = (align - (soffset % align)) % align; | ||
239 | |||
240 | if ((eoffset - soffset) >= (size + wasted)) { | ||
241 | return true; | ||
242 | } | ||
243 | |||
244 | return false; | ||
245 | } | ||
246 | |||
214 | static bool radeon_sa_bo_next_hole(struct radeon_sa_manager *sa_manager, | 247 | static bool radeon_sa_bo_next_hole(struct radeon_sa_manager *sa_manager, |
215 | struct radeon_fence **fences, | 248 | struct radeon_fence **fences, |
216 | unsigned *tries) | 249 | unsigned *tries) |
@@ -297,8 +330,8 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
297 | INIT_LIST_HEAD(&(*sa_bo)->olist); | 330 | INIT_LIST_HEAD(&(*sa_bo)->olist); |
298 | INIT_LIST_HEAD(&(*sa_bo)->flist); | 331 | INIT_LIST_HEAD(&(*sa_bo)->flist); |
299 | 332 | ||
300 | spin_lock(&sa_manager->lock); | 333 | spin_lock(&sa_manager->wq.lock); |
301 | do { | 334 | while(1) { |
302 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 335 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
303 | fences[i] = NULL; | 336 | fences[i] = NULL; |
304 | tries[i] = 0; | 337 | tries[i] = 0; |
@@ -309,30 +342,34 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
309 | 342 | ||
310 | if (radeon_sa_bo_try_alloc(sa_manager, *sa_bo, | 343 | if (radeon_sa_bo_try_alloc(sa_manager, *sa_bo, |
311 | size, align)) { | 344 | size, align)) { |
312 | spin_unlock(&sa_manager->lock); | 345 | spin_unlock(&sa_manager->wq.lock); |
313 | return 0; | 346 | return 0; |
314 | } | 347 | } |
315 | 348 | ||
316 | /* see if we can skip over some allocations */ | 349 | /* see if we can skip over some allocations */ |
317 | } while (radeon_sa_bo_next_hole(sa_manager, fences, tries)); | 350 | } while (radeon_sa_bo_next_hole(sa_manager, fences, tries)); |
318 | 351 | ||
319 | if (block) { | 352 | if (!block) { |
320 | spin_unlock(&sa_manager->lock); | 353 | break; |
321 | r = radeon_fence_wait_any(rdev, fences, false); | 354 | } |
322 | spin_lock(&sa_manager->lock); | 355 | |
323 | if (r) { | 356 | spin_unlock(&sa_manager->wq.lock); |
324 | /* if we have nothing to wait for we | 357 | r = radeon_fence_wait_any(rdev, fences, false); |
325 | are practically out of memory */ | 358 | spin_lock(&sa_manager->wq.lock); |
326 | if (r == -ENOENT) { | 359 | /* if we have nothing to wait for block */ |
327 | r = -ENOMEM; | 360 | if (r == -ENOENT) { |
328 | } | 361 | r = wait_event_interruptible_locked( |
329 | goto out_err; | 362 | sa_manager->wq, |
330 | } | 363 | radeon_sa_event(sa_manager, size, align) |
364 | ); | ||
365 | } | ||
366 | if (r) { | ||
367 | goto out_err; | ||
331 | } | 368 | } |
332 | } while (block); | 369 | }; |
333 | 370 | ||
334 | out_err: | 371 | out_err: |
335 | spin_unlock(&sa_manager->lock); | 372 | spin_unlock(&sa_manager->wq.lock); |
336 | kfree(*sa_bo); | 373 | kfree(*sa_bo); |
337 | *sa_bo = NULL; | 374 | *sa_bo = NULL; |
338 | return r; | 375 | return r; |
@@ -348,15 +385,16 @@ void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo, | |||
348 | } | 385 | } |
349 | 386 | ||
350 | sa_manager = (*sa_bo)->manager; | 387 | sa_manager = (*sa_bo)->manager; |
351 | spin_lock(&sa_manager->lock); | 388 | spin_lock(&sa_manager->wq.lock); |
352 | if (fence && fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { | 389 | if (fence && !radeon_fence_signaled(fence)) { |
353 | (*sa_bo)->fence = radeon_fence_ref(fence); | 390 | (*sa_bo)->fence = radeon_fence_ref(fence); |
354 | list_add_tail(&(*sa_bo)->flist, | 391 | list_add_tail(&(*sa_bo)->flist, |
355 | &sa_manager->flist[fence->ring]); | 392 | &sa_manager->flist[fence->ring]); |
356 | } else { | 393 | } else { |
357 | radeon_sa_bo_remove_locked(*sa_bo); | 394 | radeon_sa_bo_remove_locked(*sa_bo); |
358 | } | 395 | } |
359 | spin_unlock(&sa_manager->lock); | 396 | wake_up_all_locked(&sa_manager->wq); |
397 | spin_unlock(&sa_manager->wq.lock); | ||
360 | *sa_bo = NULL; | 398 | *sa_bo = NULL; |
361 | } | 399 | } |
362 | 400 | ||
@@ -366,7 +404,7 @@ void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, | |||
366 | { | 404 | { |
367 | struct radeon_sa_bo *i; | 405 | struct radeon_sa_bo *i; |
368 | 406 | ||
369 | spin_lock(&sa_manager->lock); | 407 | spin_lock(&sa_manager->wq.lock); |
370 | list_for_each_entry(i, &sa_manager->olist, olist) { | 408 | list_for_each_entry(i, &sa_manager->olist, olist) { |
371 | if (&i->olist == sa_manager->hole) { | 409 | if (&i->olist == sa_manager->hole) { |
372 | seq_printf(m, ">"); | 410 | seq_printf(m, ">"); |
@@ -381,6 +419,6 @@ void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, | |||
381 | } | 419 | } |
382 | seq_printf(m, "\n"); | 420 | seq_printf(m, "\n"); |
383 | } | 421 | } |
384 | spin_unlock(&sa_manager->lock); | 422 | spin_unlock(&sa_manager->wq.lock); |
385 | } | 423 | } |
386 | #endif | 424 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index e2ace5dce117..7cc78de6ddc3 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -68,70 +68,49 @@ void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, | |||
68 | radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); | 68 | radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); |
69 | } | 69 | } |
70 | 70 | ||
71 | /* caller must hold ring lock */ | ||
71 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, | 72 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, |
72 | struct radeon_semaphore *semaphore, | 73 | struct radeon_semaphore *semaphore, |
73 | bool sync_to[RADEON_NUM_RINGS], | 74 | int signaler, int waiter) |
74 | int dst_ring) | ||
75 | { | 75 | { |
76 | int i = 0, r; | 76 | int r; |
77 | 77 | ||
78 | mutex_lock(&rdev->ring_lock); | 78 | /* no need to signal and wait on the same ring */ |
79 | r = radeon_ring_alloc(rdev, &rdev->ring[dst_ring], RADEON_NUM_RINGS * 8); | 79 | if (signaler == waiter) { |
80 | if (r) { | 80 | return 0; |
81 | goto error; | ||
82 | } | 81 | } |
83 | 82 | ||
84 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 83 | /* prevent GPU deadlocks */ |
85 | /* no need to sync to our own or unused rings */ | 84 | if (!rdev->ring[signaler].ready) { |
86 | if (!sync_to[i] || i == dst_ring) | 85 | dev_err(rdev->dev, "Trying to sync to a disabled ring!"); |
87 | continue; | 86 | return -EINVAL; |
88 | 87 | } | |
89 | /* prevent GPU deadlocks */ | ||
90 | if (!rdev->ring[i].ready) { | ||
91 | dev_err(rdev->dev, "Trying to sync to a disabled ring!"); | ||
92 | r = -EINVAL; | ||
93 | goto error; | ||
94 | } | ||
95 | |||
96 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 8); | ||
97 | if (r) { | ||
98 | goto error; | ||
99 | } | ||
100 | |||
101 | radeon_semaphore_emit_signal(rdev, i, semaphore); | ||
102 | radeon_semaphore_emit_wait(rdev, dst_ring, semaphore); | ||
103 | 88 | ||
104 | radeon_ring_commit(rdev, &rdev->ring[i]); | 89 | r = radeon_ring_alloc(rdev, &rdev->ring[signaler], 8); |
90 | if (r) { | ||
91 | return r; | ||
105 | } | 92 | } |
93 | radeon_semaphore_emit_signal(rdev, signaler, semaphore); | ||
94 | radeon_ring_commit(rdev, &rdev->ring[signaler]); | ||
106 | 95 | ||
107 | radeon_ring_commit(rdev, &rdev->ring[dst_ring]); | 96 | /* we assume caller has already allocated space on waiters ring */ |
108 | mutex_unlock(&rdev->ring_lock); | 97 | radeon_semaphore_emit_wait(rdev, waiter, semaphore); |
109 | 98 | ||
110 | return 0; | 99 | return 0; |
111 | |||
112 | error: | ||
113 | /* unlock all locks taken so far */ | ||
114 | for (--i; i >= 0; --i) { | ||
115 | if (sync_to[i] || i == dst_ring) { | ||
116 | radeon_ring_undo(&rdev->ring[i]); | ||
117 | } | ||
118 | } | ||
119 | radeon_ring_undo(&rdev->ring[dst_ring]); | ||
120 | mutex_unlock(&rdev->ring_lock); | ||
121 | return r; | ||
122 | } | 100 | } |
123 | 101 | ||
124 | void radeon_semaphore_free(struct radeon_device *rdev, | 102 | void radeon_semaphore_free(struct radeon_device *rdev, |
125 | struct radeon_semaphore *semaphore, | 103 | struct radeon_semaphore **semaphore, |
126 | struct radeon_fence *fence) | 104 | struct radeon_fence *fence) |
127 | { | 105 | { |
128 | if (semaphore == NULL) { | 106 | if (semaphore == NULL || *semaphore == NULL) { |
129 | return; | 107 | return; |
130 | } | 108 | } |
131 | if (semaphore->waiters > 0) { | 109 | if ((*semaphore)->waiters > 0) { |
132 | dev_err(rdev->dev, "semaphore %p has more waiters than signalers," | 110 | dev_err(rdev->dev, "semaphore %p has more waiters than signalers," |
133 | " hardware lockup imminent!\n", semaphore); | 111 | " hardware lockup imminent!\n", *semaphore); |
134 | } | 112 | } |
135 | radeon_sa_bo_free(rdev, &semaphore->sa_bo, fence); | 113 | radeon_sa_bo_free(rdev, &(*semaphore)->sa_bo, fence); |
136 | kfree(semaphore); | 114 | kfree(*semaphore); |
115 | *semaphore = NULL; | ||
137 | } | 116 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index efff929ea49d..7c16540c10ff 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -106,13 +106,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
106 | 106 | ||
107 | radeon_bo_kunmap(gtt_obj[i]); | 107 | radeon_bo_kunmap(gtt_obj[i]); |
108 | 108 | ||
109 | r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); | 109 | r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence); |
110 | if (r) { | ||
111 | DRM_ERROR("Failed to create GTT->VRAM fence %d\n", i); | ||
112 | goto out_cleanup; | ||
113 | } | ||
114 | |||
115 | r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence); | ||
116 | if (r) { | 110 | if (r) { |
117 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); | 111 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); |
118 | goto out_cleanup; | 112 | goto out_cleanup; |
@@ -155,13 +149,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
155 | 149 | ||
156 | radeon_bo_kunmap(vram_obj); | 150 | radeon_bo_kunmap(vram_obj); |
157 | 151 | ||
158 | r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); | 152 | r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence); |
159 | if (r) { | ||
160 | DRM_ERROR("Failed to create VRAM->GTT fence %d\n", i); | ||
161 | goto out_cleanup; | ||
162 | } | ||
163 | |||
164 | r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence); | ||
165 | if (r) { | 153 | if (r) { |
166 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); | 154 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); |
167 | goto out_cleanup; | 155 | goto out_cleanup; |
@@ -241,36 +229,33 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
241 | { | 229 | { |
242 | struct radeon_fence *fence1 = NULL, *fence2 = NULL; | 230 | struct radeon_fence *fence1 = NULL, *fence2 = NULL; |
243 | struct radeon_semaphore *semaphore = NULL; | 231 | struct radeon_semaphore *semaphore = NULL; |
244 | int ridxA = radeon_ring_index(rdev, ringA); | ||
245 | int ridxB = radeon_ring_index(rdev, ringB); | ||
246 | int r; | 232 | int r; |
247 | 233 | ||
248 | r = radeon_fence_create(rdev, &fence1, ridxA); | 234 | r = radeon_semaphore_create(rdev, &semaphore); |
249 | if (r) { | 235 | if (r) { |
250 | DRM_ERROR("Failed to create sync fence 1\n"); | 236 | DRM_ERROR("Failed to create semaphore\n"); |
251 | goto out_cleanup; | 237 | goto out_cleanup; |
252 | } | 238 | } |
253 | r = radeon_fence_create(rdev, &fence2, ridxA); | 239 | |
240 | r = radeon_ring_lock(rdev, ringA, 64); | ||
254 | if (r) { | 241 | if (r) { |
255 | DRM_ERROR("Failed to create sync fence 2\n"); | 242 | DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); |
256 | goto out_cleanup; | 243 | goto out_cleanup; |
257 | } | 244 | } |
258 | 245 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); | |
259 | r = radeon_semaphore_create(rdev, &semaphore); | 246 | r = radeon_fence_emit(rdev, &fence1, ringA->idx); |
260 | if (r) { | 247 | if (r) { |
261 | DRM_ERROR("Failed to create semaphore\n"); | 248 | DRM_ERROR("Failed to emit fence 1\n"); |
249 | radeon_ring_unlock_undo(rdev, ringA); | ||
262 | goto out_cleanup; | 250 | goto out_cleanup; |
263 | } | 251 | } |
264 | 252 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); | |
265 | r = radeon_ring_lock(rdev, ringA, 64); | 253 | r = radeon_fence_emit(rdev, &fence2, ringA->idx); |
266 | if (r) { | 254 | if (r) { |
267 | DRM_ERROR("Failed to lock ring A %d\n", ridxA); | 255 | DRM_ERROR("Failed to emit fence 2\n"); |
256 | radeon_ring_unlock_undo(rdev, ringA); | ||
268 | goto out_cleanup; | 257 | goto out_cleanup; |
269 | } | 258 | } |
270 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); | ||
271 | radeon_fence_emit(rdev, fence1); | ||
272 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); | ||
273 | radeon_fence_emit(rdev, fence2); | ||
274 | radeon_ring_unlock_commit(rdev, ringA); | 259 | radeon_ring_unlock_commit(rdev, ringA); |
275 | 260 | ||
276 | mdelay(1000); | 261 | mdelay(1000); |
@@ -285,7 +270,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
285 | DRM_ERROR("Failed to lock ring B %p\n", ringB); | 270 | DRM_ERROR("Failed to lock ring B %p\n", ringB); |
286 | goto out_cleanup; | 271 | goto out_cleanup; |
287 | } | 272 | } |
288 | radeon_semaphore_emit_signal(rdev, ridxB, semaphore); | 273 | radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore); |
289 | radeon_ring_unlock_commit(rdev, ringB); | 274 | radeon_ring_unlock_commit(rdev, ringB); |
290 | 275 | ||
291 | r = radeon_fence_wait(fence1, false); | 276 | r = radeon_fence_wait(fence1, false); |
@@ -306,7 +291,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
306 | DRM_ERROR("Failed to lock ring B %p\n", ringB); | 291 | DRM_ERROR("Failed to lock ring B %p\n", ringB); |
307 | goto out_cleanup; | 292 | goto out_cleanup; |
308 | } | 293 | } |
309 | radeon_semaphore_emit_signal(rdev, ridxB, semaphore); | 294 | radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore); |
310 | radeon_ring_unlock_commit(rdev, ringB); | 295 | radeon_ring_unlock_commit(rdev, ringB); |
311 | 296 | ||
312 | r = radeon_fence_wait(fence2, false); | 297 | r = radeon_fence_wait(fence2, false); |
@@ -316,8 +301,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
316 | } | 301 | } |
317 | 302 | ||
318 | out_cleanup: | 303 | out_cleanup: |
319 | if (semaphore) | 304 | radeon_semaphore_free(rdev, &semaphore, NULL); |
320 | radeon_semaphore_free(rdev, semaphore, NULL); | ||
321 | 305 | ||
322 | if (fence1) | 306 | if (fence1) |
323 | radeon_fence_unref(&fence1); | 307 | radeon_fence_unref(&fence1); |
@@ -336,23 +320,9 @@ void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
336 | { | 320 | { |
337 | struct radeon_fence *fenceA = NULL, *fenceB = NULL; | 321 | struct radeon_fence *fenceA = NULL, *fenceB = NULL; |
338 | struct radeon_semaphore *semaphore = NULL; | 322 | struct radeon_semaphore *semaphore = NULL; |
339 | int ridxA = radeon_ring_index(rdev, ringA); | ||
340 | int ridxB = radeon_ring_index(rdev, ringB); | ||
341 | int ridxC = radeon_ring_index(rdev, ringC); | ||
342 | bool sigA, sigB; | 323 | bool sigA, sigB; |
343 | int i, r; | 324 | int i, r; |
344 | 325 | ||
345 | r = radeon_fence_create(rdev, &fenceA, ridxA); | ||
346 | if (r) { | ||
347 | DRM_ERROR("Failed to create sync fence 1\n"); | ||
348 | goto out_cleanup; | ||
349 | } | ||
350 | r = radeon_fence_create(rdev, &fenceB, ridxB); | ||
351 | if (r) { | ||
352 | DRM_ERROR("Failed to create sync fence 2\n"); | ||
353 | goto out_cleanup; | ||
354 | } | ||
355 | |||
356 | r = radeon_semaphore_create(rdev, &semaphore); | 326 | r = radeon_semaphore_create(rdev, &semaphore); |
357 | if (r) { | 327 | if (r) { |
358 | DRM_ERROR("Failed to create semaphore\n"); | 328 | DRM_ERROR("Failed to create semaphore\n"); |
@@ -361,20 +331,30 @@ void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
361 | 331 | ||
362 | r = radeon_ring_lock(rdev, ringA, 64); | 332 | r = radeon_ring_lock(rdev, ringA, 64); |
363 | if (r) { | 333 | if (r) { |
364 | DRM_ERROR("Failed to lock ring A %d\n", ridxA); | 334 | DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); |
335 | goto out_cleanup; | ||
336 | } | ||
337 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); | ||
338 | r = radeon_fence_emit(rdev, &fenceA, ringA->idx); | ||
339 | if (r) { | ||
340 | DRM_ERROR("Failed to emit sync fence 1\n"); | ||
341 | radeon_ring_unlock_undo(rdev, ringA); | ||
365 | goto out_cleanup; | 342 | goto out_cleanup; |
366 | } | 343 | } |
367 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); | ||
368 | radeon_fence_emit(rdev, fenceA); | ||
369 | radeon_ring_unlock_commit(rdev, ringA); | 344 | radeon_ring_unlock_commit(rdev, ringA); |
370 | 345 | ||
371 | r = radeon_ring_lock(rdev, ringB, 64); | 346 | r = radeon_ring_lock(rdev, ringB, 64); |
372 | if (r) { | 347 | if (r) { |
373 | DRM_ERROR("Failed to lock ring B %d\n", ridxB); | 348 | DRM_ERROR("Failed to lock ring B %d\n", ringB->idx); |
349 | goto out_cleanup; | ||
350 | } | ||
351 | radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore); | ||
352 | r = radeon_fence_emit(rdev, &fenceB, ringB->idx); | ||
353 | if (r) { | ||
354 | DRM_ERROR("Failed to create sync fence 2\n"); | ||
355 | radeon_ring_unlock_undo(rdev, ringB); | ||
374 | goto out_cleanup; | 356 | goto out_cleanup; |
375 | } | 357 | } |
376 | radeon_semaphore_emit_wait(rdev, ridxB, semaphore); | ||
377 | radeon_fence_emit(rdev, fenceB); | ||
378 | radeon_ring_unlock_commit(rdev, ringB); | 358 | radeon_ring_unlock_commit(rdev, ringB); |
379 | 359 | ||
380 | mdelay(1000); | 360 | mdelay(1000); |
@@ -393,7 +373,7 @@ void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
393 | DRM_ERROR("Failed to lock ring B %p\n", ringC); | 373 | DRM_ERROR("Failed to lock ring B %p\n", ringC); |
394 | goto out_cleanup; | 374 | goto out_cleanup; |
395 | } | 375 | } |
396 | radeon_semaphore_emit_signal(rdev, ridxC, semaphore); | 376 | radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); |
397 | radeon_ring_unlock_commit(rdev, ringC); | 377 | radeon_ring_unlock_commit(rdev, ringC); |
398 | 378 | ||
399 | for (i = 0; i < 30; ++i) { | 379 | for (i = 0; i < 30; ++i) { |
@@ -419,7 +399,7 @@ void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
419 | DRM_ERROR("Failed to lock ring B %p\n", ringC); | 399 | DRM_ERROR("Failed to lock ring B %p\n", ringC); |
420 | goto out_cleanup; | 400 | goto out_cleanup; |
421 | } | 401 | } |
422 | radeon_semaphore_emit_signal(rdev, ridxC, semaphore); | 402 | radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); |
423 | radeon_ring_unlock_commit(rdev, ringC); | 403 | radeon_ring_unlock_commit(rdev, ringC); |
424 | 404 | ||
425 | mdelay(1000); | 405 | mdelay(1000); |
@@ -436,8 +416,7 @@ void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
436 | } | 416 | } |
437 | 417 | ||
438 | out_cleanup: | 418 | out_cleanup: |
439 | if (semaphore) | 419 | radeon_semaphore_free(rdev, &semaphore, NULL); |
440 | radeon_semaphore_free(rdev, semaphore, NULL); | ||
441 | 420 | ||
442 | if (fenceA) | 421 | if (fenceA) |
443 | radeon_fence_unref(&fenceA); | 422 | radeon_fence_unref(&fenceA); |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index c94a2257761f..5b71c716d83f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -222,15 +222,11 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
222 | { | 222 | { |
223 | struct radeon_device *rdev; | 223 | struct radeon_device *rdev; |
224 | uint64_t old_start, new_start; | 224 | uint64_t old_start, new_start; |
225 | struct radeon_fence *fence, *old_fence; | 225 | struct radeon_fence *fence; |
226 | struct radeon_semaphore *sem = NULL; | 226 | int r, ridx; |
227 | int r; | ||
228 | 227 | ||
229 | rdev = radeon_get_rdev(bo->bdev); | 228 | rdev = radeon_get_rdev(bo->bdev); |
230 | r = radeon_fence_create(rdev, &fence, radeon_copy_ring_index(rdev)); | 229 | ridx = radeon_copy_ring_index(rdev); |
231 | if (unlikely(r)) { | ||
232 | return r; | ||
233 | } | ||
234 | old_start = old_mem->start << PAGE_SHIFT; | 230 | old_start = old_mem->start << PAGE_SHIFT; |
235 | new_start = new_mem->start << PAGE_SHIFT; | 231 | new_start = new_mem->start << PAGE_SHIFT; |
236 | 232 | ||
@@ -243,7 +239,6 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
243 | break; | 239 | break; |
244 | default: | 240 | default: |
245 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); | 241 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); |
246 | radeon_fence_unref(&fence); | ||
247 | return -EINVAL; | 242 | return -EINVAL; |
248 | } | 243 | } |
249 | switch (new_mem->mem_type) { | 244 | switch (new_mem->mem_type) { |
@@ -255,46 +250,23 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
255 | break; | 250 | break; |
256 | default: | 251 | default: |
257 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); | 252 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); |
258 | radeon_fence_unref(&fence); | ||
259 | return -EINVAL; | 253 | return -EINVAL; |
260 | } | 254 | } |
261 | if (!rdev->ring[radeon_copy_ring_index(rdev)].ready) { | 255 | if (!rdev->ring[ridx].ready) { |
262 | DRM_ERROR("Trying to move memory with ring turned off.\n"); | 256 | DRM_ERROR("Trying to move memory with ring turned off.\n"); |
263 | radeon_fence_unref(&fence); | ||
264 | return -EINVAL; | 257 | return -EINVAL; |
265 | } | 258 | } |
266 | 259 | ||
267 | BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); | 260 | BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); |
268 | 261 | ||
269 | /* sync other rings */ | 262 | /* sync other rings */ |
270 | old_fence = bo->sync_obj; | 263 | fence = bo->sync_obj; |
271 | if (old_fence && old_fence->ring != fence->ring | ||
272 | && !radeon_fence_signaled(old_fence)) { | ||
273 | bool sync_to_ring[RADEON_NUM_RINGS] = { }; | ||
274 | sync_to_ring[old_fence->ring] = true; | ||
275 | |||
276 | r = radeon_semaphore_create(rdev, &sem); | ||
277 | if (r) { | ||
278 | radeon_fence_unref(&fence); | ||
279 | return r; | ||
280 | } | ||
281 | |||
282 | r = radeon_semaphore_sync_rings(rdev, sem, | ||
283 | sync_to_ring, fence->ring); | ||
284 | if (r) { | ||
285 | radeon_semaphore_free(rdev, sem, NULL); | ||
286 | radeon_fence_unref(&fence); | ||
287 | return r; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | r = radeon_copy(rdev, old_start, new_start, | 264 | r = radeon_copy(rdev, old_start, new_start, |
292 | new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ | 265 | new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ |
293 | fence); | 266 | &fence); |
294 | /* FIXME: handle copy error */ | 267 | /* FIXME: handle copy error */ |
295 | r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, | 268 | r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, |
296 | evict, no_wait_reserve, no_wait_gpu, new_mem); | 269 | evict, no_wait_reserve, no_wait_gpu, new_mem); |
297 | radeon_semaphore_free(rdev, sem, fence); | ||
298 | radeon_fence_unref(&fence); | 270 | radeon_fence_unref(&fence); |
299 | return r; | 271 | return r; |
300 | } | 272 | } |
@@ -762,9 +734,7 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
762 | } | 734 | } |
763 | DRM_INFO("radeon: %uM of GTT memory ready.\n", | 735 | DRM_INFO("radeon: %uM of GTT memory ready.\n", |
764 | (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); | 736 | (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); |
765 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 737 | rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; |
766 | rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; | ||
767 | } | ||
768 | 738 | ||
769 | r = radeon_ttm_debugfs_init(rdev); | 739 | r = radeon_ttm_debugfs_init(rdev); |
770 | if (r) { | 740 | if (r) { |
@@ -825,9 +795,9 @@ static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
825 | return VM_FAULT_NOPAGE; | 795 | return VM_FAULT_NOPAGE; |
826 | } | 796 | } |
827 | rdev = radeon_get_rdev(bo->bdev); | 797 | rdev = radeon_get_rdev(bo->bdev); |
828 | mutex_lock(&rdev->vram_mutex); | 798 | down_read(&rdev->pm.mclk_lock); |
829 | r = ttm_vm_ops->fault(vma, vmf); | 799 | r = ttm_vm_ops->fault(vma, vmf); |
830 | mutex_unlock(&rdev->vram_mutex); | 800 | up_read(&rdev->pm.mclk_lock); |
831 | return r; | 801 | return r; |
832 | } | 802 | } |
833 | 803 | ||
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index a464eb5e2df2..2752f7f78237 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -426,13 +426,11 @@ static int rs400_startup(struct radeon_device *rdev) | |||
426 | return r; | 426 | return r; |
427 | } | 427 | } |
428 | 428 | ||
429 | r = radeon_ib_pool_start(rdev); | 429 | r = radeon_ib_pool_init(rdev); |
430 | if (r) | 430 | if (r) { |
431 | return r; | 431 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
432 | |||
433 | r = radeon_ib_ring_tests(rdev); | ||
434 | if (r) | ||
435 | return r; | 432 | return r; |
433 | } | ||
436 | 434 | ||
437 | return 0; | 435 | return 0; |
438 | } | 436 | } |
@@ -470,7 +468,6 @@ int rs400_resume(struct radeon_device *rdev) | |||
470 | 468 | ||
471 | int rs400_suspend(struct radeon_device *rdev) | 469 | int rs400_suspend(struct radeon_device *rdev) |
472 | { | 470 | { |
473 | radeon_ib_pool_suspend(rdev); | ||
474 | r100_cp_disable(rdev); | 471 | r100_cp_disable(rdev); |
475 | radeon_wb_disable(rdev); | 472 | radeon_wb_disable(rdev); |
476 | r100_irq_disable(rdev); | 473 | r100_irq_disable(rdev); |
@@ -482,7 +479,7 @@ void rs400_fini(struct radeon_device *rdev) | |||
482 | { | 479 | { |
483 | r100_cp_fini(rdev); | 480 | r100_cp_fini(rdev); |
484 | radeon_wb_fini(rdev); | 481 | radeon_wb_fini(rdev); |
485 | r100_ib_fini(rdev); | 482 | radeon_ib_pool_fini(rdev); |
486 | radeon_gem_fini(rdev); | 483 | radeon_gem_fini(rdev); |
487 | rs400_gart_fini(rdev); | 484 | rs400_gart_fini(rdev); |
488 | radeon_irq_kms_fini(rdev); | 485 | radeon_irq_kms_fini(rdev); |
@@ -550,20 +547,14 @@ int rs400_init(struct radeon_device *rdev) | |||
550 | return r; | 547 | return r; |
551 | r300_set_reg_safe(rdev); | 548 | r300_set_reg_safe(rdev); |
552 | 549 | ||
553 | r = radeon_ib_pool_init(rdev); | ||
554 | rdev->accel_working = true; | 550 | rdev->accel_working = true; |
555 | if (r) { | ||
556 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
557 | rdev->accel_working = false; | ||
558 | } | ||
559 | |||
560 | r = rs400_startup(rdev); | 551 | r = rs400_startup(rdev); |
561 | if (r) { | 552 | if (r) { |
562 | /* Somethings want wront with the accel init stop accel */ | 553 | /* Somethings want wront with the accel init stop accel */ |
563 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 554 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
564 | r100_cp_fini(rdev); | 555 | r100_cp_fini(rdev); |
565 | radeon_wb_fini(rdev); | 556 | radeon_wb_fini(rdev); |
566 | r100_ib_fini(rdev); | 557 | radeon_ib_pool_fini(rdev); |
567 | rs400_gart_fini(rdev); | 558 | rs400_gart_fini(rdev); |
568 | radeon_irq_kms_fini(rdev); | 559 | radeon_irq_kms_fini(rdev); |
569 | rdev->accel_working = false; | 560 | rdev->accel_working = false; |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index e95c5e61d4e2..5301b3df8466 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -294,6 +294,7 @@ void rs600_hpd_init(struct radeon_device *rdev) | |||
294 | { | 294 | { |
295 | struct drm_device *dev = rdev->ddev; | 295 | struct drm_device *dev = rdev->ddev; |
296 | struct drm_connector *connector; | 296 | struct drm_connector *connector; |
297 | unsigned enable = 0; | ||
297 | 298 | ||
298 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 299 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
299 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 300 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -301,26 +302,25 @@ void rs600_hpd_init(struct radeon_device *rdev) | |||
301 | case RADEON_HPD_1: | 302 | case RADEON_HPD_1: |
302 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | 303 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, |
303 | S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); | 304 | S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); |
304 | rdev->irq.hpd[0] = true; | ||
305 | break; | 305 | break; |
306 | case RADEON_HPD_2: | 306 | case RADEON_HPD_2: |
307 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | 307 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, |
308 | S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); | 308 | S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); |
309 | rdev->irq.hpd[1] = true; | ||
310 | break; | 309 | break; |
311 | default: | 310 | default: |
312 | break; | 311 | break; |
313 | } | 312 | } |
313 | enable |= 1 << radeon_connector->hpd.hpd; | ||
314 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 314 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
315 | } | 315 | } |
316 | if (rdev->irq.installed) | 316 | radeon_irq_kms_enable_hpd(rdev, enable); |
317 | rs600_irq_set(rdev); | ||
318 | } | 317 | } |
319 | 318 | ||
320 | void rs600_hpd_fini(struct radeon_device *rdev) | 319 | void rs600_hpd_fini(struct radeon_device *rdev) |
321 | { | 320 | { |
322 | struct drm_device *dev = rdev->ddev; | 321 | struct drm_device *dev = rdev->ddev; |
323 | struct drm_connector *connector; | 322 | struct drm_connector *connector; |
323 | unsigned disable = 0; | ||
324 | 324 | ||
325 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 325 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
326 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 326 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -328,17 +328,17 @@ void rs600_hpd_fini(struct radeon_device *rdev) | |||
328 | case RADEON_HPD_1: | 328 | case RADEON_HPD_1: |
329 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | 329 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, |
330 | S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); | 330 | S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); |
331 | rdev->irq.hpd[0] = false; | ||
332 | break; | 331 | break; |
333 | case RADEON_HPD_2: | 332 | case RADEON_HPD_2: |
334 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | 333 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, |
335 | S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); | 334 | S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); |
336 | rdev->irq.hpd[1] = false; | ||
337 | break; | 335 | break; |
338 | default: | 336 | default: |
339 | break; | 337 | break; |
340 | } | 338 | } |
339 | disable |= 1 << radeon_connector->hpd.hpd; | ||
341 | } | 340 | } |
341 | radeon_irq_kms_disable_hpd(rdev, disable); | ||
342 | } | 342 | } |
343 | 343 | ||
344 | int rs600_asic_reset(struct radeon_device *rdev) | 344 | int rs600_asic_reset(struct radeon_device *rdev) |
@@ -564,18 +564,18 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
564 | WREG32(R_000040_GEN_INT_CNTL, 0); | 564 | WREG32(R_000040_GEN_INT_CNTL, 0); |
565 | return -EINVAL; | 565 | return -EINVAL; |
566 | } | 566 | } |
567 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 567 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
568 | tmp |= S_000040_SW_INT_EN(1); | 568 | tmp |= S_000040_SW_INT_EN(1); |
569 | } | 569 | } |
570 | if (rdev->irq.gui_idle) { | 570 | if (rdev->irq.gui_idle) { |
571 | tmp |= S_000040_GUI_IDLE(1); | 571 | tmp |= S_000040_GUI_IDLE(1); |
572 | } | 572 | } |
573 | if (rdev->irq.crtc_vblank_int[0] || | 573 | if (rdev->irq.crtc_vblank_int[0] || |
574 | rdev->irq.pflip[0]) { | 574 | atomic_read(&rdev->irq.pflip[0])) { |
575 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); | 575 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); |
576 | } | 576 | } |
577 | if (rdev->irq.crtc_vblank_int[1] || | 577 | if (rdev->irq.crtc_vblank_int[1] || |
578 | rdev->irq.pflip[1]) { | 578 | atomic_read(&rdev->irq.pflip[1])) { |
579 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); | 579 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); |
580 | } | 580 | } |
581 | if (rdev->irq.hpd[0]) { | 581 | if (rdev->irq.hpd[0]) { |
@@ -686,7 +686,6 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
686 | /* GUI idle */ | 686 | /* GUI idle */ |
687 | if (G_000040_GUI_IDLE(status)) { | 687 | if (G_000040_GUI_IDLE(status)) { |
688 | rdev->irq.gui_idle_acked = true; | 688 | rdev->irq.gui_idle_acked = true; |
689 | rdev->pm.gui_idle = true; | ||
690 | wake_up(&rdev->irq.idle_queue); | 689 | wake_up(&rdev->irq.idle_queue); |
691 | } | 690 | } |
692 | /* Vertical blank interrupts */ | 691 | /* Vertical blank interrupts */ |
@@ -696,7 +695,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
696 | rdev->pm.vblank_sync = true; | 695 | rdev->pm.vblank_sync = true; |
697 | wake_up(&rdev->irq.vblank_queue); | 696 | wake_up(&rdev->irq.vblank_queue); |
698 | } | 697 | } |
699 | if (rdev->irq.pflip[0]) | 698 | if (atomic_read(&rdev->irq.pflip[0])) |
700 | radeon_crtc_handle_flip(rdev, 0); | 699 | radeon_crtc_handle_flip(rdev, 0); |
701 | } | 700 | } |
702 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { | 701 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
@@ -705,7 +704,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
705 | rdev->pm.vblank_sync = true; | 704 | rdev->pm.vblank_sync = true; |
706 | wake_up(&rdev->irq.vblank_queue); | 705 | wake_up(&rdev->irq.vblank_queue); |
707 | } | 706 | } |
708 | if (rdev->irq.pflip[1]) | 707 | if (atomic_read(&rdev->irq.pflip[1])) |
709 | radeon_crtc_handle_flip(rdev, 1); | 708 | radeon_crtc_handle_flip(rdev, 1); |
710 | } | 709 | } |
711 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { | 710 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
@@ -908,13 +907,11 @@ static int rs600_startup(struct radeon_device *rdev) | |||
908 | return r; | 907 | return r; |
909 | } | 908 | } |
910 | 909 | ||
911 | r = radeon_ib_pool_start(rdev); | 910 | r = radeon_ib_pool_init(rdev); |
912 | if (r) | 911 | if (r) { |
913 | return r; | 912 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
914 | |||
915 | r = radeon_ib_ring_tests(rdev); | ||
916 | if (r) | ||
917 | return r; | 913 | return r; |
914 | } | ||
918 | 915 | ||
919 | r = r600_audio_init(rdev); | 916 | r = r600_audio_init(rdev); |
920 | if (r) { | 917 | if (r) { |
@@ -956,7 +953,6 @@ int rs600_resume(struct radeon_device *rdev) | |||
956 | 953 | ||
957 | int rs600_suspend(struct radeon_device *rdev) | 954 | int rs600_suspend(struct radeon_device *rdev) |
958 | { | 955 | { |
959 | radeon_ib_pool_suspend(rdev); | ||
960 | r600_audio_fini(rdev); | 956 | r600_audio_fini(rdev); |
961 | r100_cp_disable(rdev); | 957 | r100_cp_disable(rdev); |
962 | radeon_wb_disable(rdev); | 958 | radeon_wb_disable(rdev); |
@@ -970,7 +966,7 @@ void rs600_fini(struct radeon_device *rdev) | |||
970 | r600_audio_fini(rdev); | 966 | r600_audio_fini(rdev); |
971 | r100_cp_fini(rdev); | 967 | r100_cp_fini(rdev); |
972 | radeon_wb_fini(rdev); | 968 | radeon_wb_fini(rdev); |
973 | r100_ib_fini(rdev); | 969 | radeon_ib_pool_fini(rdev); |
974 | radeon_gem_fini(rdev); | 970 | radeon_gem_fini(rdev); |
975 | rs600_gart_fini(rdev); | 971 | rs600_gart_fini(rdev); |
976 | radeon_irq_kms_fini(rdev); | 972 | radeon_irq_kms_fini(rdev); |
@@ -1038,20 +1034,14 @@ int rs600_init(struct radeon_device *rdev) | |||
1038 | return r; | 1034 | return r; |
1039 | rs600_set_safe_registers(rdev); | 1035 | rs600_set_safe_registers(rdev); |
1040 | 1036 | ||
1041 | r = radeon_ib_pool_init(rdev); | ||
1042 | rdev->accel_working = true; | 1037 | rdev->accel_working = true; |
1043 | if (r) { | ||
1044 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
1045 | rdev->accel_working = false; | ||
1046 | } | ||
1047 | |||
1048 | r = rs600_startup(rdev); | 1038 | r = rs600_startup(rdev); |
1049 | if (r) { | 1039 | if (r) { |
1050 | /* Somethings want wront with the accel init stop accel */ | 1040 | /* Somethings want wront with the accel init stop accel */ |
1051 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 1041 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
1052 | r100_cp_fini(rdev); | 1042 | r100_cp_fini(rdev); |
1053 | radeon_wb_fini(rdev); | 1043 | radeon_wb_fini(rdev); |
1054 | r100_ib_fini(rdev); | 1044 | radeon_ib_pool_fini(rdev); |
1055 | rs600_gart_fini(rdev); | 1045 | rs600_gart_fini(rdev); |
1056 | radeon_irq_kms_fini(rdev); | 1046 | radeon_irq_kms_fini(rdev); |
1057 | rdev->accel_working = false; | 1047 | rdev->accel_working = false; |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 159b6a43fda0..3b663fcfe061 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -637,13 +637,11 @@ static int rs690_startup(struct radeon_device *rdev) | |||
637 | return r; | 637 | return r; |
638 | } | 638 | } |
639 | 639 | ||
640 | r = radeon_ib_pool_start(rdev); | 640 | r = radeon_ib_pool_init(rdev); |
641 | if (r) | 641 | if (r) { |
642 | return r; | 642 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
643 | |||
644 | r = radeon_ib_ring_tests(rdev); | ||
645 | if (r) | ||
646 | return r; | 643 | return r; |
644 | } | ||
647 | 645 | ||
648 | r = r600_audio_init(rdev); | 646 | r = r600_audio_init(rdev); |
649 | if (r) { | 647 | if (r) { |
@@ -685,7 +683,6 @@ int rs690_resume(struct radeon_device *rdev) | |||
685 | 683 | ||
686 | int rs690_suspend(struct radeon_device *rdev) | 684 | int rs690_suspend(struct radeon_device *rdev) |
687 | { | 685 | { |
688 | radeon_ib_pool_suspend(rdev); | ||
689 | r600_audio_fini(rdev); | 686 | r600_audio_fini(rdev); |
690 | r100_cp_disable(rdev); | 687 | r100_cp_disable(rdev); |
691 | radeon_wb_disable(rdev); | 688 | radeon_wb_disable(rdev); |
@@ -699,7 +696,7 @@ void rs690_fini(struct radeon_device *rdev) | |||
699 | r600_audio_fini(rdev); | 696 | r600_audio_fini(rdev); |
700 | r100_cp_fini(rdev); | 697 | r100_cp_fini(rdev); |
701 | radeon_wb_fini(rdev); | 698 | radeon_wb_fini(rdev); |
702 | r100_ib_fini(rdev); | 699 | radeon_ib_pool_fini(rdev); |
703 | radeon_gem_fini(rdev); | 700 | radeon_gem_fini(rdev); |
704 | rs400_gart_fini(rdev); | 701 | rs400_gart_fini(rdev); |
705 | radeon_irq_kms_fini(rdev); | 702 | radeon_irq_kms_fini(rdev); |
@@ -768,20 +765,14 @@ int rs690_init(struct radeon_device *rdev) | |||
768 | return r; | 765 | return r; |
769 | rs600_set_safe_registers(rdev); | 766 | rs600_set_safe_registers(rdev); |
770 | 767 | ||
771 | r = radeon_ib_pool_init(rdev); | ||
772 | rdev->accel_working = true; | 768 | rdev->accel_working = true; |
773 | if (r) { | ||
774 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
775 | rdev->accel_working = false; | ||
776 | } | ||
777 | |||
778 | r = rs690_startup(rdev); | 769 | r = rs690_startup(rdev); |
779 | if (r) { | 770 | if (r) { |
780 | /* Somethings want wront with the accel init stop accel */ | 771 | /* Somethings want wront with the accel init stop accel */ |
781 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 772 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
782 | r100_cp_fini(rdev); | 773 | r100_cp_fini(rdev); |
783 | radeon_wb_fini(rdev); | 774 | radeon_wb_fini(rdev); |
784 | r100_ib_fini(rdev); | 775 | radeon_ib_pool_fini(rdev); |
785 | rs400_gart_fini(rdev); | 776 | rs400_gart_fini(rdev); |
786 | radeon_irq_kms_fini(rdev); | 777 | radeon_irq_kms_fini(rdev); |
787 | rdev->accel_working = false; | 778 | rdev->accel_working = false; |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 7f08cedb5333..a12fbcc8ccb6 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -408,13 +408,11 @@ static int rv515_startup(struct radeon_device *rdev) | |||
408 | return r; | 408 | return r; |
409 | } | 409 | } |
410 | 410 | ||
411 | r = radeon_ib_pool_start(rdev); | 411 | r = radeon_ib_pool_init(rdev); |
412 | if (r) | 412 | if (r) { |
413 | return r; | 413 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
414 | |||
415 | r = radeon_ib_ring_tests(rdev); | ||
416 | if (r) | ||
417 | return r; | 414 | return r; |
415 | } | ||
418 | 416 | ||
419 | return 0; | 417 | return 0; |
420 | } | 418 | } |
@@ -469,7 +467,7 @@ void rv515_fini(struct radeon_device *rdev) | |||
469 | { | 467 | { |
470 | r100_cp_fini(rdev); | 468 | r100_cp_fini(rdev); |
471 | radeon_wb_fini(rdev); | 469 | radeon_wb_fini(rdev); |
472 | r100_ib_fini(rdev); | 470 | radeon_ib_pool_fini(rdev); |
473 | radeon_gem_fini(rdev); | 471 | radeon_gem_fini(rdev); |
474 | rv370_pcie_gart_fini(rdev); | 472 | rv370_pcie_gart_fini(rdev); |
475 | radeon_agp_fini(rdev); | 473 | radeon_agp_fini(rdev); |
@@ -543,20 +541,14 @@ int rv515_init(struct radeon_device *rdev) | |||
543 | return r; | 541 | return r; |
544 | rv515_set_safe_registers(rdev); | 542 | rv515_set_safe_registers(rdev); |
545 | 543 | ||
546 | r = radeon_ib_pool_init(rdev); | ||
547 | rdev->accel_working = true; | 544 | rdev->accel_working = true; |
548 | if (r) { | ||
549 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
550 | rdev->accel_working = false; | ||
551 | } | ||
552 | |||
553 | r = rv515_startup(rdev); | 545 | r = rv515_startup(rdev); |
554 | if (r) { | 546 | if (r) { |
555 | /* Somethings want wront with the accel init stop accel */ | 547 | /* Somethings want wront with the accel init stop accel */ |
556 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 548 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
557 | r100_cp_fini(rdev); | 549 | r100_cp_fini(rdev); |
558 | radeon_wb_fini(rdev); | 550 | radeon_wb_fini(rdev); |
559 | r100_ib_fini(rdev); | 551 | radeon_ib_pool_fini(rdev); |
560 | radeon_irq_kms_fini(rdev); | 552 | radeon_irq_kms_fini(rdev); |
561 | rv370_pcie_gart_fini(rdev); | 553 | rv370_pcie_gart_fini(rdev); |
562 | radeon_agp_fini(rdev); | 554 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b4f51c569c36..ca8ffec10ff6 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -358,8 +358,10 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) | |||
358 | 358 | ||
359 | void r700_cp_fini(struct radeon_device *rdev) | 359 | void r700_cp_fini(struct radeon_device *rdev) |
360 | { | 360 | { |
361 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
361 | r700_cp_stop(rdev); | 362 | r700_cp_stop(rdev); |
362 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 363 | radeon_ring_fini(rdev, ring); |
364 | radeon_scratch_free(rdev, ring->rptr_save_reg); | ||
363 | } | 365 | } |
364 | 366 | ||
365 | /* | 367 | /* |
@@ -951,13 +953,11 @@ static int rv770_startup(struct radeon_device *rdev) | |||
951 | if (r) | 953 | if (r) |
952 | return r; | 954 | return r; |
953 | 955 | ||
954 | r = radeon_ib_pool_start(rdev); | 956 | r = radeon_ib_pool_init(rdev); |
955 | if (r) | 957 | if (r) { |
956 | return r; | 958 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
957 | |||
958 | r = radeon_ib_ring_tests(rdev); | ||
959 | if (r) | ||
960 | return r; | 959 | return r; |
960 | } | ||
961 | 961 | ||
962 | r = r600_audio_init(rdev); | 962 | r = r600_audio_init(rdev); |
963 | if (r) { | 963 | if (r) { |
@@ -994,9 +994,6 @@ int rv770_resume(struct radeon_device *rdev) | |||
994 | int rv770_suspend(struct radeon_device *rdev) | 994 | int rv770_suspend(struct radeon_device *rdev) |
995 | { | 995 | { |
996 | r600_audio_fini(rdev); | 996 | r600_audio_fini(rdev); |
997 | radeon_ib_pool_suspend(rdev); | ||
998 | r600_blit_suspend(rdev); | ||
999 | /* FIXME: we should wait for ring to be empty */ | ||
1000 | r700_cp_stop(rdev); | 997 | r700_cp_stop(rdev); |
1001 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 998 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
1002 | r600_irq_suspend(rdev); | 999 | r600_irq_suspend(rdev); |
@@ -1076,20 +1073,14 @@ int rv770_init(struct radeon_device *rdev) | |||
1076 | if (r) | 1073 | if (r) |
1077 | return r; | 1074 | return r; |
1078 | 1075 | ||
1079 | r = radeon_ib_pool_init(rdev); | ||
1080 | rdev->accel_working = true; | 1076 | rdev->accel_working = true; |
1081 | if (r) { | ||
1082 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
1083 | rdev->accel_working = false; | ||
1084 | } | ||
1085 | |||
1086 | r = rv770_startup(rdev); | 1077 | r = rv770_startup(rdev); |
1087 | if (r) { | 1078 | if (r) { |
1088 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 1079 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
1089 | r700_cp_fini(rdev); | 1080 | r700_cp_fini(rdev); |
1090 | r600_irq_fini(rdev); | 1081 | r600_irq_fini(rdev); |
1091 | radeon_wb_fini(rdev); | 1082 | radeon_wb_fini(rdev); |
1092 | r100_ib_fini(rdev); | 1083 | radeon_ib_pool_fini(rdev); |
1093 | radeon_irq_kms_fini(rdev); | 1084 | radeon_irq_kms_fini(rdev); |
1094 | rv770_pcie_gart_fini(rdev); | 1085 | rv770_pcie_gart_fini(rdev); |
1095 | rdev->accel_working = false; | 1086 | rdev->accel_working = false; |
@@ -1104,7 +1095,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
1104 | r700_cp_fini(rdev); | 1095 | r700_cp_fini(rdev); |
1105 | r600_irq_fini(rdev); | 1096 | r600_irq_fini(rdev); |
1106 | radeon_wb_fini(rdev); | 1097 | radeon_wb_fini(rdev); |
1107 | r100_ib_fini(rdev); | 1098 | radeon_ib_pool_fini(rdev); |
1108 | radeon_irq_kms_fini(rdev); | 1099 | radeon_irq_kms_fini(rdev); |
1109 | rv770_pcie_gart_fini(rdev); | 1100 | rv770_pcie_gart_fini(rdev); |
1110 | r600_vram_scratch_fini(rdev); | 1101 | r600_vram_scratch_fini(rdev); |
@@ -1121,6 +1112,8 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev) | |||
1121 | { | 1112 | { |
1122 | u32 link_width_cntl, lanes, speed_cntl, tmp; | 1113 | u32 link_width_cntl, lanes, speed_cntl, tmp; |
1123 | u16 link_cntl2; | 1114 | u16 link_cntl2; |
1115 | u32 mask; | ||
1116 | int ret; | ||
1124 | 1117 | ||
1125 | if (radeon_pcie_gen2 == 0) | 1118 | if (radeon_pcie_gen2 == 0) |
1126 | return; | 1119 | return; |
@@ -1135,6 +1128,15 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev) | |||
1135 | if (ASIC_IS_X2(rdev)) | 1128 | if (ASIC_IS_X2(rdev)) |
1136 | return; | 1129 | return; |
1137 | 1130 | ||
1131 | ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); | ||
1132 | if (ret != 0) | ||
1133 | return; | ||
1134 | |||
1135 | if (!(mask & DRM_PCIE_SPEED_50)) | ||
1136 | return; | ||
1137 | |||
1138 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | ||
1139 | |||
1138 | /* advertise upconfig capability */ | 1140 | /* advertise upconfig capability */ |
1139 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | 1141 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); |
1140 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | 1142 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 0b0279291a73..c053f8193771 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -1762,13 +1762,34 @@ void si_fence_ring_emit(struct radeon_device *rdev, | |||
1762 | */ | 1762 | */ |
1763 | void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 1763 | void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
1764 | { | 1764 | { |
1765 | struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; | 1765 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
1766 | u32 header; | 1766 | u32 header; |
1767 | 1767 | ||
1768 | if (ib->is_const_ib) | 1768 | if (ib->is_const_ib) { |
1769 | /* set switch buffer packet before const IB */ | ||
1770 | radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); | ||
1771 | radeon_ring_write(ring, 0); | ||
1772 | |||
1769 | header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); | 1773 | header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); |
1770 | else | 1774 | } else { |
1775 | u32 next_rptr; | ||
1776 | if (ring->rptr_save_reg) { | ||
1777 | next_rptr = ring->wptr + 3 + 4 + 8; | ||
1778 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1779 | radeon_ring_write(ring, ((ring->rptr_save_reg - | ||
1780 | PACKET3_SET_CONFIG_REG_START) >> 2)); | ||
1781 | radeon_ring_write(ring, next_rptr); | ||
1782 | } else if (rdev->wb.enabled) { | ||
1783 | next_rptr = ring->wptr + 5 + 4 + 8; | ||
1784 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
1785 | radeon_ring_write(ring, (1 << 8)); | ||
1786 | radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
1787 | radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
1788 | radeon_ring_write(ring, next_rptr); | ||
1789 | } | ||
1790 | |||
1771 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); | 1791 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); |
1792 | } | ||
1772 | 1793 | ||
1773 | radeon_ring_write(ring, header); | 1794 | radeon_ring_write(ring, header); |
1774 | radeon_ring_write(ring, | 1795 | radeon_ring_write(ring, |
@@ -1779,18 +1800,20 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1779 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); | 1800 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); |
1780 | radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); | 1801 | radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); |
1781 | 1802 | ||
1782 | /* flush read cache over gart for this vmid */ | 1803 | if (!ib->is_const_ib) { |
1783 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 1804 | /* flush read cache over gart for this vmid */ |
1784 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); | 1805 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
1785 | radeon_ring_write(ring, ib->vm_id); | 1806 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); |
1786 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 1807 | radeon_ring_write(ring, ib->vm_id); |
1787 | radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | | 1808 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
1788 | PACKET3_TC_ACTION_ENA | | 1809 | radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | |
1789 | PACKET3_SH_KCACHE_ACTION_ENA | | 1810 | PACKET3_TC_ACTION_ENA | |
1790 | PACKET3_SH_ICACHE_ACTION_ENA); | 1811 | PACKET3_SH_KCACHE_ACTION_ENA | |
1791 | radeon_ring_write(ring, 0xFFFFFFFF); | 1812 | PACKET3_SH_ICACHE_ACTION_ENA); |
1792 | radeon_ring_write(ring, 0); | 1813 | radeon_ring_write(ring, 0xFFFFFFFF); |
1793 | radeon_ring_write(ring, 10); /* poll interval */ | 1814 | radeon_ring_write(ring, 0); |
1815 | radeon_ring_write(ring, 10); /* poll interval */ | ||
1816 | } | ||
1794 | } | 1817 | } |
1795 | 1818 | ||
1796 | /* | 1819 | /* |
@@ -1917,10 +1940,20 @@ static int si_cp_start(struct radeon_device *rdev) | |||
1917 | 1940 | ||
1918 | static void si_cp_fini(struct radeon_device *rdev) | 1941 | static void si_cp_fini(struct radeon_device *rdev) |
1919 | { | 1942 | { |
1943 | struct radeon_ring *ring; | ||
1920 | si_cp_enable(rdev, false); | 1944 | si_cp_enable(rdev, false); |
1921 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 1945 | |
1922 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); | 1946 | ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
1923 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); | 1947 | radeon_ring_fini(rdev, ring); |
1948 | radeon_scratch_free(rdev, ring->rptr_save_reg); | ||
1949 | |||
1950 | ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; | ||
1951 | radeon_ring_fini(rdev, ring); | ||
1952 | radeon_scratch_free(rdev, ring->rptr_save_reg); | ||
1953 | |||
1954 | ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; | ||
1955 | radeon_ring_fini(rdev, ring); | ||
1956 | radeon_scratch_free(rdev, ring->rptr_save_reg); | ||
1924 | } | 1957 | } |
1925 | 1958 | ||
1926 | static int si_cp_resume(struct radeon_device *rdev) | 1959 | static int si_cp_resume(struct radeon_device *rdev) |
@@ -2702,7 +2735,7 @@ int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
2702 | if (ib->is_const_ib) | 2735 | if (ib->is_const_ib) |
2703 | ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt); | 2736 | ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt); |
2704 | else { | 2737 | else { |
2705 | switch (ib->fence->ring) { | 2738 | switch (ib->ring) { |
2706 | case RADEON_RING_TYPE_GFX_INDEX: | 2739 | case RADEON_RING_TYPE_GFX_INDEX: |
2707 | ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt); | 2740 | ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt); |
2708 | break; | 2741 | break; |
@@ -2711,7 +2744,7 @@ int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
2711 | ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt); | 2744 | ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt); |
2712 | break; | 2745 | break; |
2713 | default: | 2746 | default: |
2714 | dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->fence->ring); | 2747 | dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->ring); |
2715 | ret = -EINVAL; | 2748 | ret = -EINVAL; |
2716 | break; | 2749 | break; |
2717 | } | 2750 | } |
@@ -2942,7 +2975,6 @@ static void si_disable_interrupts(struct radeon_device *rdev) | |||
2942 | WREG32(IH_RB_RPTR, 0); | 2975 | WREG32(IH_RB_RPTR, 0); |
2943 | WREG32(IH_RB_WPTR, 0); | 2976 | WREG32(IH_RB_WPTR, 0); |
2944 | rdev->ih.enabled = false; | 2977 | rdev->ih.enabled = false; |
2945 | rdev->ih.wptr = 0; | ||
2946 | rdev->ih.rptr = 0; | 2978 | rdev->ih.rptr = 0; |
2947 | } | 2979 | } |
2948 | 2980 | ||
@@ -3093,45 +3125,45 @@ int si_irq_set(struct radeon_device *rdev) | |||
3093 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3125 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3094 | 3126 | ||
3095 | /* enable CP interrupts on all rings */ | 3127 | /* enable CP interrupts on all rings */ |
3096 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 3128 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
3097 | DRM_DEBUG("si_irq_set: sw int gfx\n"); | 3129 | DRM_DEBUG("si_irq_set: sw int gfx\n"); |
3098 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 3130 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
3099 | } | 3131 | } |
3100 | if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) { | 3132 | if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) { |
3101 | DRM_DEBUG("si_irq_set: sw int cp1\n"); | 3133 | DRM_DEBUG("si_irq_set: sw int cp1\n"); |
3102 | cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; | 3134 | cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; |
3103 | } | 3135 | } |
3104 | if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) { | 3136 | if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) { |
3105 | DRM_DEBUG("si_irq_set: sw int cp2\n"); | 3137 | DRM_DEBUG("si_irq_set: sw int cp2\n"); |
3106 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; | 3138 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; |
3107 | } | 3139 | } |
3108 | if (rdev->irq.crtc_vblank_int[0] || | 3140 | if (rdev->irq.crtc_vblank_int[0] || |
3109 | rdev->irq.pflip[0]) { | 3141 | atomic_read(&rdev->irq.pflip[0])) { |
3110 | DRM_DEBUG("si_irq_set: vblank 0\n"); | 3142 | DRM_DEBUG("si_irq_set: vblank 0\n"); |
3111 | crtc1 |= VBLANK_INT_MASK; | 3143 | crtc1 |= VBLANK_INT_MASK; |
3112 | } | 3144 | } |
3113 | if (rdev->irq.crtc_vblank_int[1] || | 3145 | if (rdev->irq.crtc_vblank_int[1] || |
3114 | rdev->irq.pflip[1]) { | 3146 | atomic_read(&rdev->irq.pflip[1])) { |
3115 | DRM_DEBUG("si_irq_set: vblank 1\n"); | 3147 | DRM_DEBUG("si_irq_set: vblank 1\n"); |
3116 | crtc2 |= VBLANK_INT_MASK; | 3148 | crtc2 |= VBLANK_INT_MASK; |
3117 | } | 3149 | } |
3118 | if (rdev->irq.crtc_vblank_int[2] || | 3150 | if (rdev->irq.crtc_vblank_int[2] || |
3119 | rdev->irq.pflip[2]) { | 3151 | atomic_read(&rdev->irq.pflip[2])) { |
3120 | DRM_DEBUG("si_irq_set: vblank 2\n"); | 3152 | DRM_DEBUG("si_irq_set: vblank 2\n"); |
3121 | crtc3 |= VBLANK_INT_MASK; | 3153 | crtc3 |= VBLANK_INT_MASK; |
3122 | } | 3154 | } |
3123 | if (rdev->irq.crtc_vblank_int[3] || | 3155 | if (rdev->irq.crtc_vblank_int[3] || |
3124 | rdev->irq.pflip[3]) { | 3156 | atomic_read(&rdev->irq.pflip[3])) { |
3125 | DRM_DEBUG("si_irq_set: vblank 3\n"); | 3157 | DRM_DEBUG("si_irq_set: vblank 3\n"); |
3126 | crtc4 |= VBLANK_INT_MASK; | 3158 | crtc4 |= VBLANK_INT_MASK; |
3127 | } | 3159 | } |
3128 | if (rdev->irq.crtc_vblank_int[4] || | 3160 | if (rdev->irq.crtc_vblank_int[4] || |
3129 | rdev->irq.pflip[4]) { | 3161 | atomic_read(&rdev->irq.pflip[4])) { |
3130 | DRM_DEBUG("si_irq_set: vblank 4\n"); | 3162 | DRM_DEBUG("si_irq_set: vblank 4\n"); |
3131 | crtc5 |= VBLANK_INT_MASK; | 3163 | crtc5 |= VBLANK_INT_MASK; |
3132 | } | 3164 | } |
3133 | if (rdev->irq.crtc_vblank_int[5] || | 3165 | if (rdev->irq.crtc_vblank_int[5] || |
3134 | rdev->irq.pflip[5]) { | 3166 | atomic_read(&rdev->irq.pflip[5])) { |
3135 | DRM_DEBUG("si_irq_set: vblank 5\n"); | 3167 | DRM_DEBUG("si_irq_set: vblank 5\n"); |
3136 | crtc6 |= VBLANK_INT_MASK; | 3168 | crtc6 |= VBLANK_INT_MASK; |
3137 | } | 3169 | } |
@@ -3359,29 +3391,27 @@ int si_irq_process(struct radeon_device *rdev) | |||
3359 | u32 rptr; | 3391 | u32 rptr; |
3360 | u32 src_id, src_data, ring_id; | 3392 | u32 src_id, src_data, ring_id; |
3361 | u32 ring_index; | 3393 | u32 ring_index; |
3362 | unsigned long flags; | ||
3363 | bool queue_hotplug = false; | 3394 | bool queue_hotplug = false; |
3364 | 3395 | ||
3365 | if (!rdev->ih.enabled || rdev->shutdown) | 3396 | if (!rdev->ih.enabled || rdev->shutdown) |
3366 | return IRQ_NONE; | 3397 | return IRQ_NONE; |
3367 | 3398 | ||
3368 | wptr = si_get_ih_wptr(rdev); | 3399 | wptr = si_get_ih_wptr(rdev); |
3400 | |||
3401 | restart_ih: | ||
3402 | /* is somebody else already processing irqs? */ | ||
3403 | if (atomic_xchg(&rdev->ih.lock, 1)) | ||
3404 | return IRQ_NONE; | ||
3405 | |||
3369 | rptr = rdev->ih.rptr; | 3406 | rptr = rdev->ih.rptr; |
3370 | DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 3407 | DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
3371 | 3408 | ||
3372 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
3373 | if (rptr == wptr) { | ||
3374 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
3375 | return IRQ_NONE; | ||
3376 | } | ||
3377 | restart_ih: | ||
3378 | /* Order reading of wptr vs. reading of IH ring data */ | 3409 | /* Order reading of wptr vs. reading of IH ring data */ |
3379 | rmb(); | 3410 | rmb(); |
3380 | 3411 | ||
3381 | /* display interrupts */ | 3412 | /* display interrupts */ |
3382 | si_irq_ack(rdev); | 3413 | si_irq_ack(rdev); |
3383 | 3414 | ||
3384 | rdev->ih.wptr = wptr; | ||
3385 | while (rptr != wptr) { | 3415 | while (rptr != wptr) { |
3386 | /* wptr/rptr are in bytes! */ | 3416 | /* wptr/rptr are in bytes! */ |
3387 | ring_index = rptr / 4; | 3417 | ring_index = rptr / 4; |
@@ -3399,7 +3429,7 @@ restart_ih: | |||
3399 | rdev->pm.vblank_sync = true; | 3429 | rdev->pm.vblank_sync = true; |
3400 | wake_up(&rdev->irq.vblank_queue); | 3430 | wake_up(&rdev->irq.vblank_queue); |
3401 | } | 3431 | } |
3402 | if (rdev->irq.pflip[0]) | 3432 | if (atomic_read(&rdev->irq.pflip[0])) |
3403 | radeon_crtc_handle_flip(rdev, 0); | 3433 | radeon_crtc_handle_flip(rdev, 0); |
3404 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 3434 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; |
3405 | DRM_DEBUG("IH: D1 vblank\n"); | 3435 | DRM_DEBUG("IH: D1 vblank\n"); |
@@ -3425,7 +3455,7 @@ restart_ih: | |||
3425 | rdev->pm.vblank_sync = true; | 3455 | rdev->pm.vblank_sync = true; |
3426 | wake_up(&rdev->irq.vblank_queue); | 3456 | wake_up(&rdev->irq.vblank_queue); |
3427 | } | 3457 | } |
3428 | if (rdev->irq.pflip[1]) | 3458 | if (atomic_read(&rdev->irq.pflip[1])) |
3429 | radeon_crtc_handle_flip(rdev, 1); | 3459 | radeon_crtc_handle_flip(rdev, 1); |
3430 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | 3460 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; |
3431 | DRM_DEBUG("IH: D2 vblank\n"); | 3461 | DRM_DEBUG("IH: D2 vblank\n"); |
@@ -3451,7 +3481,7 @@ restart_ih: | |||
3451 | rdev->pm.vblank_sync = true; | 3481 | rdev->pm.vblank_sync = true; |
3452 | wake_up(&rdev->irq.vblank_queue); | 3482 | wake_up(&rdev->irq.vblank_queue); |
3453 | } | 3483 | } |
3454 | if (rdev->irq.pflip[2]) | 3484 | if (atomic_read(&rdev->irq.pflip[2])) |
3455 | radeon_crtc_handle_flip(rdev, 2); | 3485 | radeon_crtc_handle_flip(rdev, 2); |
3456 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | 3486 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; |
3457 | DRM_DEBUG("IH: D3 vblank\n"); | 3487 | DRM_DEBUG("IH: D3 vblank\n"); |
@@ -3477,7 +3507,7 @@ restart_ih: | |||
3477 | rdev->pm.vblank_sync = true; | 3507 | rdev->pm.vblank_sync = true; |
3478 | wake_up(&rdev->irq.vblank_queue); | 3508 | wake_up(&rdev->irq.vblank_queue); |
3479 | } | 3509 | } |
3480 | if (rdev->irq.pflip[3]) | 3510 | if (atomic_read(&rdev->irq.pflip[3])) |
3481 | radeon_crtc_handle_flip(rdev, 3); | 3511 | radeon_crtc_handle_flip(rdev, 3); |
3482 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | 3512 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; |
3483 | DRM_DEBUG("IH: D4 vblank\n"); | 3513 | DRM_DEBUG("IH: D4 vblank\n"); |
@@ -3503,7 +3533,7 @@ restart_ih: | |||
3503 | rdev->pm.vblank_sync = true; | 3533 | rdev->pm.vblank_sync = true; |
3504 | wake_up(&rdev->irq.vblank_queue); | 3534 | wake_up(&rdev->irq.vblank_queue); |
3505 | } | 3535 | } |
3506 | if (rdev->irq.pflip[4]) | 3536 | if (atomic_read(&rdev->irq.pflip[4])) |
3507 | radeon_crtc_handle_flip(rdev, 4); | 3537 | radeon_crtc_handle_flip(rdev, 4); |
3508 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | 3538 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; |
3509 | DRM_DEBUG("IH: D5 vblank\n"); | 3539 | DRM_DEBUG("IH: D5 vblank\n"); |
@@ -3529,7 +3559,7 @@ restart_ih: | |||
3529 | rdev->pm.vblank_sync = true; | 3559 | rdev->pm.vblank_sync = true; |
3530 | wake_up(&rdev->irq.vblank_queue); | 3560 | wake_up(&rdev->irq.vblank_queue); |
3531 | } | 3561 | } |
3532 | if (rdev->irq.pflip[5]) | 3562 | if (atomic_read(&rdev->irq.pflip[5])) |
3533 | radeon_crtc_handle_flip(rdev, 5); | 3563 | radeon_crtc_handle_flip(rdev, 5); |
3534 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | 3564 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; |
3535 | DRM_DEBUG("IH: D6 vblank\n"); | 3565 | DRM_DEBUG("IH: D6 vblank\n"); |
@@ -3620,7 +3650,6 @@ restart_ih: | |||
3620 | break; | 3650 | break; |
3621 | case 233: /* GUI IDLE */ | 3651 | case 233: /* GUI IDLE */ |
3622 | DRM_DEBUG("IH: GUI idle\n"); | 3652 | DRM_DEBUG("IH: GUI idle\n"); |
3623 | rdev->pm.gui_idle = true; | ||
3624 | wake_up(&rdev->irq.idle_queue); | 3653 | wake_up(&rdev->irq.idle_queue); |
3625 | break; | 3654 | break; |
3626 | default: | 3655 | default: |
@@ -3632,15 +3661,17 @@ restart_ih: | |||
3632 | rptr += 16; | 3661 | rptr += 16; |
3633 | rptr &= rdev->ih.ptr_mask; | 3662 | rptr &= rdev->ih.ptr_mask; |
3634 | } | 3663 | } |
3635 | /* make sure wptr hasn't changed while processing */ | ||
3636 | wptr = si_get_ih_wptr(rdev); | ||
3637 | if (wptr != rdev->ih.wptr) | ||
3638 | goto restart_ih; | ||
3639 | if (queue_hotplug) | 3664 | if (queue_hotplug) |
3640 | schedule_work(&rdev->hotplug_work); | 3665 | schedule_work(&rdev->hotplug_work); |
3641 | rdev->ih.rptr = rptr; | 3666 | rdev->ih.rptr = rptr; |
3642 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3667 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3643 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3668 | atomic_set(&rdev->ih.lock, 0); |
3669 | |||
3670 | /* make sure wptr hasn't changed while processing */ | ||
3671 | wptr = si_get_ih_wptr(rdev); | ||
3672 | if (wptr != rptr) | ||
3673 | goto restart_ih; | ||
3674 | |||
3644 | return IRQ_HANDLED; | 3675 | return IRQ_HANDLED; |
3645 | } | 3676 | } |
3646 | 3677 | ||
@@ -3752,35 +3783,18 @@ static int si_startup(struct radeon_device *rdev) | |||
3752 | if (r) | 3783 | if (r) |
3753 | return r; | 3784 | return r; |
3754 | 3785 | ||
3755 | r = radeon_ib_pool_start(rdev); | 3786 | r = radeon_ib_pool_init(rdev); |
3756 | if (r) | ||
3757 | return r; | ||
3758 | |||
3759 | r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | ||
3760 | if (r) { | ||
3761 | DRM_ERROR("radeon: failed testing IB (%d) on CP ring 0\n", r); | ||
3762 | rdev->accel_working = false; | ||
3763 | return r; | ||
3764 | } | ||
3765 | |||
3766 | r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); | ||
3767 | if (r) { | 3787 | if (r) { |
3768 | DRM_ERROR("radeon: failed testing IB (%d) on CP ring 1\n", r); | 3788 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
3769 | rdev->accel_working = false; | ||
3770 | return r; | 3789 | return r; |
3771 | } | 3790 | } |
3772 | 3791 | ||
3773 | r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); | 3792 | r = radeon_vm_manager_init(rdev); |
3774 | if (r) { | 3793 | if (r) { |
3775 | DRM_ERROR("radeon: failed testing IB (%d) on CP ring 2\n", r); | 3794 | dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); |
3776 | rdev->accel_working = false; | ||
3777 | return r; | 3795 | return r; |
3778 | } | 3796 | } |
3779 | 3797 | ||
3780 | r = radeon_vm_manager_start(rdev); | ||
3781 | if (r) | ||
3782 | return r; | ||
3783 | |||
3784 | return 0; | 3798 | return 0; |
3785 | } | 3799 | } |
3786 | 3800 | ||
@@ -3809,12 +3823,6 @@ int si_resume(struct radeon_device *rdev) | |||
3809 | 3823 | ||
3810 | int si_suspend(struct radeon_device *rdev) | 3824 | int si_suspend(struct radeon_device *rdev) |
3811 | { | 3825 | { |
3812 | /* FIXME: we should wait for ring to be empty */ | ||
3813 | radeon_ib_pool_suspend(rdev); | ||
3814 | radeon_vm_manager_suspend(rdev); | ||
3815 | #if 0 | ||
3816 | r600_blit_suspend(rdev); | ||
3817 | #endif | ||
3818 | si_cp_enable(rdev, false); | 3826 | si_cp_enable(rdev, false); |
3819 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 3827 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
3820 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; | 3828 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; |
@@ -3903,17 +3911,7 @@ int si_init(struct radeon_device *rdev) | |||
3903 | if (r) | 3911 | if (r) |
3904 | return r; | 3912 | return r; |
3905 | 3913 | ||
3906 | r = radeon_ib_pool_init(rdev); | ||
3907 | rdev->accel_working = true; | 3914 | rdev->accel_working = true; |
3908 | if (r) { | ||
3909 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
3910 | rdev->accel_working = false; | ||
3911 | } | ||
3912 | r = radeon_vm_manager_init(rdev); | ||
3913 | if (r) { | ||
3914 | dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); | ||
3915 | } | ||
3916 | |||
3917 | r = si_startup(rdev); | 3915 | r = si_startup(rdev); |
3918 | if (r) { | 3916 | if (r) { |
3919 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 3917 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
@@ -3921,7 +3919,7 @@ int si_init(struct radeon_device *rdev) | |||
3921 | si_irq_fini(rdev); | 3919 | si_irq_fini(rdev); |
3922 | si_rlc_fini(rdev); | 3920 | si_rlc_fini(rdev); |
3923 | radeon_wb_fini(rdev); | 3921 | radeon_wb_fini(rdev); |
3924 | r100_ib_fini(rdev); | 3922 | radeon_ib_pool_fini(rdev); |
3925 | radeon_vm_manager_fini(rdev); | 3923 | radeon_vm_manager_fini(rdev); |
3926 | radeon_irq_kms_fini(rdev); | 3924 | radeon_irq_kms_fini(rdev); |
3927 | si_pcie_gart_fini(rdev); | 3925 | si_pcie_gart_fini(rdev); |
@@ -3950,7 +3948,7 @@ void si_fini(struct radeon_device *rdev) | |||
3950 | si_rlc_fini(rdev); | 3948 | si_rlc_fini(rdev); |
3951 | radeon_wb_fini(rdev); | 3949 | radeon_wb_fini(rdev); |
3952 | radeon_vm_manager_fini(rdev); | 3950 | radeon_vm_manager_fini(rdev); |
3953 | r100_ib_fini(rdev); | 3951 | radeon_ib_pool_fini(rdev); |
3954 | radeon_irq_kms_fini(rdev); | 3952 | radeon_irq_kms_fini(rdev); |
3955 | si_pcie_gart_fini(rdev); | 3953 | si_pcie_gart_fini(rdev); |
3956 | r600_vram_scratch_fini(rdev); | 3954 | r600_vram_scratch_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index db4067962868..7869089e8761 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -901,5 +901,6 @@ | |||
901 | #define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88 | 901 | #define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88 |
902 | #define PACKET3_SET_CE_DE_COUNTERS 0x89 | 902 | #define PACKET3_SET_CE_DE_COUNTERS 0x89 |
903 | #define PACKET3_WAIT_ON_AVAIL_BUFFER 0x8A | 903 | #define PACKET3_WAIT_ON_AVAIL_BUFFER 0x8A |
904 | #define PACKET3_SWITCH_BUFFER 0x8B | ||
904 | 905 | ||
905 | #endif | 906 | #endif |
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 6eb507a5d130..1efbb9075837 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
@@ -1050,6 +1050,7 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
1050 | { | 1050 | { |
1051 | struct drm_device_dma *dma = dev->dma; | 1051 | struct drm_device_dma *dma = dev->dma; |
1052 | drm_savage_private_t *dev_priv = dev->dev_private; | 1052 | drm_savage_private_t *dev_priv = dev->dev_private; |
1053 | int release_idlelock = 0; | ||
1053 | int i; | 1054 | int i; |
1054 | 1055 | ||
1055 | if (!dma) | 1056 | if (!dma) |
@@ -1059,7 +1060,10 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
1059 | if (!dma->buflist) | 1060 | if (!dma->buflist) |
1060 | return; | 1061 | return; |
1061 | 1062 | ||
1062 | /*i830_flush_queue(dev); */ | 1063 | if (file_priv->master && file_priv->master->lock.hw_lock) { |
1064 | drm_idlelock_take(&file_priv->master->lock); | ||
1065 | release_idlelock = 1; | ||
1066 | } | ||
1063 | 1067 | ||
1064 | for (i = 0; i < dma->buf_count; i++) { | 1068 | for (i = 0; i < dma->buf_count; i++) { |
1065 | struct drm_buf *buf = dma->buflist[i]; | 1069 | struct drm_buf *buf = dma->buflist[i]; |
@@ -1075,7 +1079,8 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
1075 | } | 1079 | } |
1076 | } | 1080 | } |
1077 | 1081 | ||
1078 | drm_core_reclaim_buffers(dev, file_priv); | 1082 | if (release_idlelock) |
1083 | drm_idlelock_release(&file_priv->master->lock); | ||
1079 | } | 1084 | } |
1080 | 1085 | ||
1081 | struct drm_ioctl_desc savage_ioctls[] = { | 1086 | struct drm_ioctl_desc savage_ioctls[] = { |
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index 89afe0b83643..d31d4cca9a4c 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c | |||
@@ -52,9 +52,9 @@ static struct drm_driver driver = { | |||
52 | .dev_priv_size = sizeof(drm_savage_buf_priv_t), | 52 | .dev_priv_size = sizeof(drm_savage_buf_priv_t), |
53 | .load = savage_driver_load, | 53 | .load = savage_driver_load, |
54 | .firstopen = savage_driver_firstopen, | 54 | .firstopen = savage_driver_firstopen, |
55 | .preclose = savage_reclaim_buffers, | ||
55 | .lastclose = savage_driver_lastclose, | 56 | .lastclose = savage_driver_lastclose, |
56 | .unload = savage_driver_unload, | 57 | .unload = savage_driver_unload, |
57 | .reclaim_buffers = savage_reclaim_buffers, | ||
58 | .ioctls = savage_ioctls, | 58 | .ioctls = savage_ioctls, |
59 | .dma_ioctl = savage_bci_buffers, | 59 | .dma_ioctl = savage_bci_buffers, |
60 | .fops = &savage_driver_fops, | 60 | .fops = &savage_driver_fops, |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index dd14cd1a0033..7f119870147c 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -105,10 +105,9 @@ static struct drm_driver driver = { | |||
105 | .load = sis_driver_load, | 105 | .load = sis_driver_load, |
106 | .unload = sis_driver_unload, | 106 | .unload = sis_driver_unload, |
107 | .open = sis_driver_open, | 107 | .open = sis_driver_open, |
108 | .preclose = sis_reclaim_buffers_locked, | ||
108 | .postclose = sis_driver_postclose, | 109 | .postclose = sis_driver_postclose, |
109 | .dma_quiescent = sis_idle, | 110 | .dma_quiescent = sis_idle, |
110 | .reclaim_buffers = NULL, | ||
111 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, | ||
112 | .lastclose = sis_lastclose, | 111 | .lastclose = sis_lastclose, |
113 | .ioctls = sis_ioctls, | 112 | .ioctls = sis_ioctls, |
114 | .fops = &sis_driver_fops, | 113 | .fops = &sis_driver_fops, |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index dd4a316c3d74..2c231070d250 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -74,7 +74,7 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file | |||
74 | dev_priv->vram_offset = fb->offset; | 74 | dev_priv->vram_offset = fb->offset; |
75 | 75 | ||
76 | mutex_unlock(&dev->struct_mutex); | 76 | mutex_unlock(&dev->struct_mutex); |
77 | DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size); | 77 | DRM_DEBUG("offset = %lu, size = %lu\n", fb->offset, fb->size); |
78 | 78 | ||
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
@@ -161,7 +161,7 @@ fail_alloc: | |||
161 | mem->size = 0; | 161 | mem->size = 0; |
162 | mem->free = 0; | 162 | mem->free = 0; |
163 | 163 | ||
164 | DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size, | 164 | DRM_DEBUG("alloc %d, size = %ld, offset = %ld\n", pool, mem->size, |
165 | mem->offset); | 165 | mem->offset); |
166 | 166 | ||
167 | return retval; | 167 | return retval; |
@@ -215,7 +215,7 @@ static int sis_ioctl_agp_init(struct drm_device *dev, void *data, | |||
215 | dev_priv->agp_offset = agp->offset; | 215 | dev_priv->agp_offset = agp->offset; |
216 | mutex_unlock(&dev->struct_mutex); | 216 | mutex_unlock(&dev->struct_mutex); |
217 | 217 | ||
218 | DRM_DEBUG("offset = %u, size = %u\n", agp->offset, agp->size); | 218 | DRM_DEBUG("offset = %lu, size = %lu\n", agp->offset, agp->size); |
219 | return 0; | 219 | return 0; |
220 | } | 220 | } |
221 | 221 | ||
@@ -321,14 +321,20 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
321 | struct sis_file_private *file_priv = file->driver_priv; | 321 | struct sis_file_private *file_priv = file->driver_priv; |
322 | struct sis_memblock *entry, *next; | 322 | struct sis_memblock *entry, *next; |
323 | 323 | ||
324 | if (!(file->minor->master && file->master->lock.hw_lock)) | ||
325 | return; | ||
326 | |||
327 | drm_idlelock_take(&file->master->lock); | ||
328 | |||
324 | mutex_lock(&dev->struct_mutex); | 329 | mutex_lock(&dev->struct_mutex); |
325 | if (list_empty(&file_priv->obj_list)) { | 330 | if (list_empty(&file_priv->obj_list)) { |
326 | mutex_unlock(&dev->struct_mutex); | 331 | mutex_unlock(&dev->struct_mutex); |
332 | drm_idlelock_release(&file->master->lock); | ||
333 | |||
327 | return; | 334 | return; |
328 | } | 335 | } |
329 | 336 | ||
330 | if (dev->driver->dma_quiescent) | 337 | sis_idle(dev); |
331 | dev->driver->dma_quiescent(dev); | ||
332 | 338 | ||
333 | 339 | ||
334 | list_for_each_entry_safe(entry, next, &file_priv->obj_list, | 340 | list_for_each_entry_safe(entry, next, &file_priv->obj_list, |
@@ -343,6 +349,9 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
343 | kfree(entry); | 349 | kfree(entry); |
344 | } | 350 | } |
345 | mutex_unlock(&dev->struct_mutex); | 351 | mutex_unlock(&dev->struct_mutex); |
352 | |||
353 | drm_idlelock_release(&file->master->lock); | ||
354 | |||
346 | return; | 355 | return; |
347 | } | 356 | } |
348 | 357 | ||
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 1613c78544c0..90f6b13acfac 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c | |||
@@ -54,7 +54,6 @@ static const struct file_operations tdfx_driver_fops = { | |||
54 | 54 | ||
55 | static struct drm_driver driver = { | 55 | static struct drm_driver driver = { |
56 | .driver_features = DRIVER_USE_MTRR, | 56 | .driver_features = DRIVER_USE_MTRR, |
57 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
58 | .fops = &tdfx_driver_fops, | 57 | .fops = &tdfx_driver_fops, |
59 | .name = DRIVER_NAME, | 58 | .name = DRIVER_NAME, |
60 | .desc = DRIVER_DESC, | 59 | .desc = DRIVER_DESC, |
diff --git a/drivers/gpu/drm/udl/udl_encoder.c b/drivers/gpu/drm/udl/udl_encoder.c index 56e75f0f1df5..0731ab2e6c06 100644 --- a/drivers/gpu/drm/udl/udl_encoder.c +++ b/drivers/gpu/drm/udl/udl_encoder.c | |||
@@ -27,7 +27,7 @@ static void udl_encoder_disable(struct drm_encoder *encoder) | |||
27 | } | 27 | } |
28 | 28 | ||
29 | static bool udl_mode_fixup(struct drm_encoder *encoder, | 29 | static bool udl_mode_fixup(struct drm_encoder *encoder, |
30 | struct drm_display_mode *mode, | 30 | const struct drm_display_mode *mode, |
31 | struct drm_display_mode *adjusted_mode) | 31 | struct drm_display_mode *adjusted_mode) |
32 | { | 32 | { |
33 | return true; | 33 | return true; |
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 0d7816789da1..f5dd89e891de 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c | |||
@@ -45,12 +45,25 @@ static char *udl_vidreg_unlock(char *buf) | |||
45 | * 0x01 H and V sync off (screen blank but powered) | 45 | * 0x01 H and V sync off (screen blank but powered) |
46 | * 0x07 DPMS powerdown (requires modeset to come back) | 46 | * 0x07 DPMS powerdown (requires modeset to come back) |
47 | */ | 47 | */ |
48 | static char *udl_enable_hvsync(char *buf, bool enable) | 48 | static char *udl_set_blank(char *buf, int dpms_mode) |
49 | { | 49 | { |
50 | if (enable) | 50 | u8 reg; |
51 | return udl_set_register(buf, 0x1F, 0x00); | 51 | switch (dpms_mode) { |
52 | else | 52 | case DRM_MODE_DPMS_OFF: |
53 | return udl_set_register(buf, 0x1F, 0x07); | 53 | reg = 0x07; |
54 | break; | ||
55 | case DRM_MODE_DPMS_STANDBY: | ||
56 | reg = 0x05; | ||
57 | break; | ||
58 | case DRM_MODE_DPMS_SUSPEND: | ||
59 | reg = 0x01; | ||
60 | break; | ||
61 | case DRM_MODE_DPMS_ON: | ||
62 | reg = 0x00; | ||
63 | break; | ||
64 | } | ||
65 | |||
66 | return udl_set_register(buf, 0x1f, reg); | ||
54 | } | 67 | } |
55 | 68 | ||
56 | static char *udl_set_color_depth(char *buf, u8 selection) | 69 | static char *udl_set_color_depth(char *buf, u8 selection) |
@@ -199,6 +212,20 @@ static char *udl_set_vid_cmds(char *wrptr, struct drm_display_mode *mode) | |||
199 | return wrptr; | 212 | return wrptr; |
200 | } | 213 | } |
201 | 214 | ||
215 | static char *udl_dummy_render(char *wrptr) | ||
216 | { | ||
217 | *wrptr++ = 0xAF; | ||
218 | *wrptr++ = 0x6A; /* copy */ | ||
219 | *wrptr++ = 0x00; /* from addr */ | ||
220 | *wrptr++ = 0x00; | ||
221 | *wrptr++ = 0x00; | ||
222 | *wrptr++ = 0x01; /* one pixel */ | ||
223 | *wrptr++ = 0x00; /* to address */ | ||
224 | *wrptr++ = 0x00; | ||
225 | *wrptr++ = 0x00; | ||
226 | return wrptr; | ||
227 | } | ||
228 | |||
202 | static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) | 229 | static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) |
203 | { | 230 | { |
204 | struct drm_device *dev = crtc->dev; | 231 | struct drm_device *dev = crtc->dev; |
@@ -235,9 +262,10 @@ static void udl_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
235 | 262 | ||
236 | buf = (char *)urb->transfer_buffer; | 263 | buf = (char *)urb->transfer_buffer; |
237 | buf = udl_vidreg_lock(buf); | 264 | buf = udl_vidreg_lock(buf); |
238 | buf = udl_enable_hvsync(buf, false); | 265 | buf = udl_set_blank(buf, mode); |
239 | buf = udl_vidreg_unlock(buf); | 266 | buf = udl_vidreg_unlock(buf); |
240 | 267 | ||
268 | buf = udl_dummy_render(buf); | ||
241 | retval = udl_submit_urb(dev, urb, buf - (char *) | 269 | retval = udl_submit_urb(dev, urb, buf - (char *) |
242 | urb->transfer_buffer); | 270 | urb->transfer_buffer); |
243 | } else { | 271 | } else { |
@@ -251,7 +279,7 @@ static void udl_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
251 | } | 279 | } |
252 | 280 | ||
253 | static bool udl_crtc_mode_fixup(struct drm_crtc *crtc, | 281 | static bool udl_crtc_mode_fixup(struct drm_crtc *crtc, |
254 | struct drm_display_mode *mode, | 282 | const struct drm_display_mode *mode, |
255 | struct drm_display_mode *adjusted_mode) | 283 | struct drm_display_mode *adjusted_mode) |
256 | 284 | ||
257 | { | 285 | { |
@@ -306,9 +334,11 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, | |||
306 | wrptr = udl_set_base8bpp(wrptr, 2 * mode->vdisplay * mode->hdisplay); | 334 | wrptr = udl_set_base8bpp(wrptr, 2 * mode->vdisplay * mode->hdisplay); |
307 | 335 | ||
308 | wrptr = udl_set_vid_cmds(wrptr, adjusted_mode); | 336 | wrptr = udl_set_vid_cmds(wrptr, adjusted_mode); |
309 | wrptr = udl_enable_hvsync(wrptr, true); | 337 | wrptr = udl_set_blank(wrptr, DRM_MODE_DPMS_ON); |
310 | wrptr = udl_vidreg_unlock(wrptr); | 338 | wrptr = udl_vidreg_unlock(wrptr); |
311 | 339 | ||
340 | wrptr = udl_dummy_render(wrptr); | ||
341 | |||
312 | ufb->active_16 = true; | 342 | ufb->active_16 = true; |
313 | if (old_fb) { | 343 | if (old_fb) { |
314 | struct udl_framebuffer *uold_fb = to_udl_fb(old_fb); | 344 | struct udl_framebuffer *uold_fb = to_udl_fb(old_fb); |
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index 02661f35f7a0..e927b4c052f5 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -75,6 +75,7 @@ static struct drm_driver driver = { | |||
75 | .load = via_driver_load, | 75 | .load = via_driver_load, |
76 | .unload = via_driver_unload, | 76 | .unload = via_driver_unload, |
77 | .open = via_driver_open, | 77 | .open = via_driver_open, |
78 | .preclose = via_reclaim_buffers_locked, | ||
78 | .postclose = via_driver_postclose, | 79 | .postclose = via_driver_postclose, |
79 | .context_dtor = via_final_context, | 80 | .context_dtor = via_final_context, |
80 | .get_vblank_counter = via_get_vblank_counter, | 81 | .get_vblank_counter = via_get_vblank_counter, |
@@ -85,9 +86,6 @@ static struct drm_driver driver = { | |||
85 | .irq_uninstall = via_driver_irq_uninstall, | 86 | .irq_uninstall = via_driver_irq_uninstall, |
86 | .irq_handler = via_driver_irq_handler, | 87 | .irq_handler = via_driver_irq_handler, |
87 | .dma_quiescent = via_driver_dma_quiescent, | 88 | .dma_quiescent = via_driver_dma_quiescent, |
88 | .reclaim_buffers = drm_core_reclaim_buffers, | ||
89 | .reclaim_buffers_locked = NULL, | ||
90 | .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, | ||
91 | .lastclose = via_lastclose, | 89 | .lastclose = via_lastclose, |
92 | .ioctls = via_ioctls, | 90 | .ioctls = via_ioctls, |
93 | .fops = &via_driver_fops, | 91 | .fops = &via_driver_fops, |
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c index a3574d09a07d..acfcb358e7b7 100644 --- a/drivers/gpu/drm/via/via_mm.c +++ b/drivers/gpu/drm/via/via_mm.c | |||
@@ -215,14 +215,20 @@ void via_reclaim_buffers_locked(struct drm_device *dev, | |||
215 | struct via_file_private *file_priv = file->driver_priv; | 215 | struct via_file_private *file_priv = file->driver_priv; |
216 | struct via_memblock *entry, *next; | 216 | struct via_memblock *entry, *next; |
217 | 217 | ||
218 | if (!(file->minor->master && file->master->lock.hw_lock)) | ||
219 | return; | ||
220 | |||
221 | drm_idlelock_take(&file->master->lock); | ||
222 | |||
218 | mutex_lock(&dev->struct_mutex); | 223 | mutex_lock(&dev->struct_mutex); |
219 | if (list_empty(&file_priv->obj_list)) { | 224 | if (list_empty(&file_priv->obj_list)) { |
220 | mutex_unlock(&dev->struct_mutex); | 225 | mutex_unlock(&dev->struct_mutex); |
226 | drm_idlelock_release(&file->master->lock); | ||
227 | |||
221 | return; | 228 | return; |
222 | } | 229 | } |
223 | 230 | ||
224 | if (dev->driver->dma_quiescent) | 231 | via_driver_dma_quiescent(dev); |
225 | dev->driver->dma_quiescent(dev); | ||
226 | 232 | ||
227 | list_for_each_entry_safe(entry, next, &file_priv->obj_list, | 233 | list_for_each_entry_safe(entry, next, &file_priv->obj_list, |
228 | owner_list) { | 234 | owner_list) { |
@@ -231,5 +237,8 @@ void via_reclaim_buffers_locked(struct drm_device *dev, | |||
231 | kfree(entry); | 237 | kfree(entry); |
232 | } | 238 | } |
233 | mutex_unlock(&dev->struct_mutex); | 239 | mutex_unlock(&dev->struct_mutex); |
240 | |||
241 | drm_idlelock_release(&file->master->lock); | ||
242 | |||
234 | return; | 243 | return; |
235 | } | 244 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index ee24d216aa85..4d9edead01ac 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -769,10 +769,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) | |||
769 | goto out_no_tfile; | 769 | goto out_no_tfile; |
770 | 770 | ||
771 | file_priv->driver_priv = vmw_fp; | 771 | file_priv->driver_priv = vmw_fp; |
772 | 772 | dev_priv->bdev.dev_mapping = dev->dev_mapping; | |
773 | if (unlikely(dev_priv->bdev.dev_mapping == NULL)) | ||
774 | dev_priv->bdev.dev_mapping = | ||
775 | file_priv->filp->f_path.dentry->d_inode->i_mapping; | ||
776 | 773 | ||
777 | return 0; | 774 | return 0; |
778 | 775 | ||
@@ -1147,7 +1144,6 @@ static struct drm_driver driver = { | |||
1147 | .get_vblank_counter = vmw_get_vblank_counter, | 1144 | .get_vblank_counter = vmw_get_vblank_counter, |
1148 | .enable_vblank = vmw_enable_vblank, | 1145 | .enable_vblank = vmw_enable_vblank, |
1149 | .disable_vblank = vmw_disable_vblank, | 1146 | .disable_vblank = vmw_disable_vblank, |
1150 | .reclaim_buffers_locked = NULL, | ||
1151 | .ioctls = vmw_ioctls, | 1147 | .ioctls = vmw_ioctls, |
1152 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), | 1148 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), |
1153 | .dma_quiescent = NULL, /*vmw_dma_quiescent, */ | 1149 | .dma_quiescent = NULL, /*vmw_dma_quiescent, */ |