aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dpll_mgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dpll_mgr.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c109
1 files changed, 85 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 156f8e4cbe4c..b51ad2917dbe 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2566,6 +2566,7 @@ int icl_calc_dp_combo_pll_link(struct drm_i915_private *dev_priv,
2566 switch (index) { 2566 switch (index) {
2567 default: 2567 default:
2568 MISSING_CASE(index); 2568 MISSING_CASE(index);
2569 /* fall through */
2569 case 0: 2570 case 0:
2570 link_clock = 540000; 2571 link_clock = 540000;
2571 break; 2572 break;
@@ -2639,6 +2640,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
2639 switch (div1) { 2640 switch (div1) {
2640 default: 2641 default:
2641 MISSING_CASE(div1); 2642 MISSING_CASE(div1);
2643 /* fall through */
2642 case 2: 2644 case 2:
2643 hsdiv = 0; 2645 hsdiv = 0;
2644 break; 2646 break;
@@ -2812,25 +2814,31 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
2812 MG_PLL_SSC_FLLEN | 2814 MG_PLL_SSC_FLLEN |
2813 MG_PLL_SSC_STEPSIZE(ssc_stepsize); 2815 MG_PLL_SSC_STEPSIZE(ssc_stepsize);
2814 2816
2815 pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART; 2817 pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART |
2816 2818 MG_PLL_TDC_COLDST_IREFINT_EN |
2817 if (refclk_khz != 38400) { 2819 MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
2818 pll_state->mg_pll_tdc_coldst_bias |= 2820 MG_PLL_TDC_TDCOVCCORR_EN |
2819 MG_PLL_TDC_COLDST_IREFINT_EN | 2821 MG_PLL_TDC_TDCSEL(3);
2820 MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) | 2822
2821 MG_PLL_TDC_COLDST_COLDSTART | 2823 pll_state->mg_pll_bias = MG_PLL_BIAS_BIAS_GB_SEL(3) |
2822 MG_PLL_TDC_TDCOVCCORR_EN | 2824 MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
2823 MG_PLL_TDC_TDCSEL(3); 2825 MG_PLL_BIAS_BIAS_BONUS(10) |
2824 2826 MG_PLL_BIAS_BIASCAL_EN |
2825 pll_state->mg_pll_bias = MG_PLL_BIAS_BIAS_GB_SEL(3) | 2827 MG_PLL_BIAS_CTRIM(12) |
2826 MG_PLL_BIAS_INIT_DCOAMP(0x3F) | 2828 MG_PLL_BIAS_VREF_RDAC(4) |
2827 MG_PLL_BIAS_BIAS_BONUS(10) | 2829 MG_PLL_BIAS_IREFTRIM(iref_trim);
2828 MG_PLL_BIAS_BIASCAL_EN | 2830
2829 MG_PLL_BIAS_CTRIM(12) | 2831 if (refclk_khz == 38400) {
2830 MG_PLL_BIAS_VREF_RDAC(4) | 2832 pll_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
2831 MG_PLL_BIAS_IREFTRIM(iref_trim); 2833 pll_state->mg_pll_bias_mask = 0;
2834 } else {
2835 pll_state->mg_pll_tdc_coldst_bias_mask = -1U;
2836 pll_state->mg_pll_bias_mask = -1U;
2832 } 2837 }
2833 2838
2839 pll_state->mg_pll_tdc_coldst_bias &= pll_state->mg_pll_tdc_coldst_bias_mask;
2840 pll_state->mg_pll_bias &= pll_state->mg_pll_bias_mask;
2841
2834 return true; 2842 return true;
2835} 2843}
2836 2844
@@ -2897,6 +2905,7 @@ static i915_reg_t icl_pll_id_to_enable_reg(enum intel_dpll_id id)
2897 switch (id) { 2905 switch (id) {
2898 default: 2906 default:
2899 MISSING_CASE(id); 2907 MISSING_CASE(id);
2908 /* fall through */
2900 case DPLL_ID_ICL_DPLL0: 2909 case DPLL_ID_ICL_DPLL0:
2901 case DPLL_ID_ICL_DPLL1: 2910 case DPLL_ID_ICL_DPLL1:
2902 return CNL_DPLL_ENABLE(id); 2911 return CNL_DPLL_ENABLE(id);
@@ -2939,18 +2948,41 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
2939 case DPLL_ID_ICL_MGPLL4: 2948 case DPLL_ID_ICL_MGPLL4:
2940 port = icl_mg_pll_id_to_port(id); 2949 port = icl_mg_pll_id_to_port(id);
2941 hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port)); 2950 hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port));
2951 hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
2952
2942 hw_state->mg_clktop2_coreclkctl1 = 2953 hw_state->mg_clktop2_coreclkctl1 =
2943 I915_READ(MG_CLKTOP2_CORECLKCTL1(port)); 2954 I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
2955 hw_state->mg_clktop2_coreclkctl1 &=
2956 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
2957
2944 hw_state->mg_clktop2_hsclkctl = 2958 hw_state->mg_clktop2_hsclkctl =
2945 I915_READ(MG_CLKTOP2_HSCLKCTL(port)); 2959 I915_READ(MG_CLKTOP2_HSCLKCTL(port));
2960 hw_state->mg_clktop2_hsclkctl &=
2961 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
2962 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
2963 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
2964 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
2965
2946 hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port)); 2966 hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
2947 hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port)); 2967 hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
2948 hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port)); 2968 hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
2949 hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port)); 2969 hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port));
2950 hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port)); 2970 hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port));
2971
2951 hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port)); 2972 hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port));
2952 hw_state->mg_pll_tdc_coldst_bias = 2973 hw_state->mg_pll_tdc_coldst_bias =
2953 I915_READ(MG_PLL_TDC_COLDST_BIAS(port)); 2974 I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
2975
2976 if (dev_priv->cdclk.hw.ref == 38400) {
2977 hw_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
2978 hw_state->mg_pll_bias_mask = 0;
2979 } else {
2980 hw_state->mg_pll_tdc_coldst_bias_mask = -1U;
2981 hw_state->mg_pll_bias_mask = -1U;
2982 }
2983
2984 hw_state->mg_pll_tdc_coldst_bias &= hw_state->mg_pll_tdc_coldst_bias_mask;
2985 hw_state->mg_pll_bias &= hw_state->mg_pll_bias_mask;
2954 break; 2986 break;
2955 default: 2987 default:
2956 MISSING_CASE(id); 2988 MISSING_CASE(id);
@@ -2978,19 +3010,48 @@ static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
2978{ 3010{
2979 struct intel_dpll_hw_state *hw_state = &pll->state.hw_state; 3011 struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
2980 enum port port = icl_mg_pll_id_to_port(pll->info->id); 3012 enum port port = icl_mg_pll_id_to_port(pll->info->id);
3013 u32 val;
3014
3015 /*
3016 * Some of the following registers have reserved fields, so program
3017 * these with RMW based on a mask. The mask can be fixed or generated
3018 * during the calc/readout phase if the mask depends on some other HW
3019 * state like refclk, see icl_calc_mg_pll_state().
3020 */
3021 val = I915_READ(MG_REFCLKIN_CTL(port));
3022 val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
3023 val |= hw_state->mg_refclkin_ctl;
3024 I915_WRITE(MG_REFCLKIN_CTL(port), val);
3025
3026 val = I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
3027 val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
3028 val |= hw_state->mg_clktop2_coreclkctl1;
3029 I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port), val);
3030
3031 val = I915_READ(MG_CLKTOP2_HSCLKCTL(port));
3032 val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
3033 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
3034 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
3035 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
3036 val |= hw_state->mg_clktop2_hsclkctl;
3037 I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), val);
2981 3038
2982 I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
2983 I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
2984 hw_state->mg_clktop2_coreclkctl1);
2985 I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state->mg_clktop2_hsclkctl);
2986 I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0); 3039 I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
2987 I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1); 3040 I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
2988 I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf); 3041 I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
2989 I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock); 3042 I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock);
2990 I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc); 3043 I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc);
2991 I915_WRITE(MG_PLL_BIAS(port), hw_state->mg_pll_bias); 3044
2992 I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port), 3045 val = I915_READ(MG_PLL_BIAS(port));
2993 hw_state->mg_pll_tdc_coldst_bias); 3046 val &= ~hw_state->mg_pll_bias_mask;
3047 val |= hw_state->mg_pll_bias;
3048 I915_WRITE(MG_PLL_BIAS(port), val);
3049
3050 val = I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
3051 val &= ~hw_state->mg_pll_tdc_coldst_bias_mask;
3052 val |= hw_state->mg_pll_tdc_coldst_bias;
3053 I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port), val);
3054
2994 POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port)); 3055 POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port));
2995} 3056}
2996 3057