[rfc] drm/radeon/kms: pm debugging check for vbl.
authorDave Airlie <airlied@redhat.com>
Thu, 18 Feb 2010 05:58:36 +0000 (15:58 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 22 Feb 2010 23:46:21 +0000 (09:46 +1000)
This patch adds a check on avivo chips to see if we are in the VBL
region for the active crtcs when we trigger the engine change.

I appear to have glitches locally on pm transistion (not sure all
fixes are in yet) and this at least seems to be correct here,
maybe others can test on systems with no glitches.

drivers/gpu/drm/radeon/avivod.h
drivers/gpu/drm/radeon/radeon_pm.c

index d4e6e6e4a93888a14a738dd3484279d4f5e28d9c..3c391e7e9fd41ef2834a668b73afcf8d119a9dff 100644 (file)
 
 #define        D1CRTC_CONTROL                                  0x6080
 #define                CRTC_EN                                         (1 << 0)
+#define        D1CRTC_STATUS                                   0x609c
 #define        D1CRTC_UPDATE_LOCK                              0x60E8
 #define        D1GRPH_PRIMARY_SURFACE_ADDRESS                  0x6110
 #define        D1GRPH_SECONDARY_SURFACE_ADDRESS                0x6118
 
 #define        D2CRTC_CONTROL                                  0x6880
+#define        D2CRTC_STATUS                                   0x689c
 #define        D2CRTC_UPDATE_LOCK                              0x68E8
 #define        D2GRPH_PRIMARY_SURFACE_ADDRESS                  0x6910
 #define        D2GRPH_SECONDARY_SURFACE_ADDRESS                0x6918
index f0234351fd572d010cf851c82d0acd6eac3ec39e..6dbfdf48a5f522a9e4080969c5ea33d63235e8f3 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "avivod.h"
 
 #define RADEON_IDLE_LOOP_MS 100
 #define RADEON_RECLOCK_DELAY_MS 200
@@ -283,6 +284,28 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
        mutex_unlock(&rdev->pm.mutex);
 }
 
+static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish)
+{
+       u32 stat_crtc1 = 0, stat_crtc2 = 0;
+       bool in_vbl = true;
+
+       if (ASIC_IS_AVIVO(rdev)) {
+               if (rdev->pm.active_crtcs & (1 << 0)) {
+                       stat_crtc1 = RREG32(D1CRTC_STATUS);
+                       if (!(stat_crtc1 & 1))
+                               in_vbl = false;
+               }
+               if (rdev->pm.active_crtcs & (1 << 1)) {
+                       stat_crtc2 = RREG32(D2CRTC_STATUS);
+                       if (!(stat_crtc2 & 1))
+                               in_vbl = false;
+               }
+       }
+       if (in_vbl == false)
+               DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1,
+                        stat_crtc2, finish ? "exit" : "entry");
+       return in_vbl;
+}
 static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)
 {
        /*radeon_fence_wait_last(rdev);*/
@@ -299,7 +322,11 @@ static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)
                DRM_ERROR("%s: PM_ACTION_NONE\n", __func__);
                break;
        }
+
+       /* check if we are in vblank */
+       radeon_pm_debug_check_in_vbl(rdev, false);
        radeon_set_power_state(rdev);
+       radeon_pm_debug_check_in_vbl(rdev, true);
        rdev->pm.planned_action = PM_ACTION_NONE;
 }