From d946bc44aa0bf03ff5c2888e8c3be8646e14467a Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 2 Feb 2022 12:42:49 +0200 Subject: [PATCH] drm/i915: Disable unused power wells left enabled by BIOS MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Make sure all unused power wells left enabled by BIOS get disabled during driver loading and system resume. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5028 Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220202104249.2680843-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ drivers/gpu/drm/i915/display/intel_display_power.c | 31 ++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_display_power.h | 1 + 3 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 01e8cea..c3b91e6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -10664,6 +10664,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev, } intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); + + intel_power_domains_sanitize_state(dev_priv); } void intel_display_resume(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 3693178..d2102cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -6214,6 +6214,37 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915) } /** + * intel_power_domains_sanitize_state - sanitize power domains state + * @i915: i915 device instance + * + * Sanitize the power domains state during driver loading and system resume. + * The function will disable all display power wells that BIOS has enabled + * without a user for it (any user for a power well has taken a reference + * on it by the time this function is called, after the state of all the + * pipe, encoder, etc. HW resources have been sanitized). + */ +void intel_power_domains_sanitize_state(struct drm_i915_private *i915) +{ + struct i915_power_domains *power_domains = &i915->power_domains; + struct i915_power_well *power_well; + + mutex_lock(&power_domains->lock); + + for_each_power_well_reverse(i915, power_well) { + if (power_well->desc->always_on || power_well->count || + !power_well->desc->ops->is_enabled(i915, power_well)) + continue; + + drm_dbg_kms(&i915->drm, + "BIOS left unused %s power well enabled, disabling it\n", + power_well->desc->name); + intel_power_well_disable(i915, power_well); + } + + mutex_unlock(&power_domains->lock); +} + +/** * intel_power_domains_enable - enable toggling of display power wells * @i915: i915 device instance * diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 930be3a0..f6d0e6e7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -218,6 +218,7 @@ void intel_power_domains_disable(struct drm_i915_private *dev_priv); void intel_power_domains_suspend(struct drm_i915_private *dev_priv, enum i915_drm_suspend_mode); void intel_power_domains_resume(struct drm_i915_private *dev_priv); +void intel_power_domains_sanitize_state(struct drm_i915_private *dev_priv); void intel_display_power_suspend_late(struct drm_i915_private *i915); void intel_display_power_resume_early(struct drm_i915_private *i915); -- 2.7.4