On Nov 28, 2011, at 8:49 PM, alexdeucher@gmail.com wrote:
From: Alex Deucher alexander.deucher@amd.com
Avoid infinite loops waiting for surface updates if a GPU reset happens while waiting for a page flip.
See: https://bugs.freedesktop.org/show_bug.cgi?id=43191
Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@kernel.org Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de
drivers/gpu/drm/radeon/evergreen.c | 7 ++++++- drivers/gpu/drm/radeon/r100.c | 7 ++++++- drivers/gpu/drm/radeon/rs600.c | 7 ++++++- drivers/gpu/drm/radeon/rv770.c | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/ radeon/evergreen.c index 99cdc5d..e78feab 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -84,6 +84,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */ tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
@@ -101,7 +102,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) (u32)crtc_base);
/* Wait for update_pending to go high. */
- while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset)
& EVERGREEN_GRPH_SURFACE_UPDATE_PENDING));
- for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
break;
udelay(1);
} DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside
vblank */ diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/ r100.c index 4e71da0..d7fd5aa 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -187,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
int i;
/* Lock the graphics update lock */ /* update the scanout addresses */ WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
/* Wait for update_pending to go high. */
- while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
- for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
break;
udelay(1);
} DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside
vblank */ diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/ radeon/rs600.c index 8ce17ed..8a52cf0 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */ tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) (u32)crtc_base);
/* Wait for update_pending to go high. */
- while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
- for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
break;
udelay(1);
} DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside
vblank */ diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/ radeon/rv770.c index a9242e6..7bec3f4 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */ tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) (u32)crtc_base);
/* Wait for update_pending to go high. */
- while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
- for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
break;
udelay(1);
} DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside
vblank */
1.7.3.4
Reviewed-by: Mario Kleiner mario.kleiner@tuebingen.mpg.de
********************************************************************* Mario Kleiner Max Planck Institute for Biological Cybernetics Spemannstr. 38 72076 Tuebingen Germany
e-mail: mario.kleiner@tuebingen.mpg.de office: +49 (0)7071/601-1623 fax: +49 (0)7071/601-616 www: http://www.kyb.tuebingen.mpg.de/~kleinerm ********************************************************************* "For a successful technology, reality must take precedence over public relations, for Nature cannot be fooled." (Richard Feynman)