diff options
author | Mario Kleiner <mario.kleiner@tuebingen.mpg.de> | 2010-10-05 19:57:37 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-10-06 11:46:28 +1000 |
commit | 75fa0b08e50cb72715b58321e8259c47adfe4c6f (patch) | |
tree | e6453e0bb36903e1574bcdd331539bf8b3c2092c | |
parent | 6383cf7d7839bf52aa4efa20cc921773126797f4 (diff) |
drm/radeon: Modify radeon_pm_in_vbl to use radeon_get_crtc_scanoutpos()
radeon_pm_in_vbl() didn't report in vblank status accurately. Make
it a wrapper around radeon_get_crtc_scanoutpos() which corrects for
biases, so it reports accurately.
radeon_pm_in_vbl() will only report in_vbl if all active crtc's
are currently inside vblank.
agd5f: use rdev->num_crtc rather than hardcoding the crtc count
Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 70 |
1 files changed, 9 insertions, 61 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f87efec7623..8c9b2ef32c6 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -712,73 +712,21 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) static bool radeon_pm_in_vbl(struct radeon_device *rdev) { - u32 stat_crtc = 0, vbl = 0, position = 0; + int crtc, vpos, hpos, vbl_status; bool in_vbl = true; - if (ASIC_IS_DCE4(rdev)) { - if (rdev->pm.active_crtcs & (1 << 0)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 1)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 2)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 3)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 4)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 5)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; - } - } else if (ASIC_IS_AVIVO(rdev)) { - if (rdev->pm.active_crtcs & (1 << 0)) { - vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff; - position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 1)) { - vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff; - position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff; - } - if (position < vbl && position > 1) - in_vbl = false; - } else { - if (rdev->pm.active_crtcs & (1 << 0)) { - stat_crtc = RREG32(RADEON_CRTC_STATUS); - if (!(stat_crtc & 1)) - in_vbl = false; - } - if (rdev->pm.active_crtcs & (1 << 1)) { - stat_crtc = RREG32(RADEON_CRTC2_STATUS); - if (!(stat_crtc & 1)) + /* Iterate over all active crtc's. All crtc's must be in vblank, + * otherwise return in_vbl == false. + */ + for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { + if (rdev->pm.active_crtcs & (1 << crtc)) { + vbl_status = radeon_get_crtc_scanoutpos(rdev, crtc, &vpos, &hpos); + if ((vbl_status & RADEON_SCANOUTPOS_VALID) && + !(vbl_status & RADEON_SCANOUTPOS_INVBL)) in_vbl = false; } } - if (position < vbl && position > 1) - in_vbl = false; - return in_vbl; } |