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.c89
1 files changed, 54 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d1e53abec1b5..ee72807069e4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -511,8 +511,7 @@ void intel_update_fbc(struct drm_device *dev)
511 obj = intel_fb->obj; 511 obj = intel_fb->obj;
512 adjusted_mode = &intel_crtc->config.adjusted_mode; 512 adjusted_mode = &intel_crtc->config.adjusted_mode;
513 513
514 if (i915.enable_fbc < 0 && 514 if (i915.enable_fbc < 0) {
515 INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) {
516 if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) 515 if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT))
517 DRM_DEBUG_KMS("disabled per chip default\n"); 516 DRM_DEBUG_KMS("disabled per chip default\n");
518 goto out_disable; 517 goto out_disable;
@@ -3210,6 +3209,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
3210*/ 3209*/
3211static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) 3210static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
3212{ 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
3213 /* 3220 /*
3214 * When we are idle. Drop to min voltage state. 3221 * When we are idle. Drop to min voltage state.
3215 */ 3222 */
@@ -3506,15 +3513,11 @@ static void gen8_enable_rps(struct drm_device *dev)
3506 3513
3507 I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); 3514 I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
3508 3515
3509 /* WaDisablePwrmtrEvent:chv (pre-production hw) */
3510 I915_WRITE(0xA80C, I915_READ(0xA80C) & 0x00ffffff);
3511 I915_WRITE(0xA810, I915_READ(0xA810) & 0xffffff00);
3512
3513 /* 5: Enable RPS */ 3516 /* 5: Enable RPS */
3514 I915_WRITE(GEN6_RP_CONTROL, 3517 I915_WRITE(GEN6_RP_CONTROL,
3515 GEN6_RP_MEDIA_TURBO | 3518 GEN6_RP_MEDIA_TURBO |
3516 GEN6_RP_MEDIA_HW_NORMAL_MODE | 3519 GEN6_RP_MEDIA_HW_NORMAL_MODE |
3517 GEN6_RP_MEDIA_IS_GFX | /* WaSetMaskForGfxBusyness:chv (pre-production hw ?) */ 3520 GEN6_RP_MEDIA_IS_GFX |
3518 GEN6_RP_ENABLE | 3521 GEN6_RP_ENABLE |
3519 GEN6_RP_UP_BUSY_AVG | 3522 GEN6_RP_UP_BUSY_AVG |
3520 GEN6_RP_DOWN_IDLE_AVG); 3523 GEN6_RP_DOWN_IDLE_AVG);
@@ -5608,8 +5611,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
5608 (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); 5611 (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
5609} 5612}
5610 5613
5611bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, 5614bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv,
5612 enum intel_display_power_domain domain) 5615 enum intel_display_power_domain domain)
5613{ 5616{
5614 struct i915_power_domains *power_domains; 5617 struct i915_power_domains *power_domains;
5615 struct i915_power_well *power_well; 5618 struct i915_power_well *power_well;
@@ -5620,16 +5623,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
5620 return false; 5623 return false;
5621 5624
5622 power_domains = &dev_priv->power_domains; 5625 power_domains = &dev_priv->power_domains;
5626
5623 is_enabled = true; 5627 is_enabled = true;
5628
5624 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) {
5625 if (power_well->always_on) 5630 if (power_well->always_on)
5626 continue; 5631 continue;
5627 5632
5628 if (!power_well->count) { 5633 if (!power_well->hw_enabled) {
5629 is_enabled = false; 5634 is_enabled = false;
5630 break; 5635 break;
5631 } 5636 }
5632 } 5637 }
5638
5633 return is_enabled; 5639 return is_enabled;
5634} 5640}
5635 5641
@@ -5637,30 +5643,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
5637 enum intel_display_power_domain domain) 5643 enum intel_display_power_domain domain)
5638{ 5644{
5639 struct i915_power_domains *power_domains; 5645 struct i915_power_domains *power_domains;
5640 struct i915_power_well *power_well; 5646 bool ret;
5641 bool is_enabled;
5642 int i;
5643
5644 if (dev_priv->pm.suspended)
5645 return false;
5646 5647
5647 power_domains = &dev_priv->power_domains; 5648 power_domains = &dev_priv->power_domains;
5648 5649
5649 is_enabled = true;
5650
5651 mutex_lock(&power_domains->lock); 5650 mutex_lock(&power_domains->lock);
5652 for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { 5651 ret = intel_display_power_enabled_unlocked(dev_priv, domain);
5653 if (power_well->always_on)
5654 continue;
5655
5656 if (!power_well->ops->is_enabled(dev_priv, power_well)) {
5657 is_enabled = false;
5658 break;
5659 }
5660 }
5661 mutex_unlock(&power_domains->lock); 5652 mutex_unlock(&power_domains->lock);
5662 5653
5663 return is_enabled; 5654 return ret;
5664} 5655}
5665 5656
5666/* 5657/*
@@ -5981,6 +5972,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
5981 if (!power_well->count++) { 5972 if (!power_well->count++) {
5982 DRM_DEBUG_KMS("enabling %s\n", power_well->name); 5973 DRM_DEBUG_KMS("enabling %s\n", power_well->name);
5983 power_well->ops->enable(dev_priv, power_well); 5974 power_well->ops->enable(dev_priv, power_well);
5975 power_well->hw_enabled = true;
5984 } 5976 }
5985 5977
5986 check_power_well_state(dev_priv, power_well); 5978 check_power_well_state(dev_priv, power_well);
@@ -6010,6 +6002,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
6010 6002
6011 if (!--power_well->count && i915.disable_power_well) { 6003 if (!--power_well->count && i915.disable_power_well) {
6012 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;
6013 power_well->ops->disable(dev_priv, power_well); 6006 power_well->ops->disable(dev_priv, power_well);
6014 } 6007 }
6015 6008
@@ -6024,33 +6017,56 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
6024static struct i915_power_domains *hsw_pwr; 6017static struct i915_power_domains *hsw_pwr;
6025 6018
6026/* Display audio driver power well request */ 6019/* Display audio driver power well request */
6027void i915_request_power_well(void) 6020int i915_request_power_well(void)
6028{ 6021{
6029 struct drm_i915_private *dev_priv; 6022 struct drm_i915_private *dev_priv;
6030 6023
6031 if (WARN_ON(!hsw_pwr)) 6024 if (!hsw_pwr)
6032 return; 6025 return -ENODEV;
6033 6026
6034 dev_priv = container_of(hsw_pwr, struct drm_i915_private, 6027 dev_priv = container_of(hsw_pwr, struct drm_i915_private,
6035 power_domains); 6028 power_domains);
6036 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); 6029 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
6030 return 0;
6037} 6031}
6038EXPORT_SYMBOL_GPL(i915_request_power_well); 6032EXPORT_SYMBOL_GPL(i915_request_power_well);
6039 6033
6040/* Display audio driver power well release */ 6034/* Display audio driver power well release */
6041void i915_release_power_well(void) 6035int i915_release_power_well(void)
6042{ 6036{
6043 struct drm_i915_private *dev_priv; 6037 struct drm_i915_private *dev_priv;
6044 6038
6045 if (WARN_ON(!hsw_pwr)) 6039 if (!hsw_pwr)
6046 return; 6040 return -ENODEV;
6047 6041
6048 dev_priv = container_of(hsw_pwr, struct drm_i915_private, 6042 dev_priv = container_of(hsw_pwr, struct drm_i915_private,
6049 power_domains); 6043 power_domains);
6050 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); 6044 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
6045 return 0;
6051} 6046}
6052EXPORT_SYMBOL_GPL(i915_release_power_well); 6047EXPORT_SYMBOL_GPL(i915_release_power_well);
6053 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 */
6055int 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}
6067EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
6068
6069
6054#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) 6070#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
6055 6071
6056#define HSW_ALWAYS_ON_POWER_DOMAINS ( \ 6072#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
@@ -6270,8 +6286,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
6270 int i; 6286 int i;
6271 6287
6272 mutex_lock(&power_domains->lock); 6288 mutex_lock(&power_domains->lock);
6273 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) {
6274 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 }
6275 mutex_unlock(&power_domains->lock); 6294 mutex_unlock(&power_domains->lock);
6276} 6295}
6277 6296