aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher2013-04-09 17:32:01 -0500
committerGreg Kroah-Hartman2013-05-11 15:54:05 -0500
commitf404959ea072d99e46557bd197ff7b01d3ec718d (patch)
treef42d85cdf350d187ed7ad39932f8f9473dedf24b
parentb38b76076dc96dc76b85e57e116867ee4dc62432 (diff)
downloadkernel-omap-f404959ea072d99e46557bd197ff7b01d3ec718d.tar.gz
kernel-omap-f404959ea072d99e46557bd197ff7b01d3ec718d.tar.xz
kernel-omap-f404959ea072d99e46557bd197ff7b01d3ec718d.zip
drm/radeon: update wait_for_vblank for r1xx-r4xx
commit 2b48b968c0d00aa5ab520b65a15a4f374cda7dda 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/r100.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8ff7cac222dc..62719ecfef63 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -69,6 +69,38 @@ MODULE_FIRMWARE(FIRMWARE_R520);
69 * and others in some cases. 69 * and others in some cases.
70 */ 70 */
71 71
72static bool r100_is_in_vblank(struct radeon_device *rdev, int crtc)
73{
74 if (crtc == 0) {
75 if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
76 return true;
77 else
78 return false;
79 } else {
80 if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
81 return true;
82 else
83 return false;
84 }
85}
86
87static bool r100_is_counter_moving(struct radeon_device *rdev, int crtc)
88{
89 u32 vline1, vline2;
90
91 if (crtc == 0) {
92 vline1 = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
93 vline2 = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
94 } else {
95 vline1 = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
96 vline2 = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
97 }
98 if (vline1 != vline2)
99 return true;
100 else
101 return false;
102}
103
72/** 104/**
73 * r100_wait_for_vblank - vblank wait asic callback. 105 * r100_wait_for_vblank - vblank wait asic callback.
74 * 106 *
@@ -79,36 +111,33 @@ MODULE_FIRMWARE(FIRMWARE_R520);
79 */ 111 */
80void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) 112void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
81{ 113{
82 int i; 114 unsigned i = 0;
83 115
84 if (crtc >= rdev->num_crtc) 116 if (crtc >= rdev->num_crtc)
85 return; 117 return;
86 118
87 if (crtc == 0) { 119 if (crtc == 0) {
88 if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) { 120 if (!(RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN))
89 for (i = 0; i < rdev->usec_timeout; i++) { 121 return;
90 if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR))
91 break;
92 udelay(1);
93 }
94 for (i = 0; i < rdev->usec_timeout; i++) {
95 if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
96 break;
97 udelay(1);
98 }
99 }
100 } else { 122 } else {
101 if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN) { 123 if (!(RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN))
102 for (i = 0; i < rdev->usec_timeout; i++) { 124 return;
103 if (!(RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)) 125 }
104 break; 126
105 udelay(1); 127 /* depending on when we hit vblank, we may be close to active; if so,
106 } 128 * wait for another frame.
107 for (i = 0; i < rdev->usec_timeout; i++) { 129 */
108 if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR) 130 while (r100_is_in_vblank(rdev, crtc)) {
109 break; 131 if (i++ % 100 == 0) {
110 udelay(1); 132 if (!r100_is_counter_moving(rdev, crtc))
111 } 133 break;
134 }
135 }
136
137 while (!r100_is_in_vblank(rdev, crtc)) {
138 if (i++ % 100 == 0) {
139 if (!r100_is_counter_moving(rdev, crtc))
140 break;
112 } 141 }
113 } 142 }
114} 143}