diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 54242e4f6f4c..ee72807069e4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3209,6 +3209,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val) | |||
3209 | */ | 3209 | */ |
3210 | static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) | 3210 | static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) |
3211 | { | 3211 | { |
3212 | struct drm_device *dev = dev_priv->dev; | ||
3213 | |||
3214 | /* Latest VLV doesn't need to force the gfx clock */ | ||
3215 | if (dev->pdev->revision >= 0xd) { | ||
3216 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); | ||
3217 | return; | ||
3218 | } | ||
3219 | |||
3212 | /* | 3220 | /* |
3213 | * When we are idle. Drop to min voltage state. | 3221 | * When we are idle. Drop to min voltage state. |
3214 | */ | 3222 | */ |
@@ -5603,8 +5611,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, | |||
5603 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); | 5611 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); |
5604 | } | 5612 | } |
5605 | 5613 | ||
5606 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | 5614 | bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, |
5607 | enum intel_display_power_domain domain) | 5615 | enum intel_display_power_domain domain) |
5608 | { | 5616 | { |
5609 | struct i915_power_domains *power_domains; | 5617 | struct i915_power_domains *power_domains; |
5610 | struct i915_power_well *power_well; | 5618 | struct i915_power_well *power_well; |
@@ -5615,16 +5623,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | |||
5615 | return false; | 5623 | return false; |
5616 | 5624 | ||
5617 | power_domains = &dev_priv->power_domains; | 5625 | power_domains = &dev_priv->power_domains; |
5626 | |||
5618 | is_enabled = true; | 5627 | is_enabled = true; |
5628 | |||
5619 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 5629 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { |
5620 | if (power_well->always_on) | 5630 | if (power_well->always_on) |
5621 | continue; | 5631 | continue; |
5622 | 5632 | ||
5623 | if (!power_well->count) { | 5633 | if (!power_well->hw_enabled) { |
5624 | is_enabled = false; | 5634 | is_enabled = false; |
5625 | break; | 5635 | break; |
5626 | } | 5636 | } |
5627 | } | 5637 | } |
5638 | |||
5628 | return is_enabled; | 5639 | return is_enabled; |
5629 | } | 5640 | } |
5630 | 5641 | ||
@@ -5632,30 +5643,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, | |||
5632 | enum intel_display_power_domain domain) | 5643 | enum intel_display_power_domain domain) |
5633 | { | 5644 | { |
5634 | struct i915_power_domains *power_domains; | 5645 | struct i915_power_domains *power_domains; |
5635 | struct i915_power_well *power_well; | 5646 | bool ret; |
5636 | bool is_enabled; | ||
5637 | int i; | ||
5638 | |||
5639 | if (dev_priv->pm.suspended) | ||
5640 | return false; | ||
5641 | 5647 | ||
5642 | power_domains = &dev_priv->power_domains; | 5648 | power_domains = &dev_priv->power_domains; |
5643 | 5649 | ||
5644 | is_enabled = true; | ||
5645 | |||
5646 | mutex_lock(&power_domains->lock); | 5650 | mutex_lock(&power_domains->lock); |
5647 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 5651 | ret = intel_display_power_enabled_unlocked(dev_priv, domain); |
5648 | if (power_well->always_on) | ||
5649 | continue; | ||
5650 | |||
5651 | if (!power_well->ops->is_enabled(dev_priv, power_well)) { | ||
5652 | is_enabled = false; | ||
5653 | break; | ||
5654 | } | ||
5655 | } | ||
5656 | mutex_unlock(&power_domains->lock); | 5652 | mutex_unlock(&power_domains->lock); |
5657 | 5653 | ||
5658 | return is_enabled; | 5654 | return ret; |
5659 | } | 5655 | } |
5660 | 5656 | ||
5661 | /* | 5657 | /* |
@@ -5976,6 +5972,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, | |||
5976 | if (!power_well->count++) { | 5972 | if (!power_well->count++) { |
5977 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | 5973 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); |
5978 | power_well->ops->enable(dev_priv, power_well); | 5974 | power_well->ops->enable(dev_priv, power_well); |
5975 | power_well->hw_enabled = true; | ||
5979 | } | 5976 | } |
5980 | 5977 | ||
5981 | check_power_well_state(dev_priv, power_well); | 5978 | check_power_well_state(dev_priv, power_well); |
@@ -6005,6 +6002,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
6005 | 6002 | ||
6006 | if (!--power_well->count && i915.disable_power_well) { | 6003 | if (!--power_well->count && i915.disable_power_well) { |
6007 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | 6004 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); |
6005 | power_well->hw_enabled = false; | ||
6008 | power_well->ops->disable(dev_priv, power_well); | 6006 | power_well->ops->disable(dev_priv, power_well); |
6009 | } | 6007 | } |
6010 | 6008 | ||
@@ -6048,6 +6046,27 @@ int i915_release_power_well(void) | |||
6048 | } | 6046 | } |
6049 | EXPORT_SYMBOL_GPL(i915_release_power_well); | 6047 | EXPORT_SYMBOL_GPL(i915_release_power_well); |
6050 | 6048 | ||
6049 | /* | ||
6050 | * Private interface for the audio driver to get CDCLK in kHz. | ||
6051 | * | ||
6052 | * Caller must request power well using i915_request_power_well() prior to | ||
6053 | * making the call. | ||
6054 | */ | ||
6055 | int i915_get_cdclk_freq(void) | ||
6056 | { | ||
6057 | struct drm_i915_private *dev_priv; | ||
6058 | |||
6059 | if (!hsw_pwr) | ||
6060 | return -ENODEV; | ||
6061 | |||
6062 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, | ||
6063 | power_domains); | ||
6064 | |||
6065 | return intel_ddi_get_cdclk_freq(dev_priv); | ||
6066 | } | ||
6067 | EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); | ||
6068 | |||
6069 | |||
6051 | #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) | 6070 | #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) |
6052 | 6071 | ||
6053 | #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ | 6072 | #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ |
@@ -6267,8 +6286,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv) | |||
6267 | int i; | 6286 | int i; |
6268 | 6287 | ||
6269 | mutex_lock(&power_domains->lock); | 6288 | mutex_lock(&power_domains->lock); |
6270 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) | 6289 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { |
6271 | power_well->ops->sync_hw(dev_priv, power_well); | 6290 | power_well->ops->sync_hw(dev_priv, power_well); |
6291 | power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, | ||
6292 | power_well); | ||
6293 | } | ||
6272 | mutex_unlock(&power_domains->lock); | 6294 | mutex_unlock(&power_domains->lock); |
6273 | } | 6295 | } |
6274 | 6296 | ||