From: Vandita Kulkarni <vandita.kulkarni@xxxxxxxxx> Reuse the existing calculate icl_calc_mg_pll_state() function. Since the pll variables are calculated differently for DKL phy, add support for the same. Signed-off-by: Vandita Kulkarni <vandita.kulkarni@xxxxxxxxx> Signed-off-by: Lucas De Marchi <lucas.demarchi@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 7eefd63a8b7e..3a1348ea6714 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -2625,7 +2625,8 @@ enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port) static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, u32 *target_dco_khz, - struct intel_dpll_hw_state *state) + struct intel_dpll_hw_state *state, + bool is_dkl) { u32 dco_min_freq, dco_max_freq; int div1_vals[] = {7, 5, 3, 2}; @@ -2647,8 +2648,13 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, continue; if (div2 >= 2) { - a_divratio = is_dp ? 10 : 5; - tlinedrv = 2; + if (is_dkl) { + a_divratio = 5; + tlinedrv = 1; + } else { + a_divratio = is_dp ? 10 : 5; + tlinedrv = 2; + } } else { a_divratio = 5; tlinedrv = 0; @@ -2698,7 +2704,8 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, * adapted to integer-only calculation, that's why it looks so different. */ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, - struct intel_dpll_hw_state *pll_state) + struct intel_dpll_hw_state *pll_state, + bool is_dkl) { struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); int refclk_khz = dev_priv->cdclk.hw.ref; @@ -2715,7 +2722,7 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, memset(pll_state, 0, sizeof(*pll_state)); if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz, - pll_state)) { + pll_state, is_dkl)) { DRM_DEBUG_KMS("Failed to find divisors for clock %d\n", clock); return false; } @@ -2723,8 +2730,11 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, m1div = 2; m2div_int = dco_khz / (refclk_khz * m1div); if (m2div_int > 255) { - m1div = 4; - m2div_int = dco_khz / (refclk_khz * m1div); + if (!is_dkl) { + m1div = 4; + m2div_int = dco_khz / (refclk_khz * m1div); + } + if (m2div_int > 255) { DRM_DEBUG_KMS("Failed to find mdiv for clock %d\n", clock); @@ -2753,6 +2763,12 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, iref_trim = 28; iref_pulse_w = 1; break; + + /* + * TODO: spec adds a case for ndiv = 4 when refclk > 80MHz, + * however this doesn't seem possible from the input. + * See Issue 17526. + */ default: MISSING_CASE(refclk_khz); return false; @@ -2805,7 +2821,31 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state, ssc_steplog = 4; /* write pll_state calculations */ - { + if (is_dkl) { + pll_state->mg_pll_div0 = + DKL_PLL_DIV0_INTEG_COEFF(int_coeff) | + DKL_PLL_DIV0_PROP_COEFF(prop_coeff) | + DKL_PLL_DIV0_FBPREDIV(m1div) | + DKL_PLL_DIV0_FBDIV_INT(m2div_int); + + pll_state->mg_pll_div1 = + DKL_PLL_DIV1_IREF_TRIM(iref_trim) | + DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt); + + pll_state->mg_pll_ssc = + DKL_PLL_SSC_IREF_NDIV_RATIO(iref_ndiv) | + DKL_PLL_SSC_STEP_LEN(ssc_steplen) | + DKL_PLL_SSC_STEP_NUM(ssc_steplog) | + (use_ssc ? DKL_PLL_SSC_EN : 0); + + pll_state->mg_pll_tdc_coldst_bias = + DKL_PLL_TDC_SSC_STEP_SIZE(ssc_stepsize) | + DKL_PLL_TDC_FEED_FWD_GAIN(feedfwgain); + + pll_state->mg_pll_bias = + (m2div_frac > 0 ? DKL_PLL_BIAS_FRAC_EN_H : 0) | + DKL_PLL_BIAS_FBDIV_FRAC(m2div_frac); + } else { pll_state->mg_pll_div0 = (m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) | MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) | @@ -2963,6 +3003,7 @@ static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); struct icl_port_dpll *port_dpll; enum intel_dpll_id dpll_id; + bool is_dkl = INTEL_GEN(dev_priv) >= 12; port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT]; if (!icl_calc_dpll_state(crtc_state, encoder, &port_dpll->hw_state)) { @@ -2983,7 +3024,7 @@ static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state, port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY]; - if (!icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state)) { + if (!icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state, is_dkl)) { DRM_DEBUG_KMS("Could not calculate MG PHY PLL state.\n"); goto err_unreference_tbt_pll; } -- 2.21.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx