@@ -2622,11 +2622,22 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
26222622 return true;
26232623}
26242624
2625+ /*
2626+ * Display WA #22010492432: tgl
2627+ * Program half of the nominal DCO divider fraction value.
2628+ */
2629+ static bool
2630+ tgl_combo_pll_div_frac_wa_needed (struct drm_i915_private * i915 )
2631+ {
2632+ return IS_TIGERLAKE (i915 ) && i915 -> dpll .ref_clks .nssc == 38400 ;
2633+ }
2634+
26252635static int __cnl_ddi_wrpll_get_freq (struct drm_i915_private * dev_priv ,
26262636 const struct intel_shared_dpll * pll ,
26272637 int ref_clock )
26282638{
26292639 const struct intel_dpll_hw_state * pll_state = & pll -> state .hw_state ;
2640+ u32 dco_fraction ;
26302641 u32 p0 , p1 , p2 , dco_freq ;
26312642
26322643 p0 = pll_state -> cfgcr1 & DPLL_CFGCR1_PDIV_MASK ;
@@ -2669,8 +2680,13 @@ static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
26692680 dco_freq = (pll_state -> cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK ) *
26702681 ref_clock ;
26712682
2672- dco_freq += (((pll_state -> cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK ) >>
2673- DPLL_CFGCR0_DCO_FRACTION_SHIFT ) * ref_clock ) / 0x8000 ;
2683+ dco_fraction = (pll_state -> cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK ) >>
2684+ DPLL_CFGCR0_DCO_FRACTION_SHIFT ;
2685+
2686+ if (tgl_combo_pll_div_frac_wa_needed (dev_priv ))
2687+ dco_fraction *= 2 ;
2688+
2689+ dco_freq += (dco_fraction * ref_clock ) / 0x8000 ;
26742690
26752691 if (drm_WARN_ON (& dev_priv -> drm , p0 == 0 || p1 == 0 || p2 == 0 ))
26762692 return 0 ;
@@ -2948,16 +2964,6 @@ static const struct skl_wrpll_params tgl_tbt_pll_24MHz_values = {
29482964 /* the following params are unused */
29492965};
29502966
2951- /*
2952- * Display WA #22010492432: tgl
2953- * Divide the nominal .dco_fraction value by 2.
2954- */
2955- static const struct skl_wrpll_params tgl_tbt_pll_38_4MHz_values = {
2956- .dco_integer = 0x54 , .dco_fraction = 0x1800 ,
2957- /* the following params are unused */
2958- .pdiv = 0 , .kdiv = 0 , .qdiv_mode = 0 , .qdiv_ratio = 0 ,
2959- };
2960-
29612967static bool icl_calc_dp_combo_pll (struct intel_crtc_state * crtc_state ,
29622968 struct skl_wrpll_params * pll_params )
29632969{
@@ -2991,14 +2997,12 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
29912997 MISSING_CASE (dev_priv -> dpll .ref_clks .nssc );
29922998 fallthrough ;
29932999 case 19200 :
3000+ case 38400 :
29943001 * pll_params = tgl_tbt_pll_19_2MHz_values ;
29953002 break ;
29963003 case 24000 :
29973004 * pll_params = tgl_tbt_pll_24MHz_values ;
29983005 break ;
2999- case 38400 :
3000- * pll_params = tgl_tbt_pll_38_4MHz_values ;
3001- break ;
30023006 }
30033007 } else {
30043008 switch (dev_priv -> dpll .ref_clks .nssc ) {
@@ -3065,9 +3069,14 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
30653069 const struct skl_wrpll_params * pll_params ,
30663070 struct intel_dpll_hw_state * pll_state )
30673071{
3072+ u32 dco_fraction = pll_params -> dco_fraction ;
3073+
30683074 memset (pll_state , 0 , sizeof (* pll_state ));
30693075
3070- pll_state -> cfgcr0 = DPLL_CFGCR0_DCO_FRACTION (pll_params -> dco_fraction ) |
3076+ if (tgl_combo_pll_div_frac_wa_needed (i915 ))
3077+ dco_fraction = DIV_ROUND_CLOSEST (dco_fraction , 2 );
3078+
3079+ pll_state -> cfgcr0 = DPLL_CFGCR0_DCO_FRACTION (dco_fraction ) |
30713080 pll_params -> dco_integer ;
30723081
30733082 pll_state -> cfgcr1 = DPLL_CFGCR1_QDIV_RATIO (pll_params -> qdiv_ratio ) |
0 commit comments