* [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