[Intel-gfx] [PATCH 1/5] drm/i915: Extract some helpers to compute cdclk register values

Ville Syrjala ville.syrjala at linux.intel.com
Fri Apr 30 15:34:40 UTC 2021


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

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 at linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 186 ++++++++++-----------
 1 file changed, 88 insertions(+), 98 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 1f0bd23bb883..d5314f9acf83 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -723,6 +723,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)
@@ -762,25 +779,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);
@@ -954,10 +953,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);
 
 	/*
@@ -969,17 +966,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);
@@ -1006,6 +1008,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)
@@ -1036,29 +1061,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)
@@ -1549,13 +1552,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. */
@@ -1580,33 +1610,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)
@@ -1624,8 +1627,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,
@@ -1711,23 +1715,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,
-- 
2.26.3



More information about the Intel-gfx mailing list