diff options
| author | Mark Brown <broonie@linaro.org> | 2013-08-15 06:19:52 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@linaro.org> | 2013-08-15 06:19:52 -0400 |
| commit | 4210606b19852dce52ed1a687db816695b6048e1 (patch) | |
| tree | fd0762f88dc54560d87fc1e523741d92228f6a9c /drivers/gpu/drm/i915/intel_pm.c | |
| parent | 4d8cfa4642f7d8fafa4d60f05dd34fe8c3b9fa45 (diff) | |
| parent | b7ae6f31d8243ec684af16bc5c763eccdfabaec0 (diff) | |
Merge branch 'topic/dma' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-pxa
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 65 |
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 | ||
| 5479 | void intel_gt_reset(struct drm_device *dev) | 5497 | void 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 | ||
| 5492 | void intel_gt_init(struct drm_device *dev) | 5514 | void 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 | |||
| 5559 | void 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 | } |
