[Intel-gfx] [PATCH] drm/i915: enable rc6 support on Ironlake
Jesse Barnes
jbarnes at virtuousgeek.org
Wed Dec 22 21:00:15 CET 2010
On Tue, 21 Dec 2010 15:11:00 -0800
Jesse Barnes <jbarnes at 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)
More information about the Intel-gfx
mailing list