diff options
author | José Roberto de Souza <jose.souza@intel.com> | 2022-02-16 05:40:59 -0800 |
---|---|---|
committer | José Roberto de Souza <jose.souza@intel.com> | 2022-02-18 06:35:44 -0800 |
commit | b70ad01a22176b6d903e9cb2f2184c2aa67ecee0 (patch) | |
tree | 13fb4f32bfb37490a6ab01f6fac8b858c266ff56 /drivers/gpu/drm/i915/display/intel_dpll_mgr.c | |
parent | drm/i915: Disconnect PHYs left connected by BIOS on disabled ports (diff) | |
download | linux-dev-b70ad01a22176b6d903e9cb2f2184c2aa67ecee0.tar.xz linux-dev-b70ad01a22176b6d903e9cb2f2184c2aa67ecee0.zip |
drm/i915/display/tgl+: Implement new PLL programming step
A new programming step was added to combo and TC PLL sequences.
If override_AFC_startup is set in VBT, driver should overwrite
AFC_startup value to 0x0 or 0x7 in PLL's div0 register.
The current understating is that only TGL needs this and all other
display 12 and newer platforms will have a older VBT or a newer VBT
with override_AFC_startup set to 0 but in any case there is a
drm_warn_on_once() to let us know if this is not true.
v2:
- specification updated, now AFC can be override to 0x0 or 0x7
- not using a union for div0 (Imre)
- following previous wrong vbt naming: bits instead of bytes (Imre)
BSpec: 49204
BSpec: 20122
BSpec: 49968
BSpec: 71360
Cc: Imre Deak <imre.deak@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220216134059.25348-1-jose.souza@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dpll_mgr.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 6723c3de5a80..569903d47aea 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -2748,6 +2748,9 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915, pll_state->cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL; else pll_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400; + + if (i915->vbt.override_afc_startup) + pll_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->vbt.override_afc_startup_val); } static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, @@ -2949,6 +2952,11 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, DKL_PLL_DIV0_PROP_COEFF(prop_coeff) | DKL_PLL_DIV0_FBPREDIV(m1div) | DKL_PLL_DIV0_FBDIV_INT(m2div_int); + if (dev_priv->vbt.override_afc_startup) { + u8 val = dev_priv->vbt.override_afc_startup_val; + + pll_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val); + } pll_state->mg_pll_div1 = DKL_PLL_DIV1_IREF_TRIM(iref_trim) | DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt); @@ -3448,10 +3456,10 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv, MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK; hw_state->mg_pll_div0 = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port)); - hw_state->mg_pll_div0 &= (DKL_PLL_DIV0_INTEG_COEFF_MASK | - DKL_PLL_DIV0_PROP_COEFF_MASK | - DKL_PLL_DIV0_FBPREDIV_MASK | - DKL_PLL_DIV0_FBDIV_INT_MASK); + val = DKL_PLL_DIV0_MASK; + if (dev_priv->vbt.override_afc_startup) + val |= DKL_PLL_DIV0_AFC_STARTUP_MASK; + hw_state->mg_pll_div0 &= val; hw_state->mg_pll_div1 = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port)); hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK | @@ -3513,6 +3521,10 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv, TGL_DPLL_CFGCR0(id)); hw_state->cfgcr1 = intel_de_read(dev_priv, TGL_DPLL_CFGCR1(id)); + if (dev_priv->vbt.override_afc_startup) { + hw_state->div0 = intel_de_read(dev_priv, TGL_DPLL0_DIV0(id)); + hw_state->div0 &= TGL_DPLL0_DIV0_AFC_STARTUP_MASK; + } } else { if (IS_JSL_EHL(dev_priv) && id == DPLL_ID_EHL_DPLL4) { hw_state->cfgcr0 = intel_de_read(dev_priv, @@ -3554,7 +3566,7 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv, { struct intel_dpll_hw_state *hw_state = &pll->state.hw_state; const enum intel_dpll_id id = pll->info->id; - i915_reg_t cfgcr0_reg, cfgcr1_reg; + i915_reg_t cfgcr0_reg, cfgcr1_reg, div0_reg = INVALID_MMIO_REG; if (IS_ALDERLAKE_S(dev_priv)) { cfgcr0_reg = ADLS_DPLL_CFGCR0(id); @@ -3568,6 +3580,7 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv, } else if (DISPLAY_VER(dev_priv) >= 12) { cfgcr0_reg = TGL_DPLL_CFGCR0(id); cfgcr1_reg = TGL_DPLL_CFGCR1(id); + div0_reg = TGL_DPLL0_DIV0(id); } else { if (IS_JSL_EHL(dev_priv) && id == DPLL_ID_EHL_DPLL4) { cfgcr0_reg = ICL_DPLL_CFGCR0(4); @@ -3580,6 +3593,12 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv, intel_de_write(dev_priv, cfgcr0_reg, hw_state->cfgcr0); intel_de_write(dev_priv, cfgcr1_reg, hw_state->cfgcr1); + drm_WARN_ON_ONCE(&dev_priv->drm, dev_priv->vbt.override_afc_startup && + !i915_mmio_reg_valid(div0_reg)); + if (dev_priv->vbt.override_afc_startup && + i915_mmio_reg_valid(div0_reg)) + intel_de_rmw(dev_priv, div0_reg, TGL_DPLL0_DIV0_AFC_STARTUP_MASK, + hw_state->div0); intel_de_posting_read(dev_priv, cfgcr1_reg); } @@ -3667,13 +3686,11 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv, val |= hw_state->mg_clktop2_hsclkctl; intel_de_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val); - val = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port)); - val &= ~(DKL_PLL_DIV0_INTEG_COEFF_MASK | - DKL_PLL_DIV0_PROP_COEFF_MASK | - DKL_PLL_DIV0_FBPREDIV_MASK | - DKL_PLL_DIV0_FBDIV_INT_MASK); - val |= hw_state->mg_pll_div0; - intel_de_write(dev_priv, DKL_PLL_DIV0(tc_port), val); + val = DKL_PLL_DIV0_MASK; + if (dev_priv->vbt.override_afc_startup) + val |= DKL_PLL_DIV0_AFC_STARTUP_MASK; + intel_de_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val, + hw_state->mg_pll_div0); val = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port)); val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK | @@ -3912,13 +3929,14 @@ static void icl_dump_hw_state(struct drm_i915_private *dev_priv, const struct intel_dpll_hw_state *hw_state) { drm_dbg_kms(&dev_priv->drm, - "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, " + "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, div0: 0x%x, " "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, " "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, " "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, " "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, " "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n", hw_state->cfgcr0, hw_state->cfgcr1, + hw_state->div0, hw_state->mg_refclkin_ctl, hw_state->mg_clktop2_coreclkctl1, hw_state->mg_clktop2_hsclkctl, |