From e2f425ef8a1cbd7d2c270891a3606f8ae89d8e67 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 9 Feb 2018 17:16:41 +0200 Subject: [PATCH] drm/i915: Save restore AUD_FREQ_CNTRL Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_runtime_pm.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7db3557b945c..11ff82cf62fe 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -985,6 +985,8 @@ struct drm_i915_private; struct i915_power_well; struct i915_power_well_ops { + void (*init)(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well); /* * Synchronize the well's hw state to match the current sw state, for * example enable/disable it based on the current refcount. Called @@ -2082,6 +2084,8 @@ struct drm_i915_private { */ struct mutex av_mutex; + u32 aud_freq; + struct { struct list_head list; struct llist_head free_list; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e9c79b560823..37f068a6d91c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8421,6 +8421,8 @@ enum { #define AUDIO_CP_READY(trans) ((1 << 1) << ((trans) * 4)) #define AUDIO_ELD_VALID(trans) ((1 << 0) << ((trans) * 4)) +#define SKL_AUD_FREQ_CNTRL _MMIO(0x65900) + #define HSW_AUD_CHICKENBIT _MMIO(0x65f10) #define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 70e659772a7a..f558997cadce 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -275,6 +275,14 @@ void intel_display_set_init_power(struct drm_i915_private *dev_priv, * to be enabled, and it will only be disabled if none of the registers is * requesting it to be enabled. */ + +static void hsw_power_well_init(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + if (INTEL_GEN(dev_priv) >= 9) + dev_priv->aud_freq = I915_READ(SKL_AUD_FREQ_CNTRL); +} + static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv, u8 irq_pipe_mask, bool has_vga) { @@ -410,6 +418,14 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, hsw_power_well_post_enable(dev_priv, power_well->hsw.irq_pipe_mask, power_well->hsw.has_vga); + + if (id == SKL_DISP_PW_2 && INTEL_GEN(dev_priv) >= 9) { + u32 aud_freq = I915_READ(SKL_AUD_FREQ_CNTRL); + + DRM_DEBUG_DRIVER("AUD_FREQ_CNTRL %08x -> %08x\n", + aud_freq, dev_priv->aud_freq); + I915_WRITE(SKL_AUD_FREQ_CNTRL, dev_priv->aud_freq); + } } static void hsw_power_well_disable(struct drm_i915_private *dev_priv, @@ -1931,6 +1947,7 @@ static struct i915_power_well i830_power_wells[] = { }; static const struct i915_power_well_ops hsw_power_well_ops = { + .init = hsw_power_well_init, .sync_hw = hsw_power_well_sync_hw, .enable = hsw_power_well_enable, .disable = hsw_power_well_disable, @@ -2610,6 +2627,19 @@ void intel_power_domains_fini(struct drm_i915_private *dev_priv) pm_runtime_put(kdev); } +static void intel_init_power_wells(struct drm_i915_private *dev_priv) +{ + struct i915_power_domains *power_domains = &dev_priv->power_domains; + struct i915_power_well *power_well; + + mutex_lock(&power_domains->lock); + for_each_power_well(dev_priv, power_well) { + if (power_well->ops->init) + power_well->ops->init(dev_priv, power_well); + } + mutex_unlock(&power_domains->lock); +} + static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv) { struct i915_power_domains *power_domains = &dev_priv->power_domains; @@ -3059,6 +3089,8 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) mutex_unlock(&power_domains->lock); } + intel_init_power_wells(dev_priv); + /* For now, we need the power well to be always enabled. */ intel_display_set_init_power(dev_priv, true); /* Disable power support if the user asked so. */ -- 2.13.2