Commit 53421c2f authored by Lucas De Marchi's avatar Lucas De Marchi Committed by Rodrigo Vivi

drm/i915: Apply Display WA #1183 on skl, kbl, and cfl

Display WA #1183 was recently added to workaround
"Failures when enabling DPLL0 with eDP link rate 2.16
or 4.32 GHz and CD clock frequency 308.57 or 617.14 MHz
(CDCLK_CTL CD Frequency Select 10b or 11b) used in this
 enabling or in previous enabling."

This workaround was designed to minimize the impact only
to save the bad case with that link rates. But HW engineers
indicated that it should be safe to apply broadly, although
they were expecting the DPLL0 link rate to be unchanged on
runtime.

We need to cover 2 cases: when we are in fact enabling DPLL0
and when we are just changing the frequency with small
differences.

This is based on previous patch by Rodrigo Vivi with suggestions
from Ville Syrjälä.

Cc: Arthur J Runyan <arthur.j.runyan@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171204232210.4958-1-lucas.demarchi@intel.com
parent cfe4982c
...@@ -7029,6 +7029,7 @@ enum { ...@@ -7029,6 +7029,7 @@ enum {
#define RESET_PCH_HANDSHAKE_ENABLE (1<<4) #define RESET_PCH_HANDSHAKE_ENABLE (1<<4)
#define GEN8_CHICKEN_DCPR_1 _MMIO(0x46430) #define GEN8_CHICKEN_DCPR_1 _MMIO(0x46430)
#define SKL_SELECT_ALTERNATE_DC_EXIT (1<<30)
#define MASK_WAKEMEM (1<<13) #define MASK_WAKEMEM (1<<13)
#define SKL_DFSM _MMIO(0x51000) #define SKL_DFSM _MMIO(0x51000)
...@@ -8585,6 +8586,7 @@ enum skl_power_gate { ...@@ -8585,6 +8586,7 @@ enum skl_power_gate {
#define BXT_CDCLK_CD2X_DIV_SEL_2 (2<<22) #define BXT_CDCLK_CD2X_DIV_SEL_2 (2<<22)
#define BXT_CDCLK_CD2X_DIV_SEL_4 (3<<22) #define BXT_CDCLK_CD2X_DIV_SEL_4 (3<<22)
#define BXT_CDCLK_CD2X_PIPE(pipe) ((pipe)<<20) #define BXT_CDCLK_CD2X_PIPE(pipe) ((pipe)<<20)
#define CDCLK_DIVMUX_CD_OVERRIDE (1<<19)
#define BXT_CDCLK_CD2X_PIPE_NONE BXT_CDCLK_CD2X_PIPE(3) #define BXT_CDCLK_CD2X_PIPE_NONE BXT_CDCLK_CD2X_PIPE(3)
#define BXT_CDCLK_SSA_PRECHARGE_ENABLE (1<<16) #define BXT_CDCLK_SSA_PRECHARGE_ENABLE (1<<16)
#define CDCLK_FREQ_DECIMAL_MASK (0x7ff) #define CDCLK_FREQ_DECIMAL_MASK (0x7ff)
......
...@@ -931,16 +931,10 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, ...@@ -931,16 +931,10 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv,
static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco) static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
{ {
int min_cdclk = skl_calc_cdclk(0, vco);
u32 val; u32 val;
WARN_ON(vco != 8100000 && vco != 8640000); WARN_ON(vco != 8100000 && vco != 8640000);
/* select the minimum CDCLK before enabling DPLL 0 */
val = CDCLK_FREQ_337_308 | skl_cdclk_decimal(min_cdclk);
I915_WRITE(CDCLK_CTL, val);
POSTING_READ(CDCLK_CTL);
/* /*
* We always enable DPLL0 with the lowest link rate possible, but still * We always enable DPLL0 with the lowest link rate possible, but still
* taking into account the VCO required to operate the eDP panel at the * taking into account the VCO required to operate the eDP panel at the
...@@ -994,7 +988,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -994,7 +988,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
{ {
int cdclk = cdclk_state->cdclk; int cdclk = cdclk_state->cdclk;
int vco = cdclk_state->vco; int vco = cdclk_state->vco;
u32 freq_select; u32 freq_select, cdclk_ctl;
int ret; int ret;
mutex_lock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->pcu_lock);
...@@ -1009,7 +1003,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -1009,7 +1003,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
return; return;
} }
/* set CDCLK_CTL */ /* Choose frequency for this cdclk */
switch (cdclk) { switch (cdclk) {
default: default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref); WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
...@@ -1036,10 +1030,33 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -1036,10 +1030,33 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
dev_priv->cdclk.hw.vco != vco) dev_priv->cdclk.hw.vco != vco)
skl_dpll0_disable(dev_priv); skl_dpll0_disable(dev_priv);
cdclk_ctl = I915_READ(CDCLK_CTL);
if (dev_priv->cdclk.hw.vco != vco) {
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
I915_WRITE(CDCLK_CTL, cdclk_ctl);
}
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl |= CDCLK_DIVMUX_CD_OVERRIDE;
I915_WRITE(CDCLK_CTL, cdclk_ctl);
POSTING_READ(CDCLK_CTL);
if (dev_priv->cdclk.hw.vco != vco) if (dev_priv->cdclk.hw.vco != vco)
skl_dpll0_enable(dev_priv, vco); skl_dpll0_enable(dev_priv, vco);
I915_WRITE(CDCLK_CTL, freq_select | skl_cdclk_decimal(cdclk)); /* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
I915_WRITE(CDCLK_CTL, cdclk_ctl);
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
I915_WRITE(CDCLK_CTL, cdclk_ctl);
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~CDCLK_DIVMUX_CD_OVERRIDE;
I915_WRITE(CDCLK_CTL, cdclk_ctl);
POSTING_READ(CDCLK_CTL); POSTING_READ(CDCLK_CTL);
/* inform PCU of the change */ /* inform PCU of the change */
......
...@@ -600,6 +600,11 @@ void gen9_enable_dc5(struct drm_i915_private *dev_priv) ...@@ -600,6 +600,11 @@ void gen9_enable_dc5(struct drm_i915_private *dev_priv)
DRM_DEBUG_KMS("Enabling DC5\n"); DRM_DEBUG_KMS("Enabling DC5\n");
/* Wa Display #1183: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv))
I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
SKL_SELECT_ALTERNATE_DC_EXIT);
gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5); gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5);
} }
...@@ -627,6 +632,11 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv) ...@@ -627,6 +632,11 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
{ {
DRM_DEBUG_KMS("Disabling DC6\n"); DRM_DEBUG_KMS("Disabling DC6\n");
/* Wa Display #1183: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv))
I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
SKL_SELECT_ALTERNATE_DC_EXIT);
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment