Re: [Intel-gfx] [PATCH 12/14] drm/i915: Add dkl phy pll calculations

2019-09-14 Thread Lucas De Marchi
On Fri, Sep 13, 2019 at 3:33 PM José Roberto de Souza
 wrote:
>
> The _pll_find_divisors and _calc_dkl_pll_state TGL versions are
> similar to ICL ones but the BSpec algorithm conversion from real to
> integer number plus the differences makes it easier and safer to
> implement it in new functions.
>
> BSpec: 49204


I remember doing a diff in the algorithm from icl -> tgl and
concluding otherwise:
besides the register name noise it was easier to do the other way
around and just
add the small differences to the existing code. Has the spec changed recently?

Lucas De Marchi

>
> Signed-off-by: Vandita Kulkarni 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c  |  29 ++-
>  drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 205 +-
>  2 files changed, 227 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 981e24120a87..521e5b2e6f1c 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1436,11 +1436,30 @@ static int icl_calc_mg_pll_link(struct 
> drm_i915_private *dev_priv,
>
> ref_clock = dev_priv->cdclk.hw.ref;
>
> -   m1 = pll_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
> -   m2_int = pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
> -   m2_frac = (pll_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) ?
> -   (pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_FRAC_MASK) >>
> -   MG_PLL_DIV0_FBDIV_FRAC_SHIFT : 0;
> +   if (INTEL_GEN(dev_priv) >= 12) {
> +   m1 = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK;
> +   m1 = m1 >> DKL_PLL_DIV0_FBPREDIV_SHIFT;
> +   m2_int = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK;
> +
> +   if (pll_state->mg_pll_bias & DKL_PLL_BIAS_FRAC_EN_H) {
> +   m2_frac = pll_state->mg_pll_bias &
> + DKL_PLL_BIAS_FBDIV_FRAC_MASK;
> +   m2_frac = m2_frac >> DKL_PLL_BIAS_FBDIV_SHIFT;
> +   } else {
> +   m2_frac = 0;
> +   }
> +   } else {
> +   m1 = pll_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
> +   m2_int = pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
> +
> +   if (pll_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) {
> +   m2_frac = pll_state->mg_pll_div0 &
> + MG_PLL_DIV0_FBDIV_FRAC_MASK;
> +   m2_frac = m2_frac >> MG_PLL_DIV0_FBDIV_FRAC_SHIFT;
> +   } else {
> +   m2_frac = 0;
> +   }
> +   }
>
> switch (pll_state->mg_clktop2_hsclkctl &
> MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK) {
> diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
> b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
> index 9304606c1c0a..25be6229b122 100644
> --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
> @@ -2605,6 +2605,202 @@ enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port 
> tc_port)
> return tc_port + DPLL_ID_ICL_MGPLL1;
>  }
>
> +static bool tgl_dkl_pll_find_divisors(int clock_khz, bool is_dp, bool 
> use_ssc,
> + u32 *target_dco_khz,
> + struct intel_dpll_hw_state *state)
> +{
> +   u32 dco_min_freq, dco_max_freq;
> +   int div1_vals[] = {7, 5, 3, 2};
> +   int i, div2;
> +
> +   dco_min_freq = is_dp ? 810 : use_ssc ? 800 : 7992000;
> +   dco_max_freq = is_dp ? 810 : 1000;
> +
> +   for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
> +   int div1 = div1_vals[i];
> +
> +   for (div2 = 10; div2 > 0; div2--) {
> +   int dco = div1 * div2 * clock_khz * 5;
> +   int inputsel, tlinedrv;
> +   u32 hsdiv;
> +
> +   if (dco < dco_min_freq || dco > dco_max_freq)
> +   continue;
> +
> +   state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
> +   state->mg_clktop2_coreclkctl1 =
> +   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(5);
> +
> +   tlinedrv = div2 >= 2 ? 1 : 2;
> +   inputsel = is_dp ? 0 : 1;
> +
> +   switch (div1) {
> +   default:
> +   MISSING_CASE(div1);
> +   /* fall through */
> +   case 2:
> +   hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2;
> +   break;
> +   case 3:
> +   hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3;
> +   break;
> + 

[Intel-gfx] [PATCH 12/14] drm/i915: Add dkl phy pll calculations

2019-09-13 Thread José Roberto de Souza
The _pll_find_divisors and _calc_dkl_pll_state TGL versions are
similar to ICL ones but the BSpec algorithm conversion from real to
integer number plus the differences makes it easier and safer to
implement it in new functions.

BSpec: 49204

Signed-off-by: Vandita Kulkarni 
Signed-off-by: José Roberto de Souza 
---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  29 ++-
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 205 +-
 2 files changed, 227 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 981e24120a87..521e5b2e6f1c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1436,11 +1436,30 @@ static int icl_calc_mg_pll_link(struct drm_i915_private 
*dev_priv,
 
ref_clock = dev_priv->cdclk.hw.ref;
 
-   m1 = pll_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
-   m2_int = pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
-   m2_frac = (pll_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) ?
-   (pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_FRAC_MASK) >>
-   MG_PLL_DIV0_FBDIV_FRAC_SHIFT : 0;
+   if (INTEL_GEN(dev_priv) >= 12) {
+   m1 = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK;
+   m1 = m1 >> DKL_PLL_DIV0_FBPREDIV_SHIFT;
+   m2_int = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK;
+
+   if (pll_state->mg_pll_bias & DKL_PLL_BIAS_FRAC_EN_H) {
+   m2_frac = pll_state->mg_pll_bias &
+ DKL_PLL_BIAS_FBDIV_FRAC_MASK;
+   m2_frac = m2_frac >> DKL_PLL_BIAS_FBDIV_SHIFT;
+   } else {
+   m2_frac = 0;
+   }
+   } else {
+   m1 = pll_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
+   m2_int = pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
+
+   if (pll_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) {
+   m2_frac = pll_state->mg_pll_div0 &
+ MG_PLL_DIV0_FBDIV_FRAC_MASK;
+   m2_frac = m2_frac >> MG_PLL_DIV0_FBDIV_FRAC_SHIFT;
+   } else {
+   m2_frac = 0;
+   }
+   }
 
switch (pll_state->mg_clktop2_hsclkctl &
MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK) {
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 9304606c1c0a..25be6229b122 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -2605,6 +2605,202 @@ enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port 
tc_port)
return tc_port + DPLL_ID_ICL_MGPLL1;
 }
 
+static bool tgl_dkl_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
+ u32 *target_dco_khz,
+ struct intel_dpll_hw_state *state)
+{
+   u32 dco_min_freq, dco_max_freq;
+   int div1_vals[] = {7, 5, 3, 2};
+   int i, div2;
+
+   dco_min_freq = is_dp ? 810 : use_ssc ? 800 : 7992000;
+   dco_max_freq = is_dp ? 810 : 1000;
+
+   for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
+   int div1 = div1_vals[i];
+
+   for (div2 = 10; div2 > 0; div2--) {
+   int dco = div1 * div2 * clock_khz * 5;
+   int inputsel, tlinedrv;
+   u32 hsdiv;
+
+   if (dco < dco_min_freq || dco > dco_max_freq)
+   continue;
+
+   state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
+   state->mg_clktop2_coreclkctl1 =
+   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(5);
+
+   tlinedrv = div2 >= 2 ? 1 : 2;
+   inputsel = is_dp ? 0 : 1;
+
+   switch (div1) {
+   default:
+   MISSING_CASE(div1);
+   /* fall through */
+   case 2:
+   hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2;
+   break;
+   case 3:
+   hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3;
+   break;
+   case 5:
+   hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5;
+   break;
+   case 7:
+   hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7;
+   break;
+   }
+
+   *target_dco_khz = dco;
+
+   state->mg_clktop2_hsclkctl =
+   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
+