|
@@ -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;
|
|
|
}
|
|
|
|