aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZou Nan hai <nanhai.zou@intel.com>2010-06-25 01:40:23 -0400
committerEric Anholt <eric@anholt.net>2010-08-09 14:34:12 -0400
commitaa40d6bbb9cf88f3fb296a57e046a52e9a68ab72 (patch)
tree1e3509cc6d080309414ff430374b5b21e1902d20
parent1cafd34731cd14e5a72edaf0f41717c8126cfce9 (diff)
drm/i915: Set up a render context on Ironlake
RC6 power state requires a logical render context in place for saving render context. Signed-off-by: Zou Nan hai <nanhai.zou@intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h11
-rw-r--r--drivers/gpu/drm/i915/intel_display.c53
3 files changed, 55 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8df6ac735187..047cd7ce7e1b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -254,6 +254,7 @@ typedef struct drm_i915_private {
254 drm_local_map_t hws_map; 254 drm_local_map_t hws_map;
255 struct drm_gem_object *seqno_obj; 255 struct drm_gem_object *seqno_obj;
256 struct drm_gem_object *pwrctx; 256 struct drm_gem_object *pwrctx;
257 struct drm_gem_object *renderctx;
257 258
258 struct resource mch_res; 259 struct resource mch_res;
259 260
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 21fd657663aa..a63e9a176386 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -181,6 +181,12 @@
181#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) 181#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
182#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) 182#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
183#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) 183#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
184#define MI_SET_CONTEXT MI_INSTR(0x18, 0)
185#define MI_MM_SPACE_GTT (1<<8)
186#define MI_MM_SPACE_PHYSICAL (0<<8)
187#define MI_SAVE_EXT_STATE_EN (1<<3)
188#define MI_RESTORE_EXT_STATE_EN (1<<2)
189#define MI_RESTORE_INHIBIT (1<<0)
184#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) 190#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
185#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ 191#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
186#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) 192#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
@@ -1101,6 +1107,11 @@
1101#define PEG_BAND_GAP_DATA 0x14d68 1107#define PEG_BAND_GAP_DATA 0x14d68
1102 1108
1103/* 1109/*
1110 * Logical Context regs
1111 */
1112#define CCID 0x2180
1113#define CCID_EN (1<<0)
1114/*
1104 * Overlay regs 1115 * Overlay regs
1105 */ 1116 */
1106 1117
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 53f3a98cc1ae..4668e9bf67d8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5466,37 +5466,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
5466}; 5466};
5467 5467
5468static struct drm_gem_object * 5468static struct drm_gem_object *
5469intel_alloc_power_context(struct drm_device *dev) 5469intel_alloc_context_page(struct drm_device *dev)
5470{ 5470{
5471 struct drm_gem_object *pwrctx; 5471 struct drm_gem_object *ctx;
5472 int ret; 5472 int ret;
5473 5473
5474 pwrctx = i915_gem_alloc_object(dev, 4096); 5474 ctx = i915_gem_alloc_object(dev, 4096);
5475 if (!pwrctx) { 5475 if (!ctx) {
5476 DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); 5476 DRM_DEBUG("failed to alloc power context, RC6 disabled\n");
5477 return NULL; 5477 return NULL;
5478 } 5478 }
5479 5479
5480 mutex_lock(&dev->struct_mutex); 5480 mutex_lock(&dev->struct_mutex);
5481 ret = i915_gem_object_pin(pwrctx, 4096); 5481 ret = i915_gem_object_pin(ctx, 4096);
5482 if (ret) { 5482 if (ret) {
5483 DRM_ERROR("failed to pin power context: %d\n", ret); 5483 DRM_ERROR("failed to pin power context: %d\n", ret);
5484 goto err_unref; 5484 goto err_unref;
5485 } 5485 }
5486 5486
5487 ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); 5487 ret = i915_gem_object_set_to_gtt_domain(ctx, 1);
5488 if (ret) { 5488 if (ret) {
5489 DRM_ERROR("failed to set-domain on power context: %d\n", ret); 5489 DRM_ERROR("failed to set-domain on power context: %d\n", ret);
5490 goto err_unpin; 5490 goto err_unpin;
5491 } 5491 }
5492 mutex_unlock(&dev->struct_mutex); 5492 mutex_unlock(&dev->struct_mutex);
5493 5493
5494 return pwrctx; 5494 return ctx;
5495 5495
5496err_unpin: 5496err_unpin:
5497 i915_gem_object_unpin(pwrctx); 5497 i915_gem_object_unpin(ctx);
5498err_unref: 5498err_unref:
5499 drm_gem_object_unreference(pwrctx); 5499 drm_gem_object_unreference(ctx);
5500 mutex_unlock(&dev->struct_mutex); 5500 mutex_unlock(&dev->struct_mutex);
5501 return NULL; 5501 return NULL;
5502} 5502}
@@ -5796,6 +5796,29 @@ void intel_init_clock_gating(struct drm_device *dev)
5796 * GPU can automatically power down the render unit if given a page 5796 * GPU can automatically power down the render unit if given a page
5797 * to save state. 5797 * to save state.
5798 */ 5798 */
5799 if (IS_IRONLAKE_M(dev)) {
5800 if (dev_priv->renderctx == NULL)
5801 dev_priv->renderctx = intel_alloc_context_page(dev);
5802 if (dev_priv->renderctx) {
5803 struct drm_i915_gem_object *obj_priv;
5804 obj_priv = to_intel_bo(dev_priv->renderctx);
5805 if (obj_priv) {
5806 BEGIN_LP_RING(4);
5807 OUT_RING(MI_SET_CONTEXT);
5808 OUT_RING(obj_priv->gtt_offset |
5809 MI_MM_SPACE_GTT |
5810 MI_SAVE_EXT_STATE_EN |
5811 MI_RESTORE_EXT_STATE_EN |
5812 MI_RESTORE_INHIBIT);
5813 OUT_RING(MI_NOOP);
5814 OUT_RING(MI_FLUSH);
5815 ADVANCE_LP_RING();
5816 }
5817 } else
5818 DRM_DEBUG_KMS("Failed to allocate render context."
5819 "Disable RC6\n");
5820 }
5821
5799 if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { 5822 if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) {
5800 struct drm_i915_gem_object *obj_priv = NULL; 5823 struct drm_i915_gem_object *obj_priv = NULL;
5801 5824
@@ -5804,7 +5827,7 @@ void intel_init_clock_gating(struct drm_device *dev)
5804 } else { 5827 } else {
5805 struct drm_gem_object *pwrctx; 5828 struct drm_gem_object *pwrctx;
5806 5829
5807 pwrctx = intel_alloc_power_context(dev); 5830 pwrctx = intel_alloc_context_page(dev);
5808 if (pwrctx) { 5831 if (pwrctx) {
5809 dev_priv->pwrctx = pwrctx; 5832 dev_priv->pwrctx = pwrctx;
5810 obj_priv = to_intel_bo(pwrctx); 5833 obj_priv = to_intel_bo(pwrctx);
@@ -6062,6 +6085,16 @@ void intel_modeset_cleanup(struct drm_device *dev)
6062 if (dev_priv->display.disable_fbc) 6085 if (dev_priv->display.disable_fbc)
6063 dev_priv->display.disable_fbc(dev); 6086 dev_priv->display.disable_fbc(dev);
6064 6087
6088 if (dev_priv->renderctx) {
6089 struct drm_i915_gem_object *obj_priv;
6090
6091 obj_priv = to_intel_bo(dev_priv->renderctx);
6092 I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN);
6093 I915_READ(CCID);
6094 i915_gem_object_unpin(dev_priv->renderctx);
6095 drm_gem_object_unreference(dev_priv->renderctx);
6096 }
6097
6065 if (dev_priv->pwrctx) { 6098 if (dev_priv->pwrctx) {
6066 struct drm_i915_gem_object *obj_priv; 6099 struct drm_i915_gem_object *obj_priv;
6067 6100