aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Garrett <mjg@redhat.com>2010-04-26 15:52:20 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 04:21:17 -0400
commit5876dd249e8e47c730cac090bf6edd88e5f04327 (patch)
treece5c99862483dca878bef6ac8c8280c380344f4e /drivers
parent2aba631c008e7d82e3ec45dd32bec1ea63a963cf (diff)
radeon: Unmap vram pages when reclocking
Touching vram while the card is reclocking can lead to lockups. Unmap any pages that could be touched by the CPU and block any accesses to vram until the reclocking is complete. Signed-off-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c6
5 files changed, 39 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index cdcf5eaf6714..bed84b316bba 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1024,6 +1024,7 @@ struct radeon_device {
1024 struct work_struct hotplug_work; 1024 struct work_struct hotplug_work;
1025 int num_crtc; /* number of crtcs */ 1025 int num_crtc; /* number of crtcs */
1026 struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ 1026 struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
1027 struct mutex vram_mutex;
1027 1028
1028 /* audio stuff */ 1029 /* audio stuff */
1029 struct timer_list audio_timer; 1030 struct timer_list audio_timer;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 53a2c27dd8fa..0372ec96020f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -599,6 +599,7 @@ int radeon_device_init(struct radeon_device *rdev,
599 spin_lock_init(&rdev->ih.lock); 599 spin_lock_init(&rdev->ih.lock);
600 mutex_init(&rdev->gem.mutex); 600 mutex_init(&rdev->gem.mutex);
601 mutex_init(&rdev->pm.mutex); 601 mutex_init(&rdev->pm.mutex);
602 mutex_init(&rdev->vram_mutex);
602 rwlock_init(&rdev->fence_drv.lock); 603 rwlock_init(&rdev->fence_drv.lock);
603 INIT_LIST_HEAD(&rdev->gem.objects); 604 INIT_LIST_HEAD(&rdev->gem.objects);
604 init_waitqueue_head(&rdev->irq.vblank_queue); 605 init_waitqueue_head(&rdev->irq.vblank_queue);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 6a8617bac142..06def708b014 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -112,9 +112,11 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
112 112
113 radeon_ttm_placement_from_domain(bo, domain); 113 radeon_ttm_placement_from_domain(bo, domain);
114 /* Kernel allocation are uninterruptible */ 114 /* Kernel allocation are uninterruptible */
115 mutex_lock(&rdev->vram_mutex);
115 r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, 116 r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
116 &bo->placement, 0, 0, !kernel, NULL, size, 117 &bo->placement, 0, 0, !kernel, NULL, size,
117 &radeon_ttm_bo_destroy); 118 &radeon_ttm_bo_destroy);
119 mutex_unlock(&rdev->vram_mutex);
118 if (unlikely(r != 0)) { 120 if (unlikely(r != 0)) {
119 if (r != -ERESTARTSYS) 121 if (r != -ERESTARTSYS)
120 dev_err(rdev->dev, 122 dev_err(rdev->dev,
@@ -170,7 +172,9 @@ void radeon_bo_unref(struct radeon_bo **bo)
170 if ((*bo) == NULL) 172 if ((*bo) == NULL)
171 return; 173 return;
172 tbo = &((*bo)->tbo); 174 tbo = &((*bo)->tbo);
175 mutex_lock(&(*bo)->rdev->vram_mutex);
173 ttm_bo_unref(&tbo); 176 ttm_bo_unref(&tbo);
177 mutex_unlock(&(*bo)->rdev->vram_mutex);
174 if (tbo == NULL) 178 if (tbo == NULL)
175 *bo = NULL; 179 *bo = NULL;
176} 180}
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index a61de1f9ff64..da35bd7f38dc 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -32,6 +32,28 @@
32static void radeon_pm_idle_work_handler(struct work_struct *work); 32static void radeon_pm_idle_work_handler(struct work_struct *work);
33static int radeon_debugfs_pm_init(struct radeon_device *rdev); 33static int radeon_debugfs_pm_init(struct radeon_device *rdev);
34 34
35static void radeon_unmap_vram_bos(struct radeon_device *rdev)
36{
37 struct radeon_bo *bo, *n;
38
39 if (list_empty(&rdev->gem.objects))
40 return;
41
42 list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) {
43 if (bo->tbo.mem.mem_type == TTM_PL_VRAM)
44 ttm_bo_unmap_virtual(&bo->tbo);
45 }
46
47 if (rdev->gart.table.vram.robj)
48 ttm_bo_unmap_virtual(&rdev->gart.table.vram.robj->tbo);
49
50 if (rdev->stollen_vga_memory)
51 ttm_bo_unmap_virtual(&rdev->stollen_vga_memory->tbo);
52
53 if (rdev->r600_blit.shader_obj)
54 ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo);
55}
56
35static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch) 57static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
36{ 58{
37 int i; 59 int i;
@@ -48,6 +70,10 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
48 rdev->irq.gui_idle = false; 70 rdev->irq.gui_idle = false;
49 radeon_irq_set(rdev); 71 radeon_irq_set(rdev);
50 72
73 mutex_lock(&rdev->vram_mutex);
74
75 radeon_unmap_vram_bos(rdev);
76
51 if (!static_switch) { 77 if (!static_switch) {
52 for (i = 0; i < rdev->num_crtc; i++) { 78 for (i = 0; i < rdev->num_crtc; i++) {
53 if (rdev->pm.active_crtcs & (1 << i)) { 79 if (rdev->pm.active_crtcs & (1 << i)) {
@@ -67,6 +93,8 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
67 } 93 }
68 } 94 }
69 } 95 }
96
97 mutex_unlock(&rdev->vram_mutex);
70 98
71 /* update display watermarks based on new power state */ 99 /* update display watermarks based on new power state */
72 radeon_update_bandwidth_info(rdev); 100 radeon_update_bandwidth_info(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index af98f45954b3..3aa3a65800ab 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -607,13 +607,17 @@ static const struct vm_operations_struct *ttm_vm_ops = NULL;
607static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 607static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
608{ 608{
609 struct ttm_buffer_object *bo; 609 struct ttm_buffer_object *bo;
610 struct radeon_device *rdev;
610 int r; 611 int r;
611 612
612 bo = (struct ttm_buffer_object *)vma->vm_private_data; 613 bo = (struct ttm_buffer_object *)vma->vm_private_data;
613 if (bo == NULL) { 614 if (bo == NULL) {
614 return VM_FAULT_NOPAGE; 615 return VM_FAULT_NOPAGE;
615 } 616 }
617 rdev = radeon_get_rdev(bo->bdev);
618 mutex_lock(&rdev->vram_mutex);
616 r = ttm_vm_ops->fault(vma, vmf); 619 r = ttm_vm_ops->fault(vma, vmf);
620 mutex_unlock(&rdev->vram_mutex);
617 return r; 621 return r;
618} 622}
619 623