diff mbox

drm/i915: enable rc6 support on Ironlake

Message ID 20101222120015.7f45257f@jbarnes-desktop (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes Dec. 22, 2010, 8 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 232479c..fcaa352 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -161,6 +161,7 @@ 
 #define   MI_MM_SPACE_PHYSICAL		(0<<8)
 #define   MI_SAVE_EXT_STATE_EN		(1<<3)
 #define   MI_RESTORE_EXT_STATE_EN	(1<<2)
+#define   MI_FORCE_RESTORE		(1<<1)
 #define   MI_RESTORE_INHIBIT		(1<<0)
 #define MI_STORE_DWORD_IMM	MI_INSTR(0x20, 1)
 #define   MI_MEM_VIRTUAL	(1 << 22) /* 965+ only */
@@ -1133,12 +1134,49 @@ 
 #define RCUPEI			0x111b0
 #define RCDNEI			0x111b4
 #define MCHBAR_RENDER_STANDBY		0x111b8
-#define   RS1_ENABLE		(1<<31)
-#define   RS2_ENABLE		(1<<30)
-#define   RS3_ENABLE		(1<<29)
-#define   RCX_SW_EXIT		(1<<23)
-#define   RSX_STATUS_MASK	0x00700000
-#define   RC_CSTATE_RS2		(3<<4)
+#define   RS1EN			(1<<31)
+#define   RS2EN			(1<<30)
+#define   RS3EN			(1<<29)
+#define   D3RS3EN		(1<<28) /* Display D3 imlies RS3 */
+#define   SWPROMORSX		(1<<27) /* RSx promotion timers ignored */
+#define   RCWAKERW		(1<<26) /* Resetwarn from PCH causes wakeup */
+#define   DPRSLPVREN		(1<<25) /* Fast voltage ramp enable */
+#define   GFXTGHYST		(1<<24) /* Hysteresis to allow trunk gating */
+#define   RCX_SW_EXIT		(1<<23) /* Leave RSx and prevent re-entry */
+#define   RSX_STATUS_MASK	(7<<23)
+#define   RSX_STATUS_ON		(0<<23)
+#define   RSX_STATUS_RC1	(1<<23)
+#define   RSX_STATUS_RC1E	(2<<23)
+#define   RSX_STATUS_RS1	(3<<23)
+#define   RSX_STATUS_RS2	(4<<23) /* aka rc6 */
+#define   RSX_STATUS_RSVD	(5<<23) /* deep rc6 unsupported on ilk */
+#define   RSX_STATUS_RS3	(6<<23) /* rs3 unsupported on ilk */
+#define   RSX_STATUS_RSVD2	(7<<23)
+#define   UWRCRSXE		(1<<19) /* wake counter limit prevents rsx */
+#define   RSCRP			(1<<18) /* rs requests control on rs1/2 reqs */
+#define   JRSC			(1<<17) /* rsx coupled to cpu c-state */
+#define   RS2INC0		(1<<16) /* allow rs2 in cpu c0 */
+#define   RS1CONTSAV_MASK	(3<<14)
+#define   RS1CONTSAV_NO_RS1	(0<<14) /* rs1 doesn't save/restore context */
+#define   RS1CONTSAV_RSVD	(1<<14)
+#define   RS1CONTSAV_SAVE_RS1	(2<<14) /* rs1 saves context */
+#define   RS1CONTSAV_FULL_RS1	(3<<14) /* rs1 saves and restores context */
+#define   NORMSLEXLAT_MASK	(3<<12)
+#define   SLOW_RS123		(0<<12)
+#define   SLOW_RS23		(1<<12)
+#define   SLOW_RS3		(2<<12)
+#define   NORMAL_RS123		(3<<12)
+#define   RCMODE_TIMEOUT	(1<<11) /* 0 is eval interval method */
+#define   IMPROMOEN		(1<<10) /* promo is immediate or delayed until next idle interval (only for timeout method above) */
+#define   RCENTSYNC		(1<<9) /* rs coupled to cpu c-state (3/6/7) */
+#define   STATELOCK		(1<<7) /* locked to rs_cstate if 0 */
+#define   RS_CSTATE_MASK	(3<<4)
+#define   RS_CSTATE_C367_RS1	(0<<4)
+#define   RS_CSTATE_C36_RS1_C7_RS2 (1<<4)
+#define   RS_CSTATE_RSVD	(2<<4)
+#define   RS_CSTATE_C367_RS2	(3<<4)
+#define   REDSAVES		(1<<3) /* no context save if was idle during rs0 */
+#define   REDRESTORES		(1<<2) /* no restore if was idle during rs0 */
 #define VIDCTL			0x111c0
 #define VIDSTS			0x111c8
 #define VIDSTART		0x111cc /* 8 bits */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3d53e13..ec396c9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6368,22 +6368,11 @@  void intel_enable_clock_gating(struct drm_device *dev)
 		I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
 	}
 
-	if ((IS_GEN4(dev) || IS_GEN5(dev)) && IS_MOBILE(dev)) {
-		if (dev_priv->pwrctx == NULL)
-			dev_priv->pwrctx = intel_alloc_context_page(dev);
-		if (dev_priv->pwrctx) {
-			struct drm_i915_gem_object *obj = dev_priv->pwrctx;
-			I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN);
-			I915_WRITE(MCHBAR_RENDER_STANDBY,
-				   (I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT) | RS1_ENABLE | RS2_ENABLE | RC_CSTATE_RS2);
-		}
-	}
-
 	/*
 	 * GPU can automatically power down the render unit if given a page
 	 * to save state.
 	 */
-	if (IS_IRONLAKE_M(dev)) {
+	if (IS_IRONLAKE_M(dev) && dev_priv->pwrctx) {
 		if (dev_priv->renderctx == NULL)
 			dev_priv->renderctx = intel_alloc_context_page(dev);
 		if (dev_priv->renderctx) {
@@ -6406,6 +6395,38 @@  void intel_enable_clock_gating(struct drm_device *dev)
 				       "Disable RC6\n");
 	}
 
+	if ((IS_GEN4(dev) || IS_GEN5(dev)) && IS_MOBILE(dev)) {
+		if (dev_priv->pwrctx == NULL)
+			dev_priv->pwrctx = intel_alloc_context_page(dev);
+		if (dev_priv->pwrctx) {
+			struct drm_i915_gem_object *obj = dev_priv->pwrctx;
+			u32 rstdby;
+
+			I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN);
+			I915_WRITE(CRSTANDVID, 0x808);
+
+			rstdby = RS1EN | RS2EN | SWPROMORSX | DPRSLPVREN | GFXTGHYST |
+				RS2INC0 | NORMAL_RS123 | STATELOCK;
+			I915_WRITE(MCHBAR_RENDER_STANDBY, rstdby);
+		}
+	}
+
+	if (IS_IRONLAKE_M(dev) && dev_priv->renderctx) {
+		struct drm_i915_gem_object *obj = dev_priv->renderctx;
+
+		BEGIN_LP_RING(6);
+		OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN);
+		OUT_RING(MI_SET_CONTEXT);
+		OUT_RING(MI_SUSPEND_FLUSH);
+		OUT_RING(obj->gtt_offset |
+			 MI_MM_SPACE_GTT |
+			 MI_SAVE_EXT_STATE_EN |
+			 MI_RESTORE_EXT_STATE_EN |
+			 MI_FORCE_RESTORE);
+		OUT_RING(MI_NOOP);
+		OUT_RING(MI_FLUSH);
+		ADVANCE_LP_RING();
+	}
 }
 
 void intel_disable_clock_gating(struct drm_device *dev)