diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 37 |
4 files changed, 22 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 49414d30e8d4..a47fbf60b781 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -977,6 +977,8 @@ struct i915_power_well { | |||
| 977 | bool always_on; | 977 | bool always_on; |
| 978 | /* power well enable/disable usage count */ | 978 | /* power well enable/disable usage count */ |
| 979 | int count; | 979 | int count; |
| 980 | /* cached hw enabled state */ | ||
| 981 | bool hw_enabled; | ||
| 980 | unsigned long domains; | 982 | unsigned long domains; |
| 981 | unsigned long data; | 983 | unsigned long data; |
| 982 | const struct i915_power_well_ops *ops; | 984 | const struct i915_power_well_ops *ops; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index efd3cf50cb0f..9188fede99ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -12411,8 +12411,8 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
| 12411 | 12411 | ||
| 12412 | for_each_pipe(i) { | 12412 | for_each_pipe(i) { |
| 12413 | error->pipe[i].power_domain_on = | 12413 | error->pipe[i].power_domain_on = |
| 12414 | intel_display_power_enabled_sw(dev_priv, | 12414 | intel_display_power_enabled_unlocked(dev_priv, |
| 12415 | POWER_DOMAIN_PIPE(i)); | 12415 | POWER_DOMAIN_PIPE(i)); |
| 12416 | if (!error->pipe[i].power_domain_on) | 12416 | if (!error->pipe[i].power_domain_on) |
| 12417 | continue; | 12417 | continue; |
| 12418 | 12418 | ||
| @@ -12447,7 +12447,7 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
| 12447 | enum transcoder cpu_transcoder = transcoders[i]; | 12447 | enum transcoder cpu_transcoder = transcoders[i]; |
| 12448 | 12448 | ||
| 12449 | error->transcoder[i].power_domain_on = | 12449 | error->transcoder[i].power_domain_on = |
| 12450 | intel_display_power_enabled_sw(dev_priv, | 12450 | intel_display_power_enabled_unlocked(dev_priv, |
| 12451 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); | 12451 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); |
| 12452 | if (!error->transcoder[i].power_domain_on) | 12452 | if (!error->transcoder[i].power_domain_on) |
| 12453 | continue; | 12453 | continue; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bda0ae3d80cc..eaa27ee9e367 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *); | |||
| 950 | void intel_power_domains_remove(struct drm_i915_private *); | 950 | void intel_power_domains_remove(struct drm_i915_private *); |
| 951 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, | 951 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, |
| 952 | enum intel_display_power_domain domain); | 952 | enum intel_display_power_domain domain); |
| 953 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | 953 | bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, |
| 954 | enum intel_display_power_domain domain); | 954 | enum intel_display_power_domain domain); |
| 955 | void intel_display_power_get(struct drm_i915_private *dev_priv, | 955 | void intel_display_power_get(struct drm_i915_private *dev_priv, |
| 956 | enum intel_display_power_domain domain); | 956 | enum intel_display_power_domain domain); |
| 957 | void intel_display_power_put(struct drm_i915_private *dev_priv, | 957 | void intel_display_power_put(struct drm_i915_private *dev_priv, |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 54242e4f6f4c..9ad0c6afc487 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -5603,8 +5603,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, | |||
| 5603 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); | 5603 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); |
| 5604 | } | 5604 | } |
| 5605 | 5605 | ||
| 5606 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | 5606 | bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, |
| 5607 | enum intel_display_power_domain domain) | 5607 | enum intel_display_power_domain domain) |
| 5608 | { | 5608 | { |
| 5609 | struct i915_power_domains *power_domains; | 5609 | struct i915_power_domains *power_domains; |
| 5610 | struct i915_power_well *power_well; | 5610 | struct i915_power_well *power_well; |
| @@ -5615,16 +5615,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | |||
| 5615 | return false; | 5615 | return false; |
| 5616 | 5616 | ||
| 5617 | power_domains = &dev_priv->power_domains; | 5617 | power_domains = &dev_priv->power_domains; |
| 5618 | |||
| 5618 | is_enabled = true; | 5619 | is_enabled = true; |
| 5620 | |||
| 5619 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 5621 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { |
| 5620 | if (power_well->always_on) | 5622 | if (power_well->always_on) |
| 5621 | continue; | 5623 | continue; |
| 5622 | 5624 | ||
| 5623 | if (!power_well->count) { | 5625 | if (!power_well->hw_enabled) { |
| 5624 | is_enabled = false; | 5626 | is_enabled = false; |
| 5625 | break; | 5627 | break; |
| 5626 | } | 5628 | } |
| 5627 | } | 5629 | } |
| 5630 | |||
| 5628 | return is_enabled; | 5631 | return is_enabled; |
| 5629 | } | 5632 | } |
| 5630 | 5633 | ||
| @@ -5632,30 +5635,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, | |||
| 5632 | enum intel_display_power_domain domain) | 5635 | enum intel_display_power_domain domain) |
| 5633 | { | 5636 | { |
| 5634 | struct i915_power_domains *power_domains; | 5637 | struct i915_power_domains *power_domains; |
| 5635 | struct i915_power_well *power_well; | 5638 | bool ret; |
| 5636 | bool is_enabled; | ||
| 5637 | int i; | ||
| 5638 | |||
| 5639 | if (dev_priv->pm.suspended) | ||
| 5640 | return false; | ||
| 5641 | 5639 | ||
| 5642 | power_domains = &dev_priv->power_domains; | 5640 | power_domains = &dev_priv->power_domains; |
| 5643 | 5641 | ||
| 5644 | is_enabled = true; | ||
| 5645 | |||
| 5646 | mutex_lock(&power_domains->lock); | 5642 | mutex_lock(&power_domains->lock); |
| 5647 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 5643 | 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); | 5644 | mutex_unlock(&power_domains->lock); |
| 5657 | 5645 | ||
| 5658 | return is_enabled; | 5646 | return ret; |
| 5659 | } | 5647 | } |
| 5660 | 5648 | ||
| 5661 | /* | 5649 | /* |
| @@ -5976,6 +5964,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, | |||
| 5976 | if (!power_well->count++) { | 5964 | if (!power_well->count++) { |
| 5977 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | 5965 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); |
| 5978 | power_well->ops->enable(dev_priv, power_well); | 5966 | power_well->ops->enable(dev_priv, power_well); |
| 5967 | power_well->hw_enabled = true; | ||
| 5979 | } | 5968 | } |
| 5980 | 5969 | ||
| 5981 | check_power_well_state(dev_priv, power_well); | 5970 | check_power_well_state(dev_priv, power_well); |
| @@ -6005,6 +5994,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
| 6005 | 5994 | ||
| 6006 | if (!--power_well->count && i915.disable_power_well) { | 5995 | if (!--power_well->count && i915.disable_power_well) { |
| 6007 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | 5996 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); |
| 5997 | power_well->hw_enabled = false; | ||
| 6008 | power_well->ops->disable(dev_priv, power_well); | 5998 | power_well->ops->disable(dev_priv, power_well); |
| 6009 | } | 5999 | } |
| 6010 | 6000 | ||
| @@ -6267,8 +6257,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv) | |||
| 6267 | int i; | 6257 | int i; |
| 6268 | 6258 | ||
| 6269 | mutex_lock(&power_domains->lock); | 6259 | mutex_lock(&power_domains->lock); |
| 6270 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) | 6260 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { |
| 6271 | power_well->ops->sync_hw(dev_priv, power_well); | 6261 | power_well->ops->sync_hw(dev_priv, power_well); |
| 6262 | power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, | ||
| 6263 | power_well); | ||
| 6264 | } | ||
| 6272 | mutex_unlock(&power_domains->lock); | 6265 | mutex_unlock(&power_domains->lock); |
| 6273 | } | 6266 | } |
| 6274 | 6267 | ||
