summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-01-18 13:05:39 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-01-31 16:24:49 -0500
commit410a3418a88cc1273a281d347687f736fc39dd86 (patch)
tree9057195495a9f1ae1fa128c27b0fdfb09077d224 /drivers/gpu/drm
parent9ff0744c6d7745c331a484a937160f4c2c056923 (diff)
drm/radeon: add a bios scratch asic hung helper
Used by all asic families from r600+. Flag for the vbios and later instances of the driver that the GPU is hung. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c5
-rw-r--r--drivers/gpu/drm/radeon/ni.c5
-rw-r--r--drivers/gpu/drm/radeon/r600.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/si.c5
5 files changed, 33 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index a1e12bf2d0f7..dd1d188376bf 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2433,6 +2433,8 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+ r600_set_bios_scratch_engine_hung(rdev, true);
+
evergreen_mc_stop(rdev, &save);
if (evergreen_mc_wait_for_idle(rdev)) {
dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
@@ -2448,6 +2450,9 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
udelay(50);
evergreen_mc_resume(rdev, &save);
+
+ r600_set_bios_scratch_engine_hung(rdev, false);
+
return 0;
}
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 835992d8d067..af9e86d2fc07 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1422,6 +1422,8 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
if (reset_mask == 0)
return 0;
+ r600_set_bios_scratch_engine_hung(rdev, true);
+
dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
@@ -1448,6 +1450,9 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
udelay(50);
evergreen_mc_resume(rdev, &save);
+
+ r600_set_bios_scratch_engine_hung(rdev, false);
+
return 0;
}
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index becb03e8b32f..a6208178a6f2 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1254,6 +1254,18 @@ void r600_vram_scratch_fini(struct radeon_device *rdev)
radeon_bo_unref(&rdev->vram_scratch.robj);
}
+void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung)
+{
+ u32 tmp = RREG32(R600_BIOS_3_SCRATCH);
+
+ if (hung)
+ tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
+ else
+ tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
+
+ WREG32(R600_BIOS_3_SCRATCH, tmp);
+}
+
/* We doesn't check that the GPU really needs a reset we simply do the
* reset, it's up to the caller to determine if the GPU needs one. We
* might add an helper function to check that.
@@ -1389,6 +1401,8 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+ r600_set_bios_scratch_engine_hung(rdev, true);
+
rv515_mc_stop(rdev, &save);
if (r600_mc_wait_for_idle(rdev)) {
dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
@@ -1404,6 +1418,9 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
mdelay(1);
rv515_mc_resume(rdev, &save);
+
+ r600_set_bios_scratch_engine_hung(rdev, false);
+
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ec3b739ffd79..6539d6cb4bc7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1860,6 +1860,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
/* Common functions */
/* AGP */
extern int radeon_gpu_reset(struct radeon_device *rdev);
+extern void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung);
extern void radeon_agp_disable(struct radeon_device *rdev);
extern int radeon_modeset_init(struct radeon_device *rdev);
extern void radeon_modeset_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index f06072f5e5da..1fc0e5545694 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2231,6 +2231,8 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+ r600_set_bios_scratch_engine_hung(rdev, true);
+
evergreen_mc_stop(rdev, &save);
if (radeon_mc_wait_for_idle(rdev)) {
dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
@@ -2246,6 +2248,9 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
udelay(50);
evergreen_mc_resume(rdev, &save);
+
+ r600_set_bios_scratch_engine_hung(rdev, false);
+
return 0;
}