diff options
author | Alex Deucher | 2013-04-09 17:41:15 -0500 |
---|---|---|
committer | Greg Kroah-Hartman | 2013-05-11 15:54:04 -0500 |
commit | 1ea646f51598f297ca8a68d546a383c003f002ed (patch) | |
tree | f37df9eedb1b3d837455a42741cd05effefbbb63 | |
parent | 6e08af0fb303c97a5bd7be70922110c0a983a1d1 (diff) | |
download | kernel-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.c | 52 |
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 | ||
55 | static 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 | |||
63 | static 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 | */ | ||
55 | void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) | 84 | void 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 | } |