drm/i915: Verify power domains after enabling them

After
commit 2cd9a689e9 ("drm/i915: Refactor intel_display_set_init_power() logic")
it makes more sense to check the power domain/well refcounts after
enabling the power domains functionality. Before that it's guaranteed
that most power wells (in the INIT domain) will have a reference held,
so not an interesting state.

While at it also add the check after the init_hw/fini_hw, disable and
suspend/resume steps. Make the test optional on a Kconfig option since
it may add substantial overhead: on VLV/CHV the corresponding PUNIT reg
access for each power well may take up to 20ms.

v2:
- Add the state check to more spots. (Chris)

v3:
- During suspend check the state before deiniting display core.
  Afterwards DC states are disabled (and so the dc_off power well is
  enabled) even though we don't hold a reference on it.
- Do the test conditionally based on a new Kconfig option. (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
[Add DRM_I915_DEBUG_RUNTIME_PM to welcome messages]
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180817145837.26592-1-imre.deak@intel.com
This commit is contained in:
Imre Deak 2018-08-16 22:34:14 +03:00
Родитель da4468a1aa
Коммит 6dfc4a8f13
5 изменённых файлов: 44 добавлений и 9 удалений

Просмотреть файл

@ -30,6 +30,7 @@ config DRM_I915_DEBUG
select SW_SYNC # signaling validation framework (igt/syncobj*)
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
select DRM_I915_SELFTEST
select DRM_I915_DEBUG_RUNTIME_PM
default n
help
Choose this option to turn on extra driver debugging that may affect
@ -167,3 +168,14 @@ config DRM_I915_DEBUG_VBLANK_EVADE
the vblank.
If in doubt, say "N".
config DRM_I915_DEBUG_RUNTIME_PM
bool "Enable extra state checking for runtime PM"
depends on DRM_I915
default n
help
Choose this option to turn on extra state checking for the
runtime PM functionality. This may introduce overhead during
driver loading, suspend and resume operations.
If in doubt, say "N"

Просмотреть файл

@ -1331,6 +1331,8 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv)
DRM_INFO("DRM_I915_DEBUG enabled\n");
if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
DRM_INFO("DRM_I915_DEBUG_GEM enabled\n");
if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM))
DRM_INFO("DRM_I915_DEBUG_RUNTIME_PM enabled\n");
}
/**

Просмотреть файл

@ -15905,8 +15905,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(dev_priv);
intel_fbc_init_pipe_state(dev_priv);
}

Просмотреть файл

@ -1966,7 +1966,6 @@ enum i915_drm_suspend_mode {
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_verify_state(struct drm_i915_private *dev_priv);
void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
void bxt_display_core_uninit(struct drm_i915_private *dev_priv);
void intel_runtime_pm_enable(struct drm_i915_private *dev_priv);

Просмотреть файл

@ -3716,6 +3716,8 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
cmn->desc->ops->disable(dev_priv, cmn);
}
static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
/**
* intel_power_domains_init_hw - initialize hardware power domain state
* @dev_priv: i915 device instance
@ -3767,6 +3769,8 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_sync_hw(dev_priv);
power_domains->initializing = false;
intel_power_domains_verify_state(dev_priv);
}
/**
@ -3788,6 +3792,8 @@ void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv)
/* Remove the refcount we took to keep power well support disabled. */
if (!i915_modparams.disable_power_well)
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(dev_priv);
}
/**
@ -3805,6 +3811,8 @@ void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv)
void intel_power_domains_enable(struct drm_i915_private *dev_priv)
{
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(dev_priv);
}
/**
@ -3817,6 +3825,8 @@ void intel_power_domains_enable(struct drm_i915_private *dev_priv)
void intel_power_domains_disable(struct drm_i915_private *dev_priv)
{
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(dev_priv);
}
/**
@ -3845,15 +3855,19 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
* firmware was inactive.
*/
if (!IS_GEN9_LP(dev_priv) && suspend_mode == I915_DRM_SUSPEND_IDLE &&
dev_priv->csr.dmc_payload != NULL)
dev_priv->csr.dmc_payload != NULL) {
intel_power_domains_verify_state(dev_priv);
return;
}
/*
* Even if power well support was disabled we still want to disable
* power wells if power domains must be deinitialized for suspend.
*/
if (!i915_modparams.disable_power_well)
if (!i915_modparams.disable_power_well) {
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(dev_priv);
}
if (IS_ICELAKE(dev_priv))
icl_display_core_uninit(dev_priv);
@ -3884,13 +3898,15 @@ void intel_power_domains_resume(struct drm_i915_private *dev_priv)
if (power_domains->display_core_suspended) {
intel_power_domains_init_hw(dev_priv, true);
power_domains->display_core_suspended = false;
return;
} else {
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
}
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(dev_priv);
}
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv)
{
struct i915_power_domains *power_domains = &dev_priv->power_domains;
@ -3919,7 +3935,7 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv)
* acquiring reference counts for any power wells in use and disabling the
* ones left on by BIOS but not required by any active output.
*/
void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
{
struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *power_well;
@ -3974,6 +3990,14 @@ void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
mutex_unlock(&power_domains->lock);
}
#else
static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
{
}
#endif
/**
* intel_runtime_pm_get - grab a runtime pm reference
* @dev_priv: i915 device instance