All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matt Roper <matthew.d.roper@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Subject: [PATCH v2 1/2] drm/i915: Allow /2 CD2X divider on gen11+
Date: Thu, 29 Aug 2019 17:48:28 -0700	[thread overview]
Message-ID: <20190830004828.19359-1-matthew.d.roper@intel.com> (raw)
In-Reply-To: <20190827135250.GA7482@intel.com>

The bspec has just recently been updated with new cdclk values that
require the use of a /2 CD2X divider rather than a /1 divider.  Once we
add the divider selection logic to ICL+ cdclk programming, we have
pretty much the same logic we were already using on CNL, so it's simpler
to drop icl_set_cdclk() completely and reuse cnl_set_cdclk() on gen11+
platforms as well.

v2:
 - Using ICL_CDCLK_CD2X_PIPE_NONE + BXT_CDCLK_CD2X_PIPE(pipe) for TGL is
   correct, but looks really confusing.  Add some TGL_ macros that alias
   these to avoid confusion.  (Ville)
 - Use DIV_ROUND_CLOSEST rather than / when applying the divider. (Ville)

Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
Unifying the get_cdclk functions too might be worth looking into in the
future, but it wasn't as straightforward as the set_cdclk functions so
I'm not going to tackle that with this series.

 drivers/gpu/drm/i915/display/intel_cdclk.c | 90 +++++++++-------------
 drivers/gpu/drm/i915/i915_reg.h            |  3 +
 2 files changed, 38 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 939088c7d814..58ba42dcf23f 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1659,10 +1659,23 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 		cnl_cdclk_pll_enable(dev_priv, vco);
 
 	val = divider | skl_cdclk_decimal(cdclk);
-	if (pipe == INVALID_PIPE)
-		val |= BXT_CDCLK_CD2X_PIPE_NONE;
-	else
-		val |= BXT_CDCLK_CD2X_PIPE(pipe);
+
+	if (INTEL_GEN(dev_priv) >= 12) {
+		if (pipe == INVALID_PIPE)
+			val |= TGL_CDCLK_CD2X_PIPE_NONE;
+		else
+			val |= TGL_CDCLK_CD2X_PIPE(pipe);
+	} else if (INTEL_GEN(dev_priv) >= 11) {
+		if (pipe == INVALID_PIPE)
+			val |= ICL_CDCLK_CD2X_PIPE_NONE;
+		else
+			val |= ICL_CDCLK_CD2X_PIPE(pipe);
+	} else {
+		if (pipe == INVALID_PIPE)
+			val |= BXT_CDCLK_CD2X_PIPE_NONE;
+		else
+			val |= BXT_CDCLK_CD2X_PIPE(pipe);
+	}
 	I915_WRITE(CDCLK_CTL, val);
 
 	if (pipe != INVALID_PIPE)
@@ -1813,51 +1826,6 @@ static int icl_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
 	return dev_priv->cdclk.hw.ref * ratio;
 }
 
-static void icl_set_cdclk(struct drm_i915_private *dev_priv,
-			  const struct intel_cdclk_state *cdclk_state,
-			  enum pipe pipe)
-{
-	unsigned int cdclk = cdclk_state->cdclk;
-	unsigned int vco = cdclk_state->vco;
-	int ret;
-
-	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
-				SKL_CDCLK_PREPARE_FOR_CHANGE,
-				SKL_CDCLK_READY_FOR_CHANGE,
-				SKL_CDCLK_READY_FOR_CHANGE, 3);
-	if (ret) {
-		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
-			  ret);
-		return;
-	}
-
-	if (dev_priv->cdclk.hw.vco != 0 &&
-	    dev_priv->cdclk.hw.vco != vco)
-		cnl_cdclk_pll_disable(dev_priv);
-
-	if (dev_priv->cdclk.hw.vco != vco)
-		cnl_cdclk_pll_enable(dev_priv, vco);
-
-	/*
-	 * On ICL CD2X_DIV can only be 1, so we'll never end up changing the
-	 * divider here synchronized to a pipe while CDCLK is on, nor will we
-	 * need the corresponding vblank wait.
-	 */
-	I915_WRITE(CDCLK_CTL, ICL_CDCLK_CD2X_PIPE_NONE |
-			      skl_cdclk_decimal(cdclk));
-
-	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
-				cdclk_state->voltage_level);
-
-	intel_update_cdclk(dev_priv);
-
-	/*
-	 * Can't read out the voltage level :(
-	 * Let's just assume everything is as expected.
-	 */
-	dev_priv->cdclk.hw.voltage_level = cdclk_state->voltage_level;
-}
-
 static u8 icl_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk)
 {
 	if (IS_ELKHARTLAKE(dev_priv)) {
@@ -1881,6 +1849,7 @@ static void icl_get_cdclk(struct drm_i915_private *dev_priv,
 			  struct intel_cdclk_state *cdclk_state)
 {
 	u32 val;
+	int div;
 
 	cdclk_state->bypass = 50000;
 
@@ -1914,10 +1883,21 @@ static void icl_get_cdclk(struct drm_i915_private *dev_priv,
 
 	cdclk_state->vco = (val & BXT_DE_PLL_RATIO_MASK) * cdclk_state->ref;
 
-	val = I915_READ(CDCLK_CTL);
-	WARN_ON((val & BXT_CDCLK_CD2X_DIV_SEL_MASK) != 0);
+	val = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
+	switch (val) {
+	case BXT_CDCLK_CD2X_DIV_SEL_1:
+		div = 2;
+		break;
+	case BXT_CDCLK_CD2X_DIV_SEL_2:
+		div = 4;
+		break;
+	default:
+		MISSING_CASE(val);
+		div = 2;
+		break;
+	}
 
-	cdclk_state->cdclk = cdclk_state->vco / 2;
+	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
 
 out:
 	/*
@@ -1963,7 +1943,7 @@ static void icl_init_cdclk(struct drm_i915_private *dev_priv)
 				icl_calc_voltage_level(dev_priv,
 						       sanitized_state.cdclk);
 
-	icl_set_cdclk(dev_priv, &sanitized_state, INVALID_PIPE);
+	cnl_set_cdclk(dev_priv, &sanitized_state, INVALID_PIPE);
 }
 
 static void icl_uninit_cdclk(struct drm_i915_private *dev_priv)
@@ -1975,7 +1955,7 @@ static void icl_uninit_cdclk(struct drm_i915_private *dev_priv)
 	cdclk_state.voltage_level = icl_calc_voltage_level(dev_priv,
 							   cdclk_state.cdclk);
 
-	icl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE);
+	cnl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE);
 }
 
 static void cnl_init_cdclk(struct drm_i915_private *dev_priv)
@@ -2810,7 +2790,7 @@ void intel_update_rawclk(struct drm_i915_private *dev_priv)
 void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
 {
 	if (INTEL_GEN(dev_priv) >= 11) {
-		dev_priv->display.set_cdclk = icl_set_cdclk;
+		dev_priv->display.set_cdclk = cnl_set_cdclk;
 		dev_priv->display.modeset_calc_cdclk = icl_modeset_calc_cdclk;
 	} else if (IS_CANNONLAKE(dev_priv)) {
 		dev_priv->display.set_cdclk = cnl_set_cdclk;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a142aa3d74e3..c47e2969ad04 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -9671,7 +9671,10 @@ enum skl_power_gate {
 #define  BXT_CDCLK_CD2X_PIPE(pipe)	((pipe) << 20)
 #define  CDCLK_DIVMUX_CD_OVERRIDE	(1 << 19)
 #define  BXT_CDCLK_CD2X_PIPE_NONE	BXT_CDCLK_CD2X_PIPE(3)
+#define  ICL_CDCLK_CD2X_PIPE(pipe)	(_PICK(pipe, 0, 2, 6) << 19)
 #define  ICL_CDCLK_CD2X_PIPE_NONE	(7 << 19)
+#define  TGL_CDCLK_CD2X_PIPE(pipe)	BXT_CDCLK_CD2X_PIPE(pipe)
+#define  TGL_CDCLK_CD2X_PIPE_NONE	ICL_CDCLK_CD2X_PIPE_NONE
 #define  BXT_CDCLK_SSA_PRECHARGE_ENABLE	(1 << 16)
 #define  CDCLK_FREQ_DECIMAL_MASK	(0x7ff)
 
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2019-08-30  0:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-26 22:55 [PATCH 0/2] New cdclk values for gen11+ Matt Roper
2019-08-26 22:55 ` [PATCH 1/2] drm/i915: Allow /2 CD2X divider on gen11+ Matt Roper
2019-08-27 13:52   ` Ville Syrjälä
2019-08-30  0:48     ` Matt Roper [this message]
2019-08-26 22:55 ` [PATCH 2/2] drm/i915: Add 324mhz and 326.4mhz cdclks for gen11+ Matt Roper
2019-08-27  9:19 ` ✓ Fi.CI.BAT: success for New cdclk values " Patchwork
2019-08-27 13:33 ` ✓ Fi.CI.IGT: " Patchwork
2019-08-30  1:27 ` ✓ Fi.CI.BAT: success for New cdclk values for gen11+ (rev2) Patchwork
2019-08-30 21:47 ` ✓ Fi.CI.IGT: " Patchwork
2019-08-30 22:49   ` Matt Roper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190830004828.19359-1-matthew.d.roper@intel.com \
    --to=matthew.d.roper@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=lucas.demarchi@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.