Commit 9fc59bae authored by Imre Deak's avatar Imre Deak

drm/i915/icl: Fix MG PLL setup when refclk is 38.4MHz

Atm we're zeroing out fields in MG_PLL_BIAS and MG_PLL_TDC_COLDST_BIAS
if refclk is 38.4MHz, whereas the spec tells us to preserve them.
Although the calculated values mostly match the register defaults even
for the 38.4MHz case, there are some differences wrt. what BIOS
programs (I noticed at least differences in the MG_PLL_BIAS/IREFTRIM and
MG_PLL_BIAS/BIASCAL_EN fields). In the lack of further info on how to
program these fields, just do what the spec says and preserve the BIOS
state.

v2:
- Preserve the BIOS programmed reg fields instead of programming them.

Cc: Vandita Kulkarni <vandita.kulkarni@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: James Ausmus <james.ausmus@intel.com> (v1)
Reviewed-by: default avatarVandita Kulkarni <vandita.kulkarni@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180615143911.31082-1-imre.deak@intel.com
parent 8a29c778
...@@ -2812,13 +2812,9 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, ...@@ -2812,13 +2812,9 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
MG_PLL_SSC_FLLEN | MG_PLL_SSC_FLLEN |
MG_PLL_SSC_STEPSIZE(ssc_stepsize); MG_PLL_SSC_STEPSIZE(ssc_stepsize);
pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART; pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART |
if (refclk_khz != 38400) {
pll_state->mg_pll_tdc_coldst_bias |=
MG_PLL_TDC_COLDST_IREFINT_EN | MG_PLL_TDC_COLDST_IREFINT_EN |
MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) | MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
MG_PLL_TDC_COLDST_COLDSTART |
MG_PLL_TDC_TDCOVCCORR_EN | MG_PLL_TDC_TDCOVCCORR_EN |
MG_PLL_TDC_TDCSEL(3); MG_PLL_TDC_TDCSEL(3);
...@@ -2829,8 +2825,18 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, ...@@ -2829,8 +2825,18 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
MG_PLL_BIAS_CTRIM(12) | MG_PLL_BIAS_CTRIM(12) |
MG_PLL_BIAS_VREF_RDAC(4) | MG_PLL_BIAS_VREF_RDAC(4) |
MG_PLL_BIAS_IREFTRIM(iref_trim); MG_PLL_BIAS_IREFTRIM(iref_trim);
if (refclk_khz == 38400) {
pll_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
pll_state->mg_pll_bias_mask = 0;
} else {
pll_state->mg_pll_tdc_coldst_bias_mask = -1U;
pll_state->mg_pll_bias_mask = -1U;
} }
pll_state->mg_pll_tdc_coldst_bias &= pll_state->mg_pll_tdc_coldst_bias_mask;
pll_state->mg_pll_bias &= pll_state->mg_pll_bias_mask;
return true; return true;
} }
...@@ -2948,9 +2954,21 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv, ...@@ -2948,9 +2954,21 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port)); hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port)); hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port));
hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port)); hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port));
hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port)); hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port));
hw_state->mg_pll_tdc_coldst_bias = hw_state->mg_pll_tdc_coldst_bias =
I915_READ(MG_PLL_TDC_COLDST_BIAS(port)); I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
if (dev_priv->cdclk.hw.ref == 38400) {
hw_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
hw_state->mg_pll_bias_mask = 0;
} else {
hw_state->mg_pll_tdc_coldst_bias_mask = -1U;
hw_state->mg_pll_bias_mask = -1U;
}
hw_state->mg_pll_tdc_coldst_bias &= hw_state->mg_pll_tdc_coldst_bias_mask;
hw_state->mg_pll_bias &= hw_state->mg_pll_bias_mask;
break; break;
default: default:
MISSING_CASE(id); MISSING_CASE(id);
...@@ -2978,6 +2996,7 @@ static void icl_mg_pll_write(struct drm_i915_private *dev_priv, ...@@ -2978,6 +2996,7 @@ static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
{ {
struct intel_dpll_hw_state *hw_state = &pll->state.hw_state; struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
enum port port = icl_mg_pll_id_to_port(pll->info->id); enum port port = icl_mg_pll_id_to_port(pll->info->id);
u32 val;
I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl); I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port), I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
...@@ -2988,9 +3007,17 @@ static void icl_mg_pll_write(struct drm_i915_private *dev_priv, ...@@ -2988,9 +3007,17 @@ static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf); I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock); I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock);
I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc); I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc);
I915_WRITE(MG_PLL_BIAS(port), hw_state->mg_pll_bias);
I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port), val = I915_READ(MG_PLL_BIAS(port));
hw_state->mg_pll_tdc_coldst_bias); val &= ~hw_state->mg_pll_bias_mask;
val |= hw_state->mg_pll_bias;
I915_WRITE(MG_PLL_BIAS(port), val);
val = I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
val &= ~hw_state->mg_pll_tdc_coldst_bias_mask;
val |= hw_state->mg_pll_tdc_coldst_bias;
I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port), val);
POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port)); POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port));
} }
......
...@@ -180,6 +180,8 @@ struct intel_dpll_hw_state { ...@@ -180,6 +180,8 @@ struct intel_dpll_hw_state {
uint32_t mg_pll_ssc; uint32_t mg_pll_ssc;
uint32_t mg_pll_bias; uint32_t mg_pll_bias;
uint32_t mg_pll_tdc_coldst_bias; uint32_t mg_pll_tdc_coldst_bias;
uint32_t mg_pll_bias_mask;
uint32_t mg_pll_tdc_coldst_bias_mask;
}; };
/** /**
......
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