diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-01-05 15:01:24 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-11 15:43:58 -0500 |
commit | 88271da3f3da75d6eaef5e768c82a1627edf7088 (patch) | |
tree | be417b97f6252786dd0366592d05d1fc0cb8a939 /drivers/gpu/drm | |
parent | 0dc79fb2a36efcadbb39bd8b28933d8aa40408b1 (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.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 32 |
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 | } |