Before extending this to SKL let's document DVFS a bit. Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_cdclk.c | 55 ++++++++++++++++++++++++++++++----- drivers/gpu/drm/i915/intel_dpll_mgr.c | 16 +++++----- drivers/gpu/drm/i915/intel_drv.h | 8 ++--- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 8111a13079e1..58ee4dd07cf6 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -1510,7 +1510,22 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco) dev_priv->cdclk.hw.vco = vco; } -int cnl_dvfs_pre_change(struct drm_i915_private *dev_priv) +/** + * DOC: Display Voltage and Frequency Switching (DVFS) + * + * DVFS is used to adjust the display voltage to match the display clock + * frequencies. To save power the voltage is set to minimum when disabling PLL. + * + */ + +/** + * intel_dvfs_pre_change - (DVFS) Sequence Before Frequency Change + * @dev_priv: i915 device + * + * The sequence before frequency change is the following and it requests + * the power controller to raise voltage to maximum + */ +int intel_dvfs_pre_change(struct drm_i915_private *dev_priv) { int ret; @@ -1528,14 +1543,31 @@ int cnl_dvfs_pre_change(struct drm_i915_private *dev_priv) return ret; } -void cnl_dvfs_post_change(struct drm_i915_private *dev_priv, int level) +/** + * intel_dvfs_post_change - (DVFS) Sequence After Frequency Change + * @dev_priv: i915 device + * @level: New desired voltage-frequency level. + * + * The sequence after frequency change is the following and it requests + * the port controller to lower voltage to the minimum. + */ +void intel_dvfs_post_change(struct drm_i915_private *dev_priv, int level) { mutex_lock(&dev_priv->rps.hw_lock); sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, level); mutex_unlock(&dev_priv->rps.hw_lock); } -int cnl_dvfs_new_level(int cdclk, int portclk) +/** + * intel_dvfs_new_level - DVFS get new level. + * @cdclk: CD Clock. + * @portclk: Link rate. Optional argument. When 0, only cdclk is enough. + * + * Returns: + * New required level that should be informed to pcode + * based on @cdclk and on @portclk, if available. + */ +int intel_dvfs_new_level(int cdclk, int portclk) { if (cdclk == 168000 && portclk <= 594000) return 0; @@ -1545,7 +1577,16 @@ int cnl_dvfs_new_level(int cdclk, int portclk) return 2; } -bool cnl_dvfs_needs_change(struct drm_i915_private *dev_priv, int level) +/** + * intel_dvfs_needs_change - DVFS needs change. + * @dev_priv: i915 device + * @level: New desired voltage-frequency level. + * + * Returns: + * True if current level known by pcode is different of the + * new desired one. + */ +bool intel_dvfs_needs_change(struct drm_i915_private *dev_priv, int level) { int old_level; @@ -1562,7 +1603,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, int vco = cdclk_state->vco; u32 val, divider, level; - if (cnl_dvfs_pre_change(dev_priv)) + if (intel_dvfs_pre_change(dev_priv)) return; /* cdclk = vco / 2 / div{1,2} */ @@ -1597,8 +1638,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, I915_WRITE(CDCLK_CTL, val); /* inform PCU of the change */ - level = cnl_dvfs_new_level(cdclk, 0); - cnl_dvfs_post_change(dev_priv, level); + level = intel_dvfs_new_level(cdclk, 0); + intel_dvfs_post_change(dev_priv, level); intel_update_cdclk(dev_priv); } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 4eb1be91a669..55997389a29f 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -2014,10 +2014,10 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, */ cdclk = dev_priv->cdclk.hw.cdclk; portclk = intel_ddi_port_clock(dev_priv, pll->id); - level = cnl_dvfs_new_level(cdclk, portclk); - change_level = cnl_dvfs_needs_change(dev_priv, level); + level = intel_dvfs_new_level(cdclk, portclk); + change_level = intel_dvfs_needs_change(dev_priv, level); if (change_level) - ret = cnl_dvfs_pre_change(dev_priv); + ret = intel_dvfs_pre_change(dev_priv); /* 6. Enable DPLL in DPLL_ENABLE. */ val = I915_READ(CNL_DPLL_ENABLE(pll->id)); @@ -2038,7 +2038,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, * (DVFS) Sequence After Frequency Change */ if (change_level && ret == 0) - cnl_dvfs_post_change(dev_priv, level); + intel_dvfs_post_change(dev_priv, level); /* * 9. turn on the clock for the DDI and map the DPLL to the DDI @@ -2065,10 +2065,10 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv, * (DVFS) Sequence Before Frequency Change */ cdclk = dev_priv->cdclk.hw.cdclk; - level = cnl_dvfs_new_level(cdclk, 0); - change_level = cnl_dvfs_needs_change(dev_priv, level); + level = intel_dvfs_new_level(cdclk, 0); + change_level = intel_dvfs_needs_change(dev_priv, level); if (change_level) - ret = cnl_dvfs_pre_change(dev_priv); + ret = intel_dvfs_pre_change(dev_priv); /* 3. Disable DPLL through DPLL_ENABLE. */ val = I915_READ(CNL_DPLL_ENABLE(pll->id)); @@ -2089,7 +2089,7 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv, * (DVFS) Sequence After Frequency Change */ if (change_level && ret == 0) - cnl_dvfs_post_change(dev_priv, level); + intel_dvfs_post_change(dev_priv, level); /* 6. Disable DPLL power in DPLL_ENABLE. */ val = I915_READ(CNL_DPLL_ENABLE(pll->id)); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8621110401e3..567b6e846a69 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1323,10 +1323,10 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv); void skl_uninit_cdclk(struct drm_i915_private *dev_priv); void cnl_init_cdclk(struct drm_i915_private *dev_priv); void cnl_uninit_cdclk(struct drm_i915_private *dev_priv); -int cnl_dvfs_pre_change(struct drm_i915_private *dev_priv); -void cnl_dvfs_post_change(struct drm_i915_private *dev_priv, int level); -int cnl_dvfs_new_level(int cdclk, int portclk); -bool cnl_dvfs_needs_change(struct drm_i915_private *dev_priv, int level); +int intel_dvfs_pre_change(struct drm_i915_private *dev_priv); +void intel_dvfs_post_change(struct drm_i915_private *dev_priv, int level); +int intel_dvfs_new_level(int cdclk, int portclk); +bool intel_dvfs_needs_change(struct drm_i915_private *dev_priv, int level); void bxt_init_cdclk(struct drm_i915_private *dev_priv); void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); -- 2.13.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx