diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 41 |
4 files changed, 54 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57204e298975..95391191316a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -187,6 +187,7 @@ typedef struct drm_i915_private { | |||
187 | unsigned int status_gfx_addr; | 187 | unsigned int status_gfx_addr; |
188 | drm_local_map_t hws_map; | 188 | drm_local_map_t hws_map; |
189 | struct drm_gem_object *hws_obj; | 189 | struct drm_gem_object *hws_obj; |
190 | struct drm_gem_object *pwrctx; | ||
190 | 191 | ||
191 | struct resource mch_res; | 192 | struct resource mch_res; |
192 | 193 | ||
@@ -280,6 +281,7 @@ typedef struct drm_i915_private { | |||
280 | u32 saveDSPBCNTR; | 281 | u32 saveDSPBCNTR; |
281 | u32 saveDSPARB; | 282 | u32 saveDSPARB; |
282 | u32 saveRENDERSTANDBY; | 283 | u32 saveRENDERSTANDBY; |
284 | u32 savePWRCTXA; | ||
283 | u32 saveHWS; | 285 | u32 saveHWS; |
284 | u32 savePIPEACONF; | 286 | u32 savePIPEACONF; |
285 | u32 savePIPEBCONF; | 287 | u32 savePIPEBCONF; |
@@ -1019,6 +1021,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1019 | (IS_I9XX(dev) || IS_GM45(dev)) && \ | 1021 | (IS_I9XX(dev) || IS_GM45(dev)) && \ |
1020 | !IS_IGD(dev) && \ | 1022 | !IS_IGD(dev) && \ |
1021 | !IS_IGDNG(dev)) | 1023 | !IS_IGDNG(dev)) |
1024 | #define I915_HAS_RC6(dev) (IS_I965GM(dev) || IS_GM45(dev) || IS_IGDNG_M(dev)) | ||
1022 | 1025 | ||
1023 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 1026 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
1024 | 1027 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1687edf68795..51fd152f47f3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -260,6 +260,8 @@ | |||
260 | #define HWS_PGA 0x02080 | 260 | #define HWS_PGA 0x02080 |
261 | #define HWS_ADDRESS_MASK 0xfffff000 | 261 | #define HWS_ADDRESS_MASK 0xfffff000 |
262 | #define HWS_START_ADDRESS_SHIFT 4 | 262 | #define HWS_START_ADDRESS_SHIFT 4 |
263 | #define PWRCTXA 0x2088 /* 965GM+ only */ | ||
264 | #define PWRCTX_EN (1<<0) | ||
263 | #define IPEIR 0x02088 | 265 | #define IPEIR 0x02088 |
264 | #define IPEHR 0x0208c | 266 | #define IPEHR 0x0208c |
265 | #define INSTDONE 0x02090 | 267 | #define INSTDONE 0x02090 |
@@ -769,7 +771,8 @@ | |||
769 | 771 | ||
770 | /** GM965 GM45 render standby register */ | 772 | /** GM965 GM45 render standby register */ |
771 | #define MCHBAR_RENDER_STANDBY 0x111B8 | 773 | #define MCHBAR_RENDER_STANDBY 0x111B8 |
772 | 774 | #define RCX_SW_EXIT (1<<23) | |
775 | #define RSX_STATUS_MASK 0x00700000 | ||
773 | #define PEG_BAND_GAP_DATA 0x14d68 | 776 | #define PEG_BAND_GAP_DATA 0x14d68 |
774 | 777 | ||
775 | /* | 778 | /* |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 992d5617e798..cd10d9b8181f 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -699,8 +699,10 @@ int i915_save_state(struct drm_device *dev) | |||
699 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 699 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
700 | 700 | ||
701 | /* Render Standby */ | 701 | /* Render Standby */ |
702 | if (IS_I965G(dev) && IS_MOBILE(dev)) | 702 | if (I915_HAS_RC6(dev)) { |
703 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | 703 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); |
704 | dev_priv->savePWRCTXA = I915_READ(PWRCTXA); | ||
705 | } | ||
704 | 706 | ||
705 | /* Hardware status page */ | 707 | /* Hardware status page */ |
706 | dev_priv->saveHWS = I915_READ(HWS_PGA); | 708 | dev_priv->saveHWS = I915_READ(HWS_PGA); |
@@ -762,8 +764,10 @@ int i915_restore_state(struct drm_device *dev) | |||
762 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 764 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
763 | 765 | ||
764 | /* Render Standby */ | 766 | /* Render Standby */ |
765 | if (IS_I965G(dev) && IS_MOBILE(dev)) | 767 | if (I915_HAS_RC6(dev)) { |
766 | I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); | 768 | I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); |
769 | I915_WRITE(PWRCTXA, dev_priv->savePWRCTXA); | ||
770 | } | ||
767 | 771 | ||
768 | /* Hardware status page */ | 772 | /* Hardware status page */ |
769 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 773 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 099f420de57a..8945656dc1dc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4296,6 +4296,42 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
4296 | } else if (IS_I830(dev)) { | 4296 | } else if (IS_I830(dev)) { |
4297 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | 4297 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); |
4298 | } | 4298 | } |
4299 | |||
4300 | /* | ||
4301 | * GPU can automatically power down the render unit if given a page | ||
4302 | * to save state. | ||
4303 | */ | ||
4304 | if (I915_HAS_RC6(dev)) { | ||
4305 | struct drm_gem_object *pwrctx; | ||
4306 | struct drm_i915_gem_object *obj_priv; | ||
4307 | int ret; | ||
4308 | |||
4309 | pwrctx = drm_gem_object_alloc(dev, 4096); | ||
4310 | if (!pwrctx) { | ||
4311 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | ||
4312 | goto out; | ||
4313 | } | ||
4314 | |||
4315 | ret = i915_gem_object_pin(pwrctx, 4096); | ||
4316 | if (ret) { | ||
4317 | DRM_ERROR("failed to pin power context: %d\n", ret); | ||
4318 | drm_gem_object_unreference(pwrctx); | ||
4319 | goto out; | ||
4320 | } | ||
4321 | |||
4322 | i915_gem_object_set_to_gtt_domain(pwrctx, 1); | ||
4323 | |||
4324 | obj_priv = pwrctx->driver_private; | ||
4325 | |||
4326 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); | ||
4327 | I915_WRITE(MCHBAR_RENDER_STANDBY, | ||
4328 | I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); | ||
4329 | |||
4330 | dev_priv->pwrctx = pwrctx; | ||
4331 | } | ||
4332 | |||
4333 | out: | ||
4334 | return; | ||
4299 | } | 4335 | } |
4300 | 4336 | ||
4301 | /* Set up chip specific display functions */ | 4337 | /* Set up chip specific display functions */ |
@@ -4450,6 +4486,11 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4450 | if (dev_priv->display.disable_fbc) | 4486 | if (dev_priv->display.disable_fbc) |
4451 | dev_priv->display.disable_fbc(dev); | 4487 | dev_priv->display.disable_fbc(dev); |
4452 | 4488 | ||
4489 | if (dev_priv->pwrctx) { | ||
4490 | i915_gem_object_unpin(dev_priv->pwrctx); | ||
4491 | drm_gem_object_unreference(dev_priv->pwrctx); | ||
4492 | } | ||
4493 | |||
4453 | drm_mode_config_cleanup(dev); | 4494 | drm_mode_config_cleanup(dev); |
4454 | } | 4495 | } |
4455 | 4496 | ||