diff options
author | Zou Nan hai <nanhai.zou@intel.com> | 2010-06-25 01:40:23 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-08-09 14:34:12 -0400 |
commit | aa40d6bbb9cf88f3fb296a57e046a52e9a68ab72 (patch) | |
tree | 1e3509cc6d080309414ff430374b5b21e1902d20 | |
parent | 1cafd34731cd14e5a72edaf0f41717c8126cfce9 (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.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 53 |
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 | ||
5468 | static struct drm_gem_object * | 5468 | static struct drm_gem_object * |
5469 | intel_alloc_power_context(struct drm_device *dev) | 5469 | intel_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 | ||
5496 | err_unpin: | 5496 | err_unpin: |
5497 | i915_gem_object_unpin(pwrctx); | 5497 | i915_gem_object_unpin(ctx); |
5498 | err_unref: | 5498 | err_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 | ||