aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-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 9db58530be37..4973bff37fec 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}