]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915: Extract some helpers to compute cdclk register values
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 30 Apr 2021 15:34:40 +0000 (18:34 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 5 May 2021 18:07:35 +0000 (21:07 +0300)
Extract a few of the switch statements into helper functions to
reduce the pollution in the cdclk programming functions.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210430153444.29270-2-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_cdclk.c

index f95896f7c113d052df0a361539f27fb18b486fb3..f089fd8ea0662e3422b11e4b353ceac5db3b69da 100644 (file)
@@ -724,6 +724,23 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
                bdw_calc_voltage_level(cdclk_config->cdclk);
 }
 
+static u32 bdw_cdclk_freq_sel(int cdclk)
+{
+       switch (cdclk) {
+       default:
+               MISSING_CASE(cdclk);
+               fallthrough;
+       case 337500:
+               return LCPLL_CLK_FREQ_337_5_BDW;
+       case 450000:
+               return LCPLL_CLK_FREQ_450;
+       case 540000:
+               return LCPLL_CLK_FREQ_54O_BDW;
+       case 675000:
+               return LCPLL_CLK_FREQ_675_BDW;
+       }
+}
+
 static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
@@ -763,25 +780,7 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 
        val = intel_de_read(dev_priv, LCPLL_CTL);
        val &= ~LCPLL_CLK_FREQ_MASK;
-
-       switch (cdclk) {
-       default:
-               MISSING_CASE(cdclk);
-               fallthrough;
-       case 337500:
-               val |= LCPLL_CLK_FREQ_337_5_BDW;
-               break;
-       case 450000:
-               val |= LCPLL_CLK_FREQ_450;
-               break;
-       case 540000:
-               val |= LCPLL_CLK_FREQ_54O_BDW;
-               break;
-       case 675000:
-               val |= LCPLL_CLK_FREQ_675_BDW;
-               break;
-       }
-
+       val |= bdw_cdclk_freq_sel(cdclk);
        intel_de_write(dev_priv, LCPLL_CTL, val);
 
        val = intel_de_read(dev_priv, LCPLL_CTL);
@@ -955,10 +954,8 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv,
                intel_update_max_cdclk(dev_priv);
 }
 
-static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
+static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco)
 {
-       u32 val;
-
        drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
 
        /*
@@ -970,17 +967,22 @@ static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
         * rate later on, with the constraint of choosing a frequency that
         * works with vco.
         */
+       if (vco == 8640000)
+               return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0);
+       else
+               return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0);
+}
+
+static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
+{
+       u32 val;
+
        val = intel_de_read(dev_priv, DPLL_CTRL1);
 
        val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
                 DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
        val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
-       if (vco == 8640000)
-               val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
-                                           SKL_DPLL0);
-       else
-               val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
-                                           SKL_DPLL0);
+       val |= skl_dpll0_link_rate(dev_priv, vco);
 
        intel_de_write(dev_priv, DPLL_CTRL1, val);
        intel_de_posting_read(dev_priv, DPLL_CTRL1);
@@ -1007,6 +1009,29 @@ static void skl_dpll0_disable(struct drm_i915_private *dev_priv)
        dev_priv->cdclk.hw.vco = 0;
 }
 
+static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
+                             int cdclk, int vco)
+{
+       switch (cdclk) {
+       default:
+               drm_WARN_ON(&dev_priv->drm,
+                           cdclk != dev_priv->cdclk.hw.bypass);
+               drm_WARN_ON(&dev_priv->drm, vco != 0);
+               fallthrough;
+       case 308571:
+       case 337500:
+               return CDCLK_FREQ_337_308;
+       case 450000:
+       case 432000:
+               return CDCLK_FREQ_450_432;
+       case 540000:
+               return CDCLK_FREQ_540;
+       case 617143:
+       case 675000:
+               return CDCLK_FREQ_675_617;
+       }
+}
+
 static void skl_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
@@ -1037,29 +1062,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
-       /* Choose frequency for this cdclk */
-       switch (cdclk) {
-       default:
-               drm_WARN_ON(&dev_priv->drm,
-                           cdclk != dev_priv->cdclk.hw.bypass);
-               drm_WARN_ON(&dev_priv->drm, vco != 0);
-               fallthrough;
-       case 308571:
-       case 337500:
-               freq_select = CDCLK_FREQ_337_308;
-               break;
-       case 450000:
-       case 432000:
-               freq_select = CDCLK_FREQ_450_432;
-               break;
-       case 540000:
-               freq_select = CDCLK_FREQ_540;
-               break;
-       case 617143:
-       case 675000:
-               freq_select = CDCLK_FREQ_675_617;
-               break;
-       }
+       freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco);
 
        if (dev_priv->cdclk.hw.vco != 0 &&
            dev_priv->cdclk.hw.vco != vco)
@@ -1550,13 +1553,40 @@ static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe
        }
 }
 
+static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
+                                 int cdclk, int vco)
+{
+       /* cdclk = vco / 2 / div{1,1.5,2,4} */
+       switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
+       default:
+               drm_WARN_ON(&dev_priv->drm,
+                           cdclk != dev_priv->cdclk.hw.bypass);
+               drm_WARN_ON(&dev_priv->drm, vco != 0);
+               fallthrough;
+       case 2:
+               return BXT_CDCLK_CD2X_DIV_SEL_1;
+       case 3:
+               drm_WARN(&dev_priv->drm,
+                        DISPLAY_VER(dev_priv) >= 10,
+                        "Unsupported divider\n");
+               return BXT_CDCLK_CD2X_DIV_SEL_1_5;
+       case 4:
+               return BXT_CDCLK_CD2X_DIV_SEL_2;
+       case 8:
+               drm_WARN(&dev_priv->drm,
+                        DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv),
+                        "Unsupported divider\n");
+               return BXT_CDCLK_CD2X_DIV_SEL_4;
+       }
+}
+
 static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
 {
        int cdclk = cdclk_config->cdclk;
        int vco = cdclk_config->vco;
-       u32 val, divider;
+       u32 val;
        int ret;
 
        /* Inform power controller of upcoming frequency change. */
@@ -1581,33 +1611,6 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
-       /* cdclk = vco / 2 / div{1,1.5,2,4} */
-       switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
-       default:
-               drm_WARN_ON(&dev_priv->drm,
-                           cdclk != dev_priv->cdclk.hw.bypass);
-               drm_WARN_ON(&dev_priv->drm, vco != 0);
-               fallthrough;
-       case 2:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       case 3:
-               drm_WARN(&dev_priv->drm,
-                        DISPLAY_VER(dev_priv) >= 10,
-                        "Unsupported divider\n");
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
-               break;
-       case 4:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_2;
-               break;
-       case 8:
-               drm_WARN(&dev_priv->drm,
-                        DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv),
-                        "Unsupported divider\n");
-               divider = BXT_CDCLK_CD2X_DIV_SEL_4;
-               break;
-       }
-
        if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
                if (dev_priv->cdclk.hw.vco != 0 &&
                    dev_priv->cdclk.hw.vco != vco)
@@ -1625,8 +1628,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                        bxt_de_pll_enable(dev_priv, vco);
        }
 
-       val = divider | skl_cdclk_decimal(cdclk) |
-               bxt_cdclk_cd2x_pipe(dev_priv, pipe);
+       val = bxt_cdclk_cd2x_div_sel(dev_priv, cdclk, vco) |
+               bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
+               skl_cdclk_decimal(cdclk);
 
        /*
         * Disable SSA Precharge when CD clock frequency < 500 MHz,
@@ -1712,23 +1716,9 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
        expected = skl_cdclk_decimal(cdclk);
 
        /* Figure out what CD2X divider we should be using for this cdclk */
-       switch (DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.vco,
-                                 dev_priv->cdclk.hw.cdclk)) {
-       case 2:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       case 3:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_1_5;
-               break;
-       case 4:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_2;
-               break;
-       case 8:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_4;
-               break;
-       default:
-               goto sanitize;
-       }
+       expected |= bxt_cdclk_cd2x_div_sel(dev_priv,
+                                          dev_priv->cdclk.hw.cdclk,
+                                          dev_priv->cdclk.hw.vco);
 
        /*
         * Disable SSA Precharge when CD clock frequency < 500 MHz,