aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-04-29 00:22:43 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 04:21:35 -0400
commit539d24181753e40174746d576d415bfb56131975 (patch)
tree0aead71d6217f1e58a9a021c4c37131e930b6f6c /drivers
parent68adac5e49436992e9c999fbae879d9ac5b72d4e (diff)
drm/radeon/kms: more pm fixes
- disable gui idle interrupt use Seems to hang some r5xx chips - move vbl range check into existing vbl check function in radeon_pm.c - disable crtc mc acccess for the whole reclocking process Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h2
-rw-r--r--drivers/gpu/drm/radeon/r100.c6
-rw-r--r--drivers/gpu/drm/radeon/r600.c35
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c65
4 files changed, 45 insertions, 63 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 93aab2ebd9d0..af86af836f13 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -164,10 +164,12 @@
164#define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) 164#define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0)
165 165
166/* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ 166/* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */
167#define EVERGREEN_CRTC_V_BLANK_START_END 0x6e34
167#define EVERGREEN_CRTC_CONTROL 0x6e70 168#define EVERGREEN_CRTC_CONTROL 0x6e70
168# define EVERGREEN_CRTC_MASTER_EN (1 << 0) 169# define EVERGREEN_CRTC_MASTER_EN (1 << 0)
169# define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) 170# define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
170#define EVERGREEN_CRTC_STATUS 0x6e8c 171#define EVERGREEN_CRTC_STATUS 0x6e8c
172#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90
171#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 173#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4
172 174
173#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 175#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index a5f11c300f6a..493b9b48da30 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -178,14 +178,12 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
178 rdev->pm.current_sclk = sclk; 178 rdev->pm.current_sclk = sclk;
179 DRM_INFO("Setting: e: %d\n", sclk); 179 DRM_INFO("Setting: e: %d\n", sclk);
180 } 180 }
181#if 0
182 /* set memory clock */ 181 /* set memory clock */
183 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 182 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
184 radeon_set_memory_clock(rdev, mclk); 183 radeon_set_memory_clock(rdev, mclk);
185 rdev->pm.current_mclk = mclk; 184 rdev->pm.current_mclk = mclk;
186 DRM_INFO("Setting: m: %d\n", mclk); 185 DRM_INFO("Setting: m: %d\n", mclk);
187 } 186 }
188#endif
189 radeon_pm_finish(rdev); 187 radeon_pm_finish(rdev);
190 } else { 188 } else {
191 radeon_sync_with_vblank(rdev); 189 radeon_sync_with_vblank(rdev);
@@ -193,6 +191,7 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
193 if (!radeon_pm_in_vbl(rdev)) 191 if (!radeon_pm_in_vbl(rdev))
194 return; 192 return;
195 193
194 radeon_pm_prepare(rdev);
196 /* set engine clock */ 195 /* set engine clock */
197 if (sclk != rdev->pm.current_sclk) { 196 if (sclk != rdev->pm.current_sclk) {
198 radeon_pm_debug_check_in_vbl(rdev, false); 197 radeon_pm_debug_check_in_vbl(rdev, false);
@@ -205,13 +204,12 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
205 /* set memory clock */ 204 /* set memory clock */
206 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 205 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
207 radeon_pm_debug_check_in_vbl(rdev, false); 206 radeon_pm_debug_check_in_vbl(rdev, false);
208 radeon_pm_prepare(rdev);
209 radeon_set_memory_clock(rdev, mclk); 207 radeon_set_memory_clock(rdev, mclk);
210 radeon_pm_finish(rdev);
211 radeon_pm_debug_check_in_vbl(rdev, true); 208 radeon_pm_debug_check_in_vbl(rdev, true);
212 rdev->pm.current_mclk = mclk; 209 rdev->pm.current_mclk = mclk;
213 DRM_INFO("Setting: m: %d\n", mclk); 210 DRM_INFO("Setting: m: %d\n", mclk);
214 } 211 }
212 radeon_pm_finish(rdev);
215 } 213 }
216 214
217 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; 215 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index d3a79e0a9125..75c825cb8790 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -256,7 +256,6 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch)
256 return; 256 return;
257 257
258 if (radeon_gui_idle(rdev)) { 258 if (radeon_gui_idle(rdev)) {
259
260 sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. 259 sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
261 clock_info[rdev->pm.requested_clock_mode_index].sclk; 260 clock_info[rdev->pm.requested_clock_mode_index].sclk;
262 if (sclk > rdev->clock.default_sclk) 261 if (sclk > rdev->clock.default_sclk)
@@ -271,52 +270,27 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch)
271 radeon_pm_misc(rdev); 270 radeon_pm_misc(rdev);
272 271
273 if (static_switch) { 272 if (static_switch) {
274 273 radeon_pm_prepare(rdev);
275 /* set engine clock */ 274 /* set engine clock */
276 if (sclk != rdev->pm.current_sclk) { 275 if (sclk != rdev->pm.current_sclk) {
277 radeon_set_engine_clock(rdev, sclk); 276 radeon_set_engine_clock(rdev, sclk);
278 rdev->pm.current_sclk = sclk; 277 rdev->pm.current_sclk = sclk;
279 DRM_INFO("Setting: e: %d\n", sclk); 278 DRM_INFO("Setting: e: %d\n", sclk);
280 } 279 }
281
282 /* set memory clock */ 280 /* set memory clock */
283 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 281 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
284 radeon_pm_prepare(rdev);
285 radeon_set_memory_clock(rdev, mclk); 282 radeon_set_memory_clock(rdev, mclk);
286 radeon_pm_finish(rdev);
287 rdev->pm.current_mclk = mclk; 283 rdev->pm.current_mclk = mclk;
288 DRM_INFO("Setting: m: %d\n", mclk); 284 DRM_INFO("Setting: m: %d\n", mclk);
289 } 285 }
290 286 radeon_pm_finish(rdev);
291 } else { 287 } else {
292 u32 position;
293 u32 vbl;
294
295 radeon_sync_with_vblank(rdev); 288 radeon_sync_with_vblank(rdev);
296 289
297 if (!radeon_pm_in_vbl(rdev)) 290 if (!radeon_pm_in_vbl(rdev))
298 return; 291 return;
299 292
300 if (rdev->pm.active_crtcs & (1 << 0)) { 293 radeon_pm_prepare(rdev);
301 vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END);
302 position = RREG32(AVIVO_D1CRTC_STATUS_POSITION);
303 position &= 0xfff;
304 vbl &= 0xfff;
305
306 if (position < vbl && position > 1)
307 return;
308 }
309
310 if (rdev->pm.active_crtcs & (1 << 1)) {
311 vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END);
312 position = RREG32(AVIVO_D2CRTC_STATUS_POSITION);
313 position &= 0xfff;
314 vbl &= 0xfff;
315
316 if (position < vbl && position > 1)
317 return;
318 }
319
320 if (sclk != rdev->pm.current_sclk) { 294 if (sclk != rdev->pm.current_sclk) {
321 radeon_pm_debug_check_in_vbl(rdev, false); 295 radeon_pm_debug_check_in_vbl(rdev, false);
322 radeon_set_engine_clock(rdev, sclk); 296 radeon_set_engine_clock(rdev, sclk);
@@ -328,13 +302,12 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch)
328 /* set memory clock */ 302 /* set memory clock */
329 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 303 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
330 radeon_pm_debug_check_in_vbl(rdev, false); 304 radeon_pm_debug_check_in_vbl(rdev, false);
331 radeon_pm_prepare(rdev);
332 radeon_set_memory_clock(rdev, mclk); 305 radeon_set_memory_clock(rdev, mclk);
333 radeon_pm_finish(rdev);
334 radeon_pm_debug_check_in_vbl(rdev, true); 306 radeon_pm_debug_check_in_vbl(rdev, true);
335 rdev->pm.current_mclk = mclk; 307 rdev->pm.current_mclk = mclk;
336 DRM_INFO("Setting: m: %d\n", mclk); 308 DRM_INFO("Setting: m: %d\n", mclk);
337 } 309 }
310 radeon_pm_finish(rdev);
338 } 311 }
339 312
340 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; 313 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 88163e043fcf..2eb675e78440 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -64,7 +64,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
64 mutex_lock(&rdev->ddev->struct_mutex); 64 mutex_lock(&rdev->ddev->struct_mutex);
65 mutex_lock(&rdev->vram_mutex); 65 mutex_lock(&rdev->vram_mutex);
66 mutex_lock(&rdev->cp.mutex); 66 mutex_lock(&rdev->cp.mutex);
67 67#if 0
68 /* wait for GPU idle */ 68 /* wait for GPU idle */
69 rdev->pm.gui_idle = false; 69 rdev->pm.gui_idle = false;
70 rdev->irq.gui_idle = true; 70 rdev->irq.gui_idle = true;
@@ -74,7 +74,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
74 msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); 74 msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT));
75 rdev->irq.gui_idle = false; 75 rdev->irq.gui_idle = false;
76 radeon_irq_set(rdev); 76 radeon_irq_set(rdev);
77 77#endif
78 radeon_unmap_vram_bos(rdev); 78 radeon_unmap_vram_bos(rdev);
79 79
80 if (!static_switch) { 80 if (!static_switch) {
@@ -85,7 +85,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
85 } 85 }
86 } 86 }
87 } 87 }
88 88
89 radeon_set_power_state(rdev, static_switch); 89 radeon_set_power_state(rdev, static_switch);
90 90
91 if (!static_switch) { 91 if (!static_switch) {
@@ -389,51 +389,57 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
389 389
390bool radeon_pm_in_vbl(struct radeon_device *rdev) 390bool radeon_pm_in_vbl(struct radeon_device *rdev)
391{ 391{
392 u32 stat_crtc = 0; 392 u32 stat_crtc = 0, vbl = 0, position = 0;
393 bool in_vbl = true; 393 bool in_vbl = true;
394 394
395 if (ASIC_IS_DCE4(rdev)) { 395 if (ASIC_IS_DCE4(rdev)) {
396 if (rdev->pm.active_crtcs & (1 << 0)) { 396 if (rdev->pm.active_crtcs & (1 << 0)) {
397 stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); 397 vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
398 if (!(stat_crtc & 1)) 398 EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff;
399 in_vbl = false; 399 position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
400 EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff;
400 } 401 }
401 if (rdev->pm.active_crtcs & (1 << 1)) { 402 if (rdev->pm.active_crtcs & (1 << 1)) {
402 stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); 403 vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
403 if (!(stat_crtc & 1)) 404 EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff;
404 in_vbl = false; 405 position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
406 EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff;
405 } 407 }
406 if (rdev->pm.active_crtcs & (1 << 2)) { 408 if (rdev->pm.active_crtcs & (1 << 2)) {
407 stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); 409 vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
408 if (!(stat_crtc & 1)) 410 EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff;
409 in_vbl = false; 411 position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
412 EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff;
410 } 413 }
411 if (rdev->pm.active_crtcs & (1 << 3)) { 414 if (rdev->pm.active_crtcs & (1 << 3)) {
412 stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); 415 vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
413 if (!(stat_crtc & 1)) 416 EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff;
414 in_vbl = false; 417 position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
418 EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff;
415 } 419 }
416 if (rdev->pm.active_crtcs & (1 << 4)) { 420 if (rdev->pm.active_crtcs & (1 << 4)) {
417 stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); 421 vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
418 if (!(stat_crtc & 1)) 422 EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff;
419 in_vbl = false; 423 position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
424 EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff;
420 } 425 }
421 if (rdev->pm.active_crtcs & (1 << 5)) { 426 if (rdev->pm.active_crtcs & (1 << 5)) {
422 stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); 427 vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
423 if (!(stat_crtc & 1)) 428 EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff;
424 in_vbl = false; 429 position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
430 EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff;
425 } 431 }
426 } else if (ASIC_IS_AVIVO(rdev)) { 432 } else if (ASIC_IS_AVIVO(rdev)) {
427 if (rdev->pm.active_crtcs & (1 << 0)) { 433 if (rdev->pm.active_crtcs & (1 << 0)) {
428 stat_crtc = RREG32(D1CRTC_STATUS); 434 vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff;
429 if (!(stat_crtc & 1)) 435 position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff;
430 in_vbl = false;
431 } 436 }
432 if (rdev->pm.active_crtcs & (1 << 1)) { 437 if (rdev->pm.active_crtcs & (1 << 1)) {
433 stat_crtc = RREG32(D2CRTC_STATUS); 438 vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff;
434 if (!(stat_crtc & 1)) 439 position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff;
435 in_vbl = false;
436 } 440 }
441 if (position < vbl && position > 1)
442 in_vbl = false;
437 } else { 443 } else {
438 if (rdev->pm.active_crtcs & (1 << 0)) { 444 if (rdev->pm.active_crtcs & (1 << 0)) {
439 stat_crtc = RREG32(RADEON_CRTC_STATUS); 445 stat_crtc = RREG32(RADEON_CRTC_STATUS);
@@ -447,6 +453,9 @@ bool radeon_pm_in_vbl(struct radeon_device *rdev)
447 } 453 }
448 } 454 }
449 455
456 if (position < vbl && position > 1)
457 in_vbl = false;
458
450 return in_vbl; 459 return in_vbl;
451} 460}
452 461