diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-04-29 00:22:43 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-18 04:21:35 -0400 |
commit | 539d24181753e40174746d576d415bfb56131975 (patch) | |
tree | 0aead71d6217f1e58a9a021c4c37131e930b6f6c /drivers/gpu/drm/radeon/radeon_pm.c | |
parent | 68adac5e49436992e9c999fbae879d9ac5b72d4e (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/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 65 |
1 files changed, 37 insertions, 28 deletions
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 | ||
390 | bool radeon_pm_in_vbl(struct radeon_device *rdev) | 390 | bool 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 | ||