Explorar el Código

[rfc] drm/radeon/kms: pm debugging check for vbl.

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.
Dave Airlie hace 15 años
padre
commit
f735261baa
Se han modificado 2 ficheros con 29 adiciones y 0 borrados
  1. 2 0
      drivers/gpu/drm/radeon/avivod.h
  2. 27 0
      drivers/gpu/drm/radeon/radeon_pm.c

+ 2 - 0
drivers/gpu/drm/radeon/avivod.h

@@ -30,11 +30,13 @@
 
 #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

+ 27 - 0
drivers/gpu/drm/radeon/radeon_pm.c

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