From f1eb57613a5eed15a1511d088a9e06ad5ee83572 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 5 Nov 2012 09:25:10 -0500 Subject: [PATCH] drm/radeon: adjust dce4_wait_for_vblank() May fix: https://bugs.freedesktop.org/show_bug.cgi?id=56139 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/evergreen.c | 43 +++++++++++++++++++++++++------ drivers/gpu/drm/radeon/evergreen_reg.h | 2 + 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 200021b..75f08bb 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -191,6 +191,29 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) } } +static bool dce4_in_vblank(struct radeon_device *rdev, int crtc) +{ + if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) + return true; + else + return false; +} + +static bool dce4_counter_moving(struct radeon_device *rdev, int crtc) +{ + u32 current_status1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]); + u32 current_status2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]); + u32 hc1 = current_status1 & EVERGREEN_CRTC_HORZ_COUNT_MASK; + u32 vc1 = current_status1 & EVERGREEN_CRTC_VERT_COUNT_MASK; + u32 hc2 = current_status2 & EVERGREEN_CRTC_HORZ_COUNT_MASK; + u32 vc2 = current_status2 & EVERGREEN_CRTC_VERT_COUNT_MASK; + + if ((hc1 != hc2) || (vc1 != vc2)) + return true; + else + return false; +} + /** * dce4_wait_for_vblank - vblank wait asic callback. * @@ -201,21 +224,23 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) */ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) { - int i; + unsigned i = 0; if (crtc >= rdev->num_crtc) return; if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) { - for (i = 0; i < rdev->usec_timeout; i++) { - if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)) - break; - udelay(1); + while (dce4_in_vblank(rdev, crtc)) { + if ((i++ % 100) == 0) { + if (!dce4_counter_moving(rdev, crtc)) + break; + } } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) - break; - udelay(1); + while (!dce4_in_vblank(rdev, crtc)) { + if ((i++ % 100) == 0) { + if (!dce4_counter_moving(rdev, crtc)) + break; + } } } } diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 9630d06..2a40fc5 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -230,6 +230,8 @@ #define EVERGREEN_CRTC_STATUS 0x6e8c # define EVERGREEN_CRTC_V_BLANK (1 << 0) #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 +# define EVERGREEN_CRTC_VERT_COUNT_MASK 0x00001fff +# define EVERGREEN_CRTC_HORZ_COUNT_MASK 0x1fff0000 #define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 -- 1.7.7.5