Message ID | 1429174334-12089-4-git-send-email-animesh.manna@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On to, 2015-04-16 at 14:22 +0530, Animesh Manna wrote: > From: "A.Sunil Kamath" <sunil.kamath@intel.com> > > This patch just implements the basic enable and disable > functions of DC5 state which is needed for both SKL and BXT. > > Its important to load respective CSR program before calling > enable, which anyways will happen as CSR program is executed > during boot. > > DC5 is a power saving state where hardware dynamically disables > power well 1 and the CDCLK PLL and saves the associated registers. > > DC5 can be entered when software allows it, power well 2 is > disabled, and hardware detects that all pipes are disabled > or pipe A is enabled with PSR active. > > Its better to configure display engine to have power well 2 disabled before > getting into DC5 enable function. Hence rpm framework will have to > ensure to check status of power well 2 before calling gen9_enable_dc5. > > Rather dc5 entry criteria should be decided based on power well 2 status. > If disabled, then call gen9_enable_dc5. > > v2: Replace HAS_ with IS_ check as per Daniel's review comments > > v3: Cleared the bits dc5/dc6 enable of DC_STATE_EN register > before setting them as per Satheesh's review comments. > > v4: call POSTING_READ for every write to a register to ensure that > its written immediately. > > v5: Modified as per review comments from Imre. > - Squashed register definitions into this patch. > - Finetuned comments and functions. > > v6: > Avoid redundant writes in gen9_set_dc_state_debugmask_memory_up function. > > v7: > 1] Rebase to latest. > 2] Move all runtime PM functions defined in intel_display.c to > intel_runtime_pm.c. > > v8: Rebased to drm-intel-nightly. (Animesh) > > Issue: VIZ-2819 > Signed-off-by: A.Sunil Kamath <sunil.kamath@intel.com> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> > Signed-off-by: Animesh Manna <animesh.manna@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> > --- > drivers/gpu/drm/i915/i915_reg.h | 11 +++++++++ > drivers/gpu/drm/i915/intel_runtime_pm.c | 41 +++++++++++++++++++++++++++++++-- > 2 files changed, 50 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 596e8eb..dcb8528 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -6792,6 +6792,17 @@ enum skl_disp_power_wells { > #define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - SKL_DPLL1) * 8) > #define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - SKL_DPLL1) * 8) > > +/* > +* SKL DC > +*/ > +#define DC_STATE_EN 0x45504 > +#define DC_STATE_EN_UPTO_DC5 (1<<0) > +#define DC_STATE_EN_UPTO_DC6 (2<<0) > +#define DC_STATE_EN_UPTO_DC5_DC6_MASK 0x3 > + > +#define DC_STATE_DEBUG 0x45520 > +#define DC_STATE_DEBUG_MASK_MEMORY_UP (1<<1) > + > /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, > * since on HSW we can't write to it using I915_WRITE. */ > #define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c > index 23f02a8..466ea69 100644 > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c > @@ -321,14 +321,51 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, > SKL_DISPLAY_MISC_IO_POWER_DOMAINS)) | \ > BIT(POWER_DOMAIN_INIT)) > > +static void gen9_set_dc_state_debugmask_memory_up( > + struct drm_i915_private *dev_priv) > +{ > + uint32_t val; > + > + /* The below bit doesn't need to be cleared ever afterwards */ > + val = I915_READ(DC_STATE_DEBUG); > + if (!(val & DC_STATE_DEBUG_MASK_MEMORY_UP)) { > + val |= DC_STATE_DEBUG_MASK_MEMORY_UP; > + I915_WRITE(DC_STATE_DEBUG, val); > + POSTING_READ(DC_STATE_DEBUG); > + } > +} > + > static void gen9_enable_dc5(struct drm_i915_private *dev_priv) > { > - /* TODO: Implementation to be done. */ > + struct drm_device *dev = dev_priv->dev; > + uint32_t val; > + > + WARN_ON(!IS_GEN9(dev)); > + > + DRM_DEBUG_KMS("Enabling DC5\n"); > + > + gen9_set_dc_state_debugmask_memory_up(dev_priv); > + > + val = I915_READ(DC_STATE_EN); > + val &= ~DC_STATE_EN_UPTO_DC5_DC6_MASK; > + val |= DC_STATE_EN_UPTO_DC5; > + I915_WRITE(DC_STATE_EN, val); > + POSTING_READ(DC_STATE_EN); > } > > static void gen9_disable_dc5(struct drm_i915_private *dev_priv) > { > - /* TODO: Implementation to be done. */ > + struct drm_device *dev = dev_priv->dev; > + uint32_t val; > + > + WARN_ON(!IS_GEN9(dev)); > + > + DRM_DEBUG_KMS("Disabling DC5\n"); > + > + val = I915_READ(DC_STATE_EN); > + val &= ~DC_STATE_EN_UPTO_DC5; > + I915_WRITE(DC_STATE_EN, val); > + POSTING_READ(DC_STATE_EN); > } > > static void skl_set_power_well(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 596e8eb..dcb8528 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6792,6 +6792,17 @@ enum skl_disp_power_wells { #define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - SKL_DPLL1) * 8) #define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - SKL_DPLL1) * 8) +/* +* SKL DC +*/ +#define DC_STATE_EN 0x45504 +#define DC_STATE_EN_UPTO_DC5 (1<<0) +#define DC_STATE_EN_UPTO_DC6 (2<<0) +#define DC_STATE_EN_UPTO_DC5_DC6_MASK 0x3 + +#define DC_STATE_DEBUG 0x45520 +#define DC_STATE_DEBUG_MASK_MEMORY_UP (1<<1) + /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, * since on HSW we can't write to it using I915_WRITE. */ #define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 23f02a8..466ea69 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -321,14 +321,51 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, SKL_DISPLAY_MISC_IO_POWER_DOMAINS)) | \ BIT(POWER_DOMAIN_INIT)) +static void gen9_set_dc_state_debugmask_memory_up( + struct drm_i915_private *dev_priv) +{ + uint32_t val; + + /* The below bit doesn't need to be cleared ever afterwards */ + val = I915_READ(DC_STATE_DEBUG); + if (!(val & DC_STATE_DEBUG_MASK_MEMORY_UP)) { + val |= DC_STATE_DEBUG_MASK_MEMORY_UP; + I915_WRITE(DC_STATE_DEBUG, val); + POSTING_READ(DC_STATE_DEBUG); + } +} + static void gen9_enable_dc5(struct drm_i915_private *dev_priv) { - /* TODO: Implementation to be done. */ + struct drm_device *dev = dev_priv->dev; + uint32_t val; + + WARN_ON(!IS_GEN9(dev)); + + DRM_DEBUG_KMS("Enabling DC5\n"); + + gen9_set_dc_state_debugmask_memory_up(dev_priv); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_UPTO_DC5_DC6_MASK; + val |= DC_STATE_EN_UPTO_DC5; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); } static void gen9_disable_dc5(struct drm_i915_private *dev_priv) { - /* TODO: Implementation to be done. */ + struct drm_device *dev = dev_priv->dev; + uint32_t val; + + WARN_ON(!IS_GEN9(dev)); + + DRM_DEBUG_KMS("Disabling DC5\n"); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_UPTO_DC5; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); } static void skl_set_power_well(struct drm_i915_private *dev_priv,