aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ccbdd83f5220..b0e4a0bd1313 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
5063 } 5063 }
5064 } else { 5064 } else {
5065 if (enable_requested) { 5065 if (enable_requested) {
5066 unsigned long irqflags;
5067 enum pipe p;
5068
5066 I915_WRITE(HSW_PWR_WELL_DRIVER, 0); 5069 I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
5070 POSTING_READ(HSW_PWR_WELL_DRIVER);
5067 DRM_DEBUG_KMS("Requesting to disable the power well\n"); 5071 DRM_DEBUG_KMS("Requesting to disable the power well\n");
5072
5073 /*
5074 * After this, the registers on the pipes that are part
5075 * of the power well will become zero, so we have to
5076 * adjust our counters according to that.
5077 *
5078 * FIXME: Should we do this in general in
5079 * drm_vblank_post_modeset?
5080 */
5081 spin_lock_irqsave(&dev->vbl_lock, irqflags);
5082 for_each_pipe(p)
5083 if (p != PIPE_A)
5084 dev->last_vblank[p] = 0;
5085 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5068 } 5086 }
5069 } 5087 }
5070} 5088}
@@ -5476,7 +5494,7 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
5476 gen6_gt_check_fifodbg(dev_priv); 5494 gen6_gt_check_fifodbg(dev_priv);
5477} 5495}
5478 5496
5479void intel_gt_reset(struct drm_device *dev) 5497void intel_gt_sanitize(struct drm_device *dev)
5480{ 5498{
5481 struct drm_i915_private *dev_priv = dev->dev_private; 5499 struct drm_i915_private *dev_priv = dev->dev_private;
5482 5500
@@ -5487,26 +5505,61 @@ void intel_gt_reset(struct drm_device *dev)
5487 if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) 5505 if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
5488 __gen6_gt_force_wake_mt_reset(dev_priv); 5506 __gen6_gt_force_wake_mt_reset(dev_priv);
5489 } 5507 }
5508
5509 /* BIOS often leaves RC6 enabled, but disable it for hw init */
5510 if (INTEL_INFO(dev)->gen >= 6)
5511 intel_disable_gt_powersave(dev);
5490} 5512}
5491 5513
5492void intel_gt_init(struct drm_device *dev) 5514void intel_gt_init(struct drm_device *dev)
5493{ 5515{
5494 struct drm_i915_private *dev_priv = dev->dev_private; 5516 struct drm_i915_private *dev_priv = dev->dev_private;
5495 5517
5496 spin_lock_init(&dev_priv->gt_lock);
5497
5498 intel_gt_reset(dev);
5499
5500 if (IS_VALLEYVIEW(dev)) { 5518 if (IS_VALLEYVIEW(dev)) {
5501 dev_priv->gt.force_wake_get = vlv_force_wake_get; 5519 dev_priv->gt.force_wake_get = vlv_force_wake_get;
5502 dev_priv->gt.force_wake_put = vlv_force_wake_put; 5520 dev_priv->gt.force_wake_put = vlv_force_wake_put;
5503 } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { 5521 } else if (IS_HASWELL(dev)) {
5504 dev_priv->gt.force_wake_get = __gen6_gt_force_wake_mt_get; 5522 dev_priv->gt.force_wake_get = __gen6_gt_force_wake_mt_get;
5505 dev_priv->gt.force_wake_put = __gen6_gt_force_wake_mt_put; 5523 dev_priv->gt.force_wake_put = __gen6_gt_force_wake_mt_put;
5524 } else if (IS_IVYBRIDGE(dev)) {
5525 u32 ecobus;
5526
5527 /* IVB configs may use multi-threaded forcewake */
5528
5529 /* A small trick here - if the bios hasn't configured
5530 * MT forcewake, and if the device is in RC6, then
5531 * force_wake_mt_get will not wake the device and the
5532 * ECOBUS read will return zero. Which will be
5533 * (correctly) interpreted by the test below as MT
5534 * forcewake being disabled.
5535 */
5536 mutex_lock(&dev->struct_mutex);
5537 __gen6_gt_force_wake_mt_get(dev_priv);
5538 ecobus = I915_READ_NOTRACE(ECOBUS);
5539 __gen6_gt_force_wake_mt_put(dev_priv);
5540 mutex_unlock(&dev->struct_mutex);
5541
5542 if (ecobus & FORCEWAKE_MT_ENABLE) {
5543 dev_priv->gt.force_wake_get =
5544 __gen6_gt_force_wake_mt_get;
5545 dev_priv->gt.force_wake_put =
5546 __gen6_gt_force_wake_mt_put;
5547 } else {
5548 DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
5549 DRM_INFO("when using vblank-synced partial screen updates.\n");
5550 dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get;
5551 dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put;
5552 }
5506 } else if (IS_GEN6(dev)) { 5553 } else if (IS_GEN6(dev)) {
5507 dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; 5554 dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get;
5508 dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; 5555 dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put;
5509 } 5556 }
5557}
5558
5559void intel_pm_init(struct drm_device *dev)
5560{
5561 struct drm_i915_private *dev_priv = dev->dev_private;
5562
5510 INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, 5563 INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
5511 intel_gen6_powersave_work); 5564 intel_gen6_powersave_work);
5512} 5565}