mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 17:59:32 +00:00
drm/i915/gen9: Fix runtime PM refcounting in case DMC firmware isn't loaded
While we disable runtime PM and with that display power well support if the DMC firmware isn't loaded, we still want to disable power wells during system suspend and driver unload. So drop/reacquire the corresponding power refcount during suspend/resume and driver unloading. This also means we have to check if DMC is not loaded and skip enabling DC states in the power well code. v2: - Reuse intel_csr_ucode_suspend() in intel_csr_ucode_fini() instead of opencoding the former. (Chris) - Add docbook comment to the public resume and suspend functions. CC: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1460980101-14713-1-git-send-email-imre.deak@intel.com
This commit is contained in:
parent
bf93ba67e9
commit
f74ed08d55
4 changed files with 50 additions and 4 deletions
|
@ -640,8 +640,7 @@ static int i915_drm_suspend(struct drm_device *dev)
|
||||||
|
|
||||||
intel_display_set_init_power(dev_priv, false);
|
intel_display_set_init_power(dev_priv, false);
|
||||||
|
|
||||||
if (HAS_CSR(dev_priv))
|
intel_csr_ucode_suspend(dev_priv);
|
||||||
flush_work(&dev_priv->csr.work);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
enable_rpm_wakeref_asserts(dev_priv);
|
enable_rpm_wakeref_asserts(dev_priv);
|
||||||
|
@ -733,6 +732,8 @@ static int i915_drm_resume(struct drm_device *dev)
|
||||||
|
|
||||||
disable_rpm_wakeref_asserts(dev_priv);
|
disable_rpm_wakeref_asserts(dev_priv);
|
||||||
|
|
||||||
|
intel_csr_ucode_resume(dev_priv);
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
i915_gem_restore_gtt_mappings(dev);
|
i915_gem_restore_gtt_mappings(dev);
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
|
@ -466,11 +466,51 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
|
||||||
schedule_work(&dev_priv->csr.work);
|
schedule_work(&dev_priv->csr.work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_csr_ucode_suspend() - prepare CSR firmware before system suspend
|
||||||
|
* @dev_priv: i915 drm device
|
||||||
|
*
|
||||||
|
* Prepare the DMC firmware before entering system suspend. This includes
|
||||||
|
* flushing pending work items and releasing any resources acquired during
|
||||||
|
* init.
|
||||||
|
*/
|
||||||
|
void intel_csr_ucode_suspend(struct drm_i915_private *dev_priv)
|
||||||
|
{
|
||||||
|
if (!HAS_CSR(dev_priv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
flush_work(&dev_priv->csr.work);
|
||||||
|
|
||||||
|
/* Drop the reference held in case DMC isn't loaded. */
|
||||||
|
if (!dev_priv->csr.dmc_payload)
|
||||||
|
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_csr_ucode_resume() - init CSR firmware during system resume
|
||||||
|
* @dev_priv: i915 drm device
|
||||||
|
*
|
||||||
|
* Reinitialize the DMC firmware during system resume, reacquiring any
|
||||||
|
* resources released in intel_csr_ucode_suspend().
|
||||||
|
*/
|
||||||
|
void intel_csr_ucode_resume(struct drm_i915_private *dev_priv)
|
||||||
|
{
|
||||||
|
if (!HAS_CSR(dev_priv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reacquire the reference to keep RPM disabled in case DMC isn't
|
||||||
|
* loaded.
|
||||||
|
*/
|
||||||
|
if (!dev_priv->csr.dmc_payload)
|
||||||
|
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_csr_ucode_fini() - unload the CSR firmware.
|
* intel_csr_ucode_fini() - unload the CSR firmware.
|
||||||
* @dev_priv: i915 drm device.
|
* @dev_priv: i915 drm device.
|
||||||
*
|
*
|
||||||
* Firmmware unloading includes freeing the internal momory and reset the
|
* Firmmware unloading includes freeing the internal memory and reset the
|
||||||
* firmware loading status.
|
* firmware loading status.
|
||||||
*/
|
*/
|
||||||
void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
|
void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
|
||||||
|
@ -478,7 +518,7 @@ void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
|
||||||
if (!HAS_CSR(dev_priv))
|
if (!HAS_CSR(dev_priv))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flush_work(&dev_priv->csr.work);
|
intel_csr_ucode_suspend(dev_priv);
|
||||||
|
|
||||||
kfree(dev_priv->csr.dmc_payload);
|
kfree(dev_priv->csr.dmc_payload);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1275,6 +1275,8 @@ u32 skl_plane_ctl_rotation(unsigned int rotation);
|
||||||
void intel_csr_ucode_init(struct drm_i915_private *);
|
void intel_csr_ucode_init(struct drm_i915_private *);
|
||||||
void intel_csr_load_program(struct drm_i915_private *);
|
void intel_csr_load_program(struct drm_i915_private *);
|
||||||
void intel_csr_ucode_fini(struct drm_i915_private *);
|
void intel_csr_ucode_fini(struct drm_i915_private *);
|
||||||
|
void intel_csr_ucode_suspend(struct drm_i915_private *);
|
||||||
|
void intel_csr_ucode_resume(struct drm_i915_private *);
|
||||||
|
|
||||||
/* intel_dp.c */
|
/* intel_dp.c */
|
||||||
void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
|
void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
|
||||||
|
|
|
@ -809,6 +809,9 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
|
||||||
static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
|
static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
|
||||||
struct i915_power_well *power_well)
|
struct i915_power_well *power_well)
|
||||||
{
|
{
|
||||||
|
if (!dev_priv->csr.dmc_payload)
|
||||||
|
return;
|
||||||
|
|
||||||
if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
|
if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
|
||||||
skl_enable_dc6(dev_priv);
|
skl_enable_dc6(dev_priv);
|
||||||
else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
|
else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
|
||||||
|
|
Loading…
Reference in a new issue