aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-01-05 15:01:24 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-01-11 15:43:58 -0500
commit88271da3f3da75d6eaef5e768c82a1627edf7088 (patch)
treebe417b97f6252786dd0366592d05d1fc0cb8a939 /drivers/gpu/drm
parent0dc79fb2a36efcadbb39bd8b28933d8aa40408b1 (diff)
drm/i915: re-enable rc6 support for Ironlake+
Re-enable rc6 support on Ironlake for power savings. Adds a debugfs file to check current RC state, adds a missing workaround for Ironlake MI_SET_CONTEXT instructions, and renames MCHBAR_RENDER_STANDBY to RSTDBYCTL to match the docs. Keep RC6 and the power context disabled on pre-ILK. It only seems to hang and doesn't save any power. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c26
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h50
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c32
4 files changed, 91 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 7243d6418651..9c4cdc143be9 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -896,7 +896,7 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
896 struct drm_device *dev = node->minor->dev; 896 struct drm_device *dev = node->minor->dev;
897 drm_i915_private_t *dev_priv = dev->dev_private; 897 drm_i915_private_t *dev_priv = dev->dev_private;
898 u32 rgvmodectl = I915_READ(MEMMODECTL); 898 u32 rgvmodectl = I915_READ(MEMMODECTL);
899 u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY); 899 u32 rstdbyctl = I915_READ(RSTDBYCTL);
900 u16 crstandvid = I915_READ16(CRSTANDVID); 900 u16 crstandvid = I915_READ16(CRSTANDVID);
901 901
902 seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? 902 seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
@@ -919,6 +919,30 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
919 seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); 919 seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f));
920 seq_printf(m, "Render standby enabled: %s\n", 920 seq_printf(m, "Render standby enabled: %s\n",
921 (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); 921 (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes");
922 seq_printf(m, "Current RS state: ");
923 switch (rstdbyctl & RSX_STATUS_MASK) {
924 case RSX_STATUS_ON:
925 seq_printf(m, "on\n");
926 break;
927 case RSX_STATUS_RC1:
928 seq_printf(m, "RC1\n");
929 break;
930 case RSX_STATUS_RC1E:
931 seq_printf(m, "RC1E\n");
932 break;
933 case RSX_STATUS_RS1:
934 seq_printf(m, "RS1\n");
935 break;
936 case RSX_STATUS_RS2:
937 seq_printf(m, "RS2 (RC6)\n");
938 break;
939 case RSX_STATUS_RS3:
940 seq_printf(m, "RC3 (RC6+)\n");
941 break;
942 default:
943 seq_printf(m, "unknown\n");
944 break;
945 }
922 946
923 return 0; 947 return 0;
924} 948}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b0ab4247ce48..33ddf3120f2f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -145,6 +145,8 @@
145#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ 145#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
146#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ 146#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */
147#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) 147#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
148#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0)
149#define MI_SUSPEND_FLUSH_EN (1<<0)
148#define MI_REPORT_HEAD MI_INSTR(0x07, 0) 150#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
149#define MI_OVERLAY_FLIP MI_INSTR(0x11,0) 151#define MI_OVERLAY_FLIP MI_INSTR(0x11,0)
150#define MI_OVERLAY_CONTINUE (0x0<<21) 152#define MI_OVERLAY_CONTINUE (0x0<<21)
@@ -159,6 +161,7 @@
159#define MI_MM_SPACE_PHYSICAL (0<<8) 161#define MI_MM_SPACE_PHYSICAL (0<<8)
160#define MI_SAVE_EXT_STATE_EN (1<<3) 162#define MI_SAVE_EXT_STATE_EN (1<<3)
161#define MI_RESTORE_EXT_STATE_EN (1<<2) 163#define MI_RESTORE_EXT_STATE_EN (1<<2)
164#define MI_FORCE_RESTORE (1<<1)
162#define MI_RESTORE_INHIBIT (1<<0) 165#define MI_RESTORE_INHIBIT (1<<0)
163#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) 166#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
164#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ 167#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
@@ -1131,9 +1134,50 @@
1131#define RCBMINAVG 0x111a0 1134#define RCBMINAVG 0x111a0
1132#define RCUPEI 0x111b0 1135#define RCUPEI 0x111b0
1133#define RCDNEI 0x111b4 1136#define RCDNEI 0x111b4
1134#define MCHBAR_RENDER_STANDBY 0x111b8 1137#define RSTDBYCTL 0x111b8
1135#define RCX_SW_EXIT (1<<23) 1138#define RS1EN (1<<31)
1136#define RSX_STATUS_MASK 0x00700000 1139#define RS2EN (1<<30)
1140#define RS3EN (1<<29)
1141#define D3RS3EN (1<<28) /* Display D3 imlies RS3 */
1142#define SWPROMORSX (1<<27) /* RSx promotion timers ignored */
1143#define RCWAKERW (1<<26) /* Resetwarn from PCH causes wakeup */
1144#define DPRSLPVREN (1<<25) /* Fast voltage ramp enable */
1145#define GFXTGHYST (1<<24) /* Hysteresis to allow trunk gating */
1146#define RCX_SW_EXIT (1<<23) /* Leave RSx and prevent re-entry */
1147#define RSX_STATUS_MASK (7<<20)
1148#define RSX_STATUS_ON (0<<20)
1149#define RSX_STATUS_RC1 (1<<20)
1150#define RSX_STATUS_RC1E (2<<20)
1151#define RSX_STATUS_RS1 (3<<20)
1152#define RSX_STATUS_RS2 (4<<20) /* aka rc6 */
1153#define RSX_STATUS_RSVD (5<<20) /* deep rc6 unsupported on ilk */
1154#define RSX_STATUS_RS3 (6<<20) /* rs3 unsupported on ilk */
1155#define RSX_STATUS_RSVD2 (7<<20)
1156#define UWRCRSXE (1<<19) /* wake counter limit prevents rsx */
1157#define RSCRP (1<<18) /* rs requests control on rs1/2 reqs */
1158#define JRSC (1<<17) /* rsx coupled to cpu c-state */
1159#define RS2INC0 (1<<16) /* allow rs2 in cpu c0 */
1160#define RS1CONTSAV_MASK (3<<14)
1161#define RS1CONTSAV_NO_RS1 (0<<14) /* rs1 doesn't save/restore context */
1162#define RS1CONTSAV_RSVD (1<<14)
1163#define RS1CONTSAV_SAVE_RS1 (2<<14) /* rs1 saves context */
1164#define RS1CONTSAV_FULL_RS1 (3<<14) /* rs1 saves and restores context */
1165#define NORMSLEXLAT_MASK (3<<12)
1166#define SLOW_RS123 (0<<12)
1167#define SLOW_RS23 (1<<12)
1168#define SLOW_RS3 (2<<12)
1169#define NORMAL_RS123 (3<<12)
1170#define RCMODE_TIMEOUT (1<<11) /* 0 is eval interval method */
1171#define IMPROMOEN (1<<10) /* promo is immediate or delayed until next idle interval (only for timeout method above) */
1172#define RCENTSYNC (1<<9) /* rs coupled to cpu c-state (3/6/7) */
1173#define STATELOCK (1<<7) /* locked to rs_cstate if 0 */
1174#define RS_CSTATE_MASK (3<<4)
1175#define RS_CSTATE_C367_RS1 (0<<4)
1176#define RS_CSTATE_C36_RS1_C7_RS2 (1<<4)
1177#define RS_CSTATE_RSVD (2<<4)
1178#define RS_CSTATE_C367_RS2 (3<<4)
1179#define REDSAVES (1<<3) /* no context save if was idle during rs0 */
1180#define REDRESTORES (1<<2) /* no restore if was idle during rs0 */
1137#define VIDCTL 0x111c0 1181#define VIDCTL 0x111c0
1138#define VIDSTS 0x111c8 1182#define VIDSTS 0x111c8
1139#define VIDSTART 0x111cc /* 8 bits */ 1183#define VIDSTART 0x111cc /* 8 bits */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 410772466fa7..af530637777a 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -740,7 +740,7 @@ void i915_restore_display(struct drm_device *dev)
740 I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); 740 I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
741 I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); 741 I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR);
742 I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); 742 I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL);
743 I915_WRITE(MCHBAR_RENDER_STANDBY, 743 I915_WRITE(RSTDBYCTL,
744 dev_priv->saveMCHBAR_RENDER_STANDBY); 744 dev_priv->saveMCHBAR_RENDER_STANDBY);
745 } else { 745 } else {
746 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); 746 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
@@ -811,7 +811,7 @@ int i915_save_state(struct drm_device *dev)
811 dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR); 811 dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR);
812 dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR); 812 dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR);
813 dev_priv->saveMCHBAR_RENDER_STANDBY = 813 dev_priv->saveMCHBAR_RENDER_STANDBY =
814 I915_READ(MCHBAR_RENDER_STANDBY); 814 I915_READ(RSTDBYCTL);
815 } else { 815 } else {
816 dev_priv->saveIER = I915_READ(IER); 816 dev_priv->saveIER = I915_READ(IER);
817 dev_priv->saveIMR = I915_READ(IMR); 817 dev_priv->saveIMR = I915_READ(IMR);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 043825c9ddcf..f3c0525d5328 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6420,35 +6420,37 @@ void intel_enable_clock_gating(struct drm_device *dev)
6420 * GPU can automatically power down the render unit if given a page 6420 * GPU can automatically power down the render unit if given a page
6421 * to save state. 6421 * to save state.
6422 */ 6422 */
6423 if (IS_IRONLAKE_M(dev) && 0) { /* XXX causes a failure during suspend */ 6423 if (IS_IRONLAKE_M(dev)) {
6424 if (dev_priv->renderctx == NULL) 6424 if (dev_priv->renderctx == NULL)
6425 dev_priv->renderctx = intel_alloc_context_page(dev); 6425 dev_priv->renderctx = intel_alloc_context_page(dev);
6426 if (dev_priv->renderctx) { 6426 if (dev_priv->renderctx) {
6427 struct drm_i915_gem_object *obj = dev_priv->renderctx; 6427 struct drm_i915_gem_object *obj = dev_priv->renderctx;
6428 if (BEGIN_LP_RING(4) == 0) { 6428 if (BEGIN_LP_RING(6) != 0) {
6429 OUT_RING(MI_SET_CONTEXT); 6429 i915_gem_object_unpin(obj);
6430 OUT_RING(obj->gtt_offset | 6430 drm_gem_object_unreference(&obj->base);
6431 MI_MM_SPACE_GTT | 6431 dev_priv->renderctx = NULL;
6432 MI_SAVE_EXT_STATE_EN | 6432 return;
6433 MI_RESTORE_EXT_STATE_EN |
6434 MI_RESTORE_INHIBIT);
6435 OUT_RING(MI_NOOP);
6436 OUT_RING(MI_FLUSH);
6437 ADVANCE_LP_RING();
6438 } 6433 }
6434 OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN);
6435 OUT_RING(MI_SET_CONTEXT);
6436 OUT_RING(obj->gtt_offset |
6437 MI_MM_SPACE_GTT |
6438 MI_SAVE_EXT_STATE_EN |
6439 MI_RESTORE_EXT_STATE_EN |
6440 MI_RESTORE_INHIBIT);
6441 OUT_RING(MI_SUSPEND_FLUSH);
6442 OUT_RING(MI_NOOP);
6443 OUT_RING(MI_FLUSH);
6444 ADVANCE_LP_RING();
6439 } else 6445 } else
6440 DRM_DEBUG_KMS("Failed to allocate render context." 6446 DRM_DEBUG_KMS("Failed to allocate render context."
6441 "Disable RC6\n"); 6447 "Disable RC6\n");
6442 }
6443 6448
6444 if (IS_GEN4(dev) && IS_MOBILE(dev)) {
6445 if (dev_priv->pwrctx == NULL) 6449 if (dev_priv->pwrctx == NULL)
6446 dev_priv->pwrctx = intel_alloc_context_page(dev); 6450 dev_priv->pwrctx = intel_alloc_context_page(dev);
6447 if (dev_priv->pwrctx) { 6451 if (dev_priv->pwrctx) {
6448 struct drm_i915_gem_object *obj = dev_priv->pwrctx; 6452 struct drm_i915_gem_object *obj = dev_priv->pwrctx;
6449 I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN); 6453 I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN);
6450 I915_WRITE(MCHBAR_RENDER_STANDBY,
6451 I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT);
6452 } 6454 }
6453 } 6455 }
6454} 6456}