aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher2013-04-09 17:49:59 -0500
committerGreg Kroah-Hartman2013-05-11 15:54:04 -0500
commit415c4bfb8b5e2a6bdc98f1038d87d2f6393bb216 (patch)
tree561805b0aab450ea7a1efc230fb4755c0171a965
parent1ea646f51598f297ca8a68d546a383c003f002ed (diff)
downloadkernel-omap-415c4bfb8b5e2a6bdc98f1038d87d2f6393bb216.tar.gz
kernel-omap-415c4bfb8b5e2a6bdc98f1038d87d2f6393bb216.tar.xz
kernel-omap-415c4bfb8b5e2a6bdc98f1038d87d2f6393bb216.zip
drm/radeon: update wait_for_vblank for evergreen+
commit 10257a6d8359c41407eb26b7ad7bf710a7e00155 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/evergreen.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 1b0a4eca922a..4157c33516af 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -105,6 +105,27 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
105 } 105 }
106} 106}
107 107
108static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc)
109{
110 if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
111 return true;
112 else
113 return false;
114}
115
116static bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc)
117{
118 u32 pos1, pos2;
119
120 pos1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
121 pos2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
122
123 if (pos1 != pos2)
124 return true;
125 else
126 return false;
127}
128
108/** 129/**
109 * dce4_wait_for_vblank - vblank wait asic callback. 130 * dce4_wait_for_vblank - vblank wait asic callback.
110 * 131 *
@@ -115,21 +136,28 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
115 */ 136 */
116void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) 137void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
117{ 138{
118 int i; 139 unsigned i = 0;
119 140
120 if (crtc >= rdev->num_crtc) 141 if (crtc >= rdev->num_crtc)
121 return; 142 return;
122 143
123 if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) { 144 if (!(RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN))
124 for (i = 0; i < rdev->usec_timeout; i++) { 145 return;
125 if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)) 146
147 /* depending on when we hit vblank, we may be close to active; if so,
148 * wait for another frame.
149 */
150 while (dce4_is_in_vblank(rdev, crtc)) {
151 if (i++ % 100 == 0) {
152 if (!dce4_is_counter_moving(rdev, crtc))
126 break; 153 break;
127 udelay(1);
128 } 154 }
129 for (i = 0; i < rdev->usec_timeout; i++) { 155 }
130 if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) 156
157 while (!dce4_is_in_vblank(rdev, crtc)) {
158 if (i++ % 100 == 0) {
159 if (!dce4_is_counter_moving(rdev, crtc))
131 break; 160 break;
132 udelay(1);
133 } 161 }
134 } 162 }
135} 163}