aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher2013-04-09 17:41:15 -0500
committerGreg Kroah-Hartman2013-05-11 15:54:04 -0500
commit1ea646f51598f297ca8a68d546a383c003f002ed (patch)
treef37df9eedb1b3d837455a42741cd05effefbbb63
parent6e08af0fb303c97a5bd7be70922110c0a983a1d1 (diff)
downloadkernel-omap-1ea646f51598f297ca8a68d546a383c003f002ed.tar.gz
kernel-omap-1ea646f51598f297ca8a68d546a383c003f002ed.tar.xz
kernel-omap-1ea646f51598f297ca8a68d546a383c003f002ed.zip
drm/radeon: update wait_for_vblank for r5xx-r7xx
commit bea5497bfc1067620c8c8e9d37a42e0bb6d7d7fa upstream. Properly wait for the next vblank region. The previous code didn't always wait long enough depending on the timing. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/radeon/rs600.c52
1 files changed, 44 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 5a0fc74c2ba6..46fa1b07c560 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -52,23 +52,59 @@ static const u32 crtc_offsets[2] =
52 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL 52 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
53}; 53};
54 54
55static bool avivo_is_in_vblank(struct radeon_device *rdev, int crtc)
56{
57 if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)
58 return true;
59 else
60 return false;
61}
62
63static bool avivo_is_counter_moving(struct radeon_device *rdev, int crtc)
64{
65 u32 pos1, pos2;
66
67 pos1 = RREG32(AVIVO_D1CRTC_STATUS_POSITION + crtc_offsets[crtc]);
68 pos2 = RREG32(AVIVO_D1CRTC_STATUS_POSITION + crtc_offsets[crtc]);
69
70 if (pos1 != pos2)
71 return true;
72 else
73 return false;
74}
75
76/**
77 * avivo_wait_for_vblank - vblank wait asic callback.
78 *
79 * @rdev: radeon_device pointer
80 * @crtc: crtc to wait for vblank on
81 *
82 * Wait for vblank on the requested crtc (r5xx-r7xx).
83 */
55void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) 84void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
56{ 85{
57 int i; 86 unsigned i = 0;
58 87
59 if (crtc >= rdev->num_crtc) 88 if (crtc >= rdev->num_crtc)
60 return; 89 return;
61 90
62 if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) { 91 if (!(RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN))
63 for (i = 0; i < rdev->usec_timeout; i++) { 92 return;
64 if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)) 93
94 /* depending on when we hit vblank, we may be close to active; if so,
95 * wait for another frame.
96 */
97 while (avivo_is_in_vblank(rdev, crtc)) {
98 if (i++ % 100 == 0) {
99 if (!avivo_is_counter_moving(rdev, crtc))
65 break; 100 break;
66 udelay(1);
67 } 101 }
68 for (i = 0; i < rdev->usec_timeout; i++) { 102 }
69 if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK) 103
104 while (!avivo_is_in_vblank(rdev, crtc)) {
105 if (i++ % 100 == 0) {
106 if (!avivo_is_counter_moving(rdev, crtc))
70 break; 107 break;
71 udelay(1);
72 } 108 }
73 } 109 }
74} 110}