summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/r100.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-09-09 20:23:45 (GMT)
committerDave Airlie <airlied@redhat.com>2009-09-10 00:12:41 (GMT)
commit45600232b3dbb97817c9e15de848c742901893e1 (patch)
treedc8953d21cfc3d48faedcabef87e62dee3242ee1 /drivers/gpu/drm/radeon/r100.c
parent5d93b135fc051be3740cbe55729fc7b86a7069d7 (diff)
downloadlinux-45600232b3dbb97817c9e15de848c742901893e1.tar.xz
drm/radeon/kms: wait for cp idle before stopping it.
If we stop CP and that it's still processing thing GPU hang might happen, this patch wait for CP idle (the wait can timeout) so we can avoid shutting down CP at bad time. This is especialy usefull when reseting the GPU as it seems GPU reset fails to properly reset CP when the CP wasn't stop after being idle. Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r--drivers/gpu/drm/radeon/r100.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 5708c07..938a693 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -487,6 +487,21 @@ int r100_copy_blit(struct radeon_device *rdev,
/*
* CP
*/
+static int r100_cp_wait_for_idle(struct radeon_device *rdev)
+{
+ unsigned i;
+ u32 tmp;
+
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ tmp = RREG32(R_000E40_RBBM_STATUS);
+ if (!G_000E40_CP_CMDSTRM_BUSY(tmp)) {
+ return 0;
+ }
+ udelay(1);
+ }
+ return -1;
+}
+
void r100_ring_start(struct radeon_device *rdev)
{
int r;
@@ -715,6 +730,9 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
void r100_cp_fini(struct radeon_device *rdev)
{
+ if (r100_cp_wait_for_idle(rdev)) {
+ DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n");
+ }
/* Disable ring */
rdev->cp.ready = false;
WREG32(RADEON_CP_CSQ_CNTL, 0);