Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
[pandora-kernel.git] / drivers / gpu / drm / radeon / radeon_pm.c
index f87efec..8c9b2ef 100644 (file)
@@ -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;
 }