summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_pm.c
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 18:21:17 +1000
commit5876dd249e8e47c730cac090bf6edd88e5f04327 (patch)
treece5c99862483dca878bef6ac8c8280c380344f4e /drivers/gpu/drm/radeon/radeon_pm.c
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/gpu/drm/radeon/radeon_pm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c28
1 files changed, 28 insertions, 0 deletions
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 @@
static void radeon_pm_idle_work_handler(struct work_struct *work);
static int radeon_debugfs_pm_init(struct radeon_device *rdev);
+static void radeon_unmap_vram_bos(struct radeon_device *rdev)
+{
+ struct radeon_bo *bo, *n;
+
+ if (list_empty(&rdev->gem.objects))
+ return;
+
+ list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) {
+ if (bo->tbo.mem.mem_type == TTM_PL_VRAM)
+ ttm_bo_unmap_virtual(&bo->tbo);
+ }
+
+ if (rdev->gart.table.vram.robj)
+ ttm_bo_unmap_virtual(&rdev->gart.table.vram.robj->tbo);
+
+ if (rdev->stollen_vga_memory)
+ ttm_bo_unmap_virtual(&rdev->stollen_vga_memory->tbo);
+
+ if (rdev->r600_blit.shader_obj)
+ ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo);
+}
+
static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
{
int i;
@@ -48,6 +70,10 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
rdev->irq.gui_idle = false;
radeon_irq_set(rdev);
+ mutex_lock(&rdev->vram_mutex);
+
+ radeon_unmap_vram_bos(rdev);
+
if (!static_switch) {
for (i = 0; i < rdev->num_crtc; i++) {
if (rdev->pm.active_crtcs & (1 << i)) {
@@ -67,6 +93,8 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
}
}
}
+
+ mutex_unlock(&rdev->vram_mutex);
/* update display watermarks based on new power state */
radeon_update_bandwidth_info(rdev);