diff options
author | Alex Deucher | 2013-04-09 17:49:59 -0500 |
---|---|---|
committer | Greg Kroah-Hartman | 2013-05-11 15:54:04 -0500 |
commit | 415c4bfb8b5e2a6bdc98f1038d87d2f6393bb216 (patch) | |
tree | 561805b0aab450ea7a1efc230fb4755c0171a965 | |
parent | 1ea646f51598f297ca8a68d546a383c003f002ed (diff) | |
download | kernel-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.c | 44 |
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 | ||
108 | static 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 | |||
116 | static 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 | */ |
116 | void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) | 137 | void 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 | } |