Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: enable rc6 support on Ironlake
@ 2010-12-21 23:11 Jesse Barnes
  2010-12-22 20:00 ` Jesse Barnes
  0 siblings, 1 reply; 2+ messages in thread
From: Jesse Barnes @ 2010-12-21 23:11 UTC (permalink / raw)
  To: intel-gfx

Doesn't actually work right now, but I did manage to get into rc6 once
and see a lot of power savings (over 1W).
---
 drivers/gpu/drm/i915/i915_reg.h      |    6 ++++++
 drivers/gpu/drm/i915/intel_display.c |   27 +++++++++++++++------------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d60860e..7f93a13 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -145,6 +145,8 @@
 #define   MI_END_SCENE		(1 << 4) /* flush binner and incr scene count */
 #define   MI_INVALIDATE_ISP	(1 << 5) /* invalidate indirect state pointers */
 #define MI_BATCH_BUFFER_END	MI_INSTR(0x0a, 0)
+#define MI_SUSPEND_FLUSH	MI_INSTR(0x0b, 0)
+#define   MI_SUSPEND_FLUSH_EN	(1<<0)
 #define MI_REPORT_HEAD		MI_INSTR(0x07, 0)
 #define MI_OVERLAY_FLIP		MI_INSTR(0x11,0)
 #define   MI_OVERLAY_CONTINUE	(0x0<<21)
@@ -1131,8 +1133,12 @@
 #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 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 8806596..eae18ed 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6368,17 +6368,30 @@ 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) && 0) { /* XXX causes a failure during suspend */
+	if (IS_IRONLAKE_M(dev)) {
 		if (dev_priv->renderctx == NULL)
 			dev_priv->renderctx = intel_alloc_context_page(dev);
 		if (dev_priv->renderctx) {
 			struct drm_i915_gem_object *obj = dev_priv->renderctx;
-			if (BEGIN_LP_RING(4) == 0) {
+			if (BEGIN_LP_RING(6) == 0) {
+				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 |
@@ -6393,16 +6406,6 @@ void intel_enable_clock_gating(struct drm_device *dev)
 				       "Disable RC6\n");
 	}
 
-	if (IS_GEN4(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);
-		}
-	}
 }
 
 void intel_disable_clock_gating(struct drm_device *dev)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] drm/i915: enable rc6 support on Ironlake
  2010-12-21 23:11 [PATCH] drm/i915: enable rc6 support on Ironlake Jesse Barnes
@ 2010-12-22 20:00 ` Jesse Barnes
  0 siblings, 0 replies; 2+ messages in thread
From: Jesse Barnes @ 2010-12-22 20:00 UTC (permalink / raw)
  To: intel-gfx

On Tue, 21 Dec 2010 15:11:00 -0800
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:

> Doesn't actually work right now, but I did manage to get into rc6 once
> and see a lot of power savings (over 1W).
> ---

This one works better (doesn't hang the GPU, I think because I was
missing the CRSTANDVID programming earlier).  However, RSTDBYCTL
indicates that my machine only gets to RC1, or trunk clock gating, so
there's probably more power to be saved.  That said, this patch by
itself seems to save a little power.

-- 
Jesse Barnes, Intel Open Source Technology Center

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)

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-12-22 20:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-21 23:11 [PATCH] drm/i915: enable rc6 support on Ironlake Jesse Barnes
2010-12-22 20:00 ` Jesse Barnes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox