All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] drm/i915: CNL DVFS thing
@ 2017-10-18 20:48 Ville Syrjala
  2017-10-18 20:48 ` [PATCH 1/8] drm/i915: Clean up some cdclk switch statements Ville Syrjala
                   ` (16 more replies)
  0 siblings, 17 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Here's my idea on how the CNL DVFS thing ought to be implemented.
Not sure I gleaned the details of the port clock limits correctly, but
other than that I think this should work.

Entire series available here:
git://github.com/vsyrjala/linux.git dvfs_voltage_4

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>

Ville Syrjälä (8):
  drm/i915: Clean up some cdclk switch statements
  drm/i915: Start tracking voltage level in the cdclk state
  drm/i915: USe cdclk_state->voltage on VLV/CHV
  drm/i915: Use cdclk_state->voltage on BDW
  drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
  drm/i915: Use cdclk_state->voltage on BXT/GLK
  drm/i915: Use cdclk_state->voltage on CNL
  drm/i915: Adjust system agent voltage on CNL if required by DDI ports

 drivers/gpu/drm/i915/i915_drv.h         |   3 +
 drivers/gpu/drm/i915/intel_cdclk.c      | 318 +++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_ddi.c        |  13 ++
 drivers/gpu/drm/i915/intel_display.c    |  14 +-
 drivers/gpu/drm/i915/intel_dp_mst.c     |   5 +
 drivers/gpu/drm/i915/intel_drv.h        |  10 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c |   3 +-
 7 files changed, 276 insertions(+), 90 deletions(-)

-- 
2.13.6

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 1/8] drm/i915: Clean up some cdclk switch statements
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-19  7:20   ` Mika Kahola
  2017-10-18 20:48 ` [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state Ville Syrjala
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Redo some switch statements in the cdclk code to use a common
fall through for the default case. Makes everything look a bit
more uniform

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 68 +++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index b2a6d62b71c0..4bffd31a8924 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -681,6 +681,13 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 	val &= ~LCPLL_CLK_FREQ_MASK;
 
 	switch (cdclk) {
+	default:
+		MISSING_CASE(cdclk);
+		/* fall through */
+	case 337500:
+		val |= LCPLL_CLK_FREQ_337_5_BDW;
+		data = 2;
+		break;
 	case 450000:
 		val |= LCPLL_CLK_FREQ_450;
 		data = 0;
@@ -689,17 +696,10 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		val |= LCPLL_CLK_FREQ_54O_BDW;
 		data = 1;
 		break;
-	case 337500:
-		val |= LCPLL_CLK_FREQ_337_5_BDW;
-		data = 2;
-		break;
 	case 675000:
 		val |= LCPLL_CLK_FREQ_675_BDW;
 		data = 3;
 		break;
-	default:
-		WARN(1, "invalid cdclk frequency\n");
-		return;
 	}
 
 	I915_WRITE(LCPLL_CTL, val);
@@ -926,8 +926,6 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 	u32 freq_select, pcu_ack;
 	int ret;
 
-	WARN_ON((cdclk == 24000) != (vco == 0));
-
 	mutex_lock(&dev_priv->pcu_lock);
 	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				SKL_CDCLK_PREPARE_FOR_CHANGE,
@@ -942,6 +940,15 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 
 	/* set CDCLK_CTL */
 	switch (cdclk) {
+	default:
+		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
+		WARN_ON(vco != 0);
+		/* fall through */
+	case 308571:
+	case 337500:
+		freq_select = CDCLK_FREQ_337_308;
+		pcu_ack = 0;
+		break;
 	case 450000:
 	case 432000:
 		freq_select = CDCLK_FREQ_450_432;
@@ -951,12 +958,6 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 		freq_select = CDCLK_FREQ_540;
 		pcu_ack = 2;
 		break;
-	case 308571:
-	case 337500:
-	default:
-		freq_select = CDCLK_FREQ_337_308;
-		pcu_ack = 0;
-		break;
 	case 617143:
 	case 675000:
 		freq_select = CDCLK_FREQ_675_617;
@@ -1110,6 +1111,7 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
 	switch (cdclk) {
 	default:
 		MISSING_CASE(cdclk);
+		/* fall through */
 	case 144000:
 	case 288000:
 	case 384000:
@@ -1134,6 +1136,7 @@ static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
 	switch (cdclk) {
 	default:
 		MISSING_CASE(cdclk);
+		/* fall through */
 	case  79200:
 	case 158400:
 	case 316800:
@@ -1246,24 +1249,22 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 
 	/* cdclk = vco / 2 / div{1,1.5,2,4} */
 	switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
-	case 8:
-		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
-		break;
-	case 4:
-		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
+	default:
+		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
+		WARN_ON(vco != 0);
+		/* fall through */
+	case 2:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
 		break;
 	case 3:
 		WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n");
 		divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
 		break;
-	case 2:
-		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
+	case 4:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
 		break;
-	default:
-		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
-		WARN_ON(vco != 0);
-
-		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
+	case 8:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
 		break;
 	}
 
@@ -1532,18 +1533,16 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 
 	/* cdclk = vco / 2 / div{1,2} */
 	switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
-	case 4:
-		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
-		break;
-	case 2:
-		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
-		break;
 	default:
 		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
 		WARN_ON(vco != 0);
-
+		/* fall through */
+	case 2:
 		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
 		break;
+	case 4:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
+		break;
 	}
 
 	switch (cdclk) {
@@ -1592,6 +1591,7 @@ static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
 	switch (cdclk) {
 	default:
 		MISSING_CASE(cdclk);
+		/* fall through */
 	case 168000:
 	case 336000:
 		ratio = dev_priv->cdclk.hw.ref == 19200 ? 35 : 28;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
  2017-10-18 20:48 ` [PATCH 1/8] drm/i915: Clean up some cdclk switch statements Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-19 23:32   ` Rodrigo Vivi
  2017-10-20 14:01   ` Ville Syrjälä
  2017-10-18 20:48 ` [PATCH 3/8] drm/i915: USe cdclk_state->voltage on VLV/CHV Ville Syrjala
                   ` (14 subsequent siblings)
  16 siblings, 2 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

For CNL we'll need to start considering the port clocks when we select
the voltage level for the system agent. To that end start tracking the
voltage in the cdclk state (since that already has to adjust it).

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |  1 +
 drivers/gpu/drm/i915/intel_cdclk.c      | 31 ++++++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_display.c    |  8 ++++----
 drivers/gpu/drm/i915/intel_drv.h        |  4 +++-
 drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++-
 5 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f01c80076c59..d3ac58dc275f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2227,6 +2227,7 @@ struct i915_oa_ops {
 
 struct intel_cdclk_state {
 	unsigned int cdclk, vco, ref;
+	u8 voltage;
 };
 
 struct drm_i915_private {
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 4bffd31a8924..522222f8bb50 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1690,17 +1690,34 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
 }
 
 /**
- * intel_cdclk_state_compare - Determine if two CDCLK states differ
+ * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes
  * @a: first CDCLK state
  * @b: second CDCLK state
  *
  * Returns:
- * True if the CDCLK states are identical, false if they differ.
+ * True if the CDCLK states require pipes to be off during reprogramming, false if not.
  */
-bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
+bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
 			       const struct intel_cdclk_state *b)
 {
-	return memcmp(a, b, sizeof(*a)) == 0;
+	return a->cdclk != b->cdclk ||
+		a->vco != b->vco ||
+		a->ref != b->ref;
+}
+
+/**
+ * intel_cdclk_changed - Determine if two CDCLK states are different
+ * @a: first CDCLK state
+ * @b: second CDCLK state
+ *
+ * Returns:
+ * True if the CDCLK states don't match, false if they do.
+ */
+bool intel_cdclk_changed(const struct intel_cdclk_state *a,
+			 const struct intel_cdclk_state *b)
+{
+	return intel_cdclk_needs_modeset(a, b) ||
+		a->voltage != b->voltage;
 }
 
 /**
@@ -1714,15 +1731,15 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
 void intel_set_cdclk(struct drm_i915_private *dev_priv,
 		     const struct intel_cdclk_state *cdclk_state)
 {
-	if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state))
+	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state))
 		return;
 
 	if (WARN_ON_ONCE(!dev_priv->display.set_cdclk))
 		return;
 
-	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n",
+	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz, voltage %d\n",
 			 cdclk_state->cdclk, cdclk_state->vco,
-			 cdclk_state->ref);
+			 cdclk_state->ref, cdclk_state->voltage);
 
 	dev_priv->display.set_cdclk(dev_priv, cdclk_state);
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bd62c0a65bcd..32e7cca52da2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11946,16 +11946,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 		 * holding all the crtc locks, even if we don't end up
 		 * touching the hardware
 		 */
-		if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
-					       &intel_state->cdclk.logical)) {
+		if (intel_cdclk_changed(&dev_priv->cdclk.logical,
+					&intel_state->cdclk.logical)) {
 			ret = intel_lock_all_pipes(state);
 			if (ret < 0)
 				return ret;
 		}
 
 		/* All pipes must be switched off while we change the cdclk. */
-		if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
-					       &intel_state->cdclk.actual)) {
+		if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual,
+					      &intel_state->cdclk.actual)) {
 			ret = intel_modeset_all_pipes(state);
 			if (ret < 0)
 				return ret;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a05ab3a1ab27..765a737700c5 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1324,8 +1324,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
 void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
 void intel_update_cdclk(struct drm_i915_private *dev_priv);
 void intel_update_rawclk(struct drm_i915_private *dev_priv);
-bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
+bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
 			       const struct intel_cdclk_state *b);
+bool intel_cdclk_changed(const struct intel_cdclk_state *a,
+			 const struct intel_cdclk_state *b);
 void intel_set_cdclk(struct drm_i915_private *dev_priv,
 		     const struct intel_cdclk_state *cdclk_state);
 
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 8af286c63d3b..5ac553fab7c7 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
 	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 
 	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
-	WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
+	/* Can't read out the voltage so can't use intel_cdclk_changed() */
+	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
 
 	gen9_assert_dbuf_enabled(dev_priv);
 
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 3/8] drm/i915: USe cdclk_state->voltage on VLV/CHV
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
  2017-10-18 20:48 ` [PATCH 1/8] drm/i915: Clean up some cdclk switch statements Ville Syrjala
  2017-10-18 20:48 ` [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-19 17:43   ` [PATCH v2 3/8] drm/i915: Use " Ville Syrjala
  2017-10-20 17:03   ` [PATCH v3 " Ville Syrjala
  2017-10-18 20:48 ` [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW Ville Syrjala
                   ` (13 subsequent siblings)
  16 siblings, 2 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Store the punit DSPFREQUAR value into cdclk_state->voltage on
VLV/CHV. Since we can actually read that out from the hardware
this can give us a bit more cross checking between the hardware
and software state.

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 53 ++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 522222f8bb50..df71667c9fd6 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -437,13 +437,45 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
 		return 200000;
 }
 
+static u8 vlv_calc_voltage(struct drm_i915_private *dev_priv, int cdclk)
+{
+	if (IS_VALLEYVIEW(dev_priv)) {
+		if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
+			return 2;
+		else if (cdclk >= 266667)
+			return 1;
+		else
+			return 0;
+	} else {
+		/*
+		 * Specs are full of misinformation, but testing on actual
+		 * hardware has shown that we just need to write the desired
+		 * CCK divider into the Punit register.
+		 */
+		return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
+	}
+}
+
 static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
 			  struct intel_cdclk_state *cdclk_state)
 {
+	u32 val;
+
 	cdclk_state->vco = vlv_get_hpll_vco(dev_priv);
 	cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
 					       CCK_DISPLAY_CLOCK_CONTROL,
 					       cdclk_state->vco);
+
+	mutex_lock(&dev_priv->pcu_lock);
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	mutex_unlock(&dev_priv->pcu_lock);
+
+	if (IS_VALLEYVIEW(dev_priv))
+		cdclk_state->voltage = (val & DSPFREQGUAR_MASK) >>
+			DSPFREQGUAR_SHIFT;
+	else
+		cdclk_state->voltage = (val & DSPFREQGUAR_MASK_CHV) >>
+			DSPFREQGUAR_SHIFT_CHV;
 }
 
 static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
@@ -496,20 +528,15 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
-	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
-		cmd = 2;
-	else if (cdclk == 266667)
-		cmd = 1;
-	else
-		cmd = 0;
+	cmd = cdclk_state->voltage << DSPFREQGUAR_SHIFT;
 
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK;
-	val |= (cmd << DSPFREQGUAR_SHIFT);
+	val |= cmd;
 	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
 	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
-		      DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
+		      DSPFREQSTAT_MASK) == cmd,
 		     50)) {
 		DRM_ERROR("timed out waiting for CDclk change\n");
 	}
@@ -588,15 +615,15 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	 * hardware has shown that we just need to write the desired
 	 * CCK divider into the Punit register.
 	 */
-	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
+	cmd = cdclk_state->voltage << DSPFREQGUAR_SHIFT_CHV;
 
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK_CHV;
-	val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
+	val |= cmd;
 	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
 	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
-		      DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
+		      DSPFREQSTAT_MASK_CHV) == cmd,
 		     50)) {
 		DRM_ERROR("timed out waiting for CDclk change\n");
 	}
@@ -1859,11 +1886,15 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
 	cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
 
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage =
+		vlv_calc_voltage(dev_priv, cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = vlv_calc_cdclk(dev_priv, 0);
 
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage =
+			vlv_calc_voltage(dev_priv, cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (2 preceding siblings ...)
  2017-10-18 20:48 ` [PATCH 3/8] drm/i915: USe cdclk_state->voltage on VLV/CHV Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-19 23:44   ` Rodrigo Vivi
  2017-10-20 17:03   ` [PATCH v2 " Ville Syrjala
  2017-10-18 20:48 ` [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL Ville Syrjala
                   ` (12 subsequent siblings)
  16 siblings, 2 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Track the system agent voltage we request from pcode in the cdclk state
on BDW. Annoyingly we can't actually read out the current value since
there's no pcode command to do that, so we'll have to just assume that
it worked.

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index df71667c9fd6..7442e9443ffa 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -648,6 +648,21 @@ static int bdw_calc_cdclk(int min_cdclk)
 		return 337500;
 }
 
+static u8 bdw_calc_voltage(int cdclk)
+{
+	switch (cdclk) {
+	default:
+	case 337500:
+		return 2;
+	case 450000:
+		return 0;
+	case 540000:
+		return 1;
+	case 675000:
+		return 3;
+	}
+}
+
 static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
 			  struct intel_cdclk_state *cdclk_state)
 {
@@ -666,13 +681,19 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
 		cdclk_state->cdclk = 337500;
 	else
 		cdclk_state->cdclk = 675000;
+
+	/*
+	 * Can't read this out :( Let's assume it's
+	 * at least what the CDCLK frequency requires.
+	 */
+	cdclk_state->voltage = bdw_calc_voltage(cdclk_state->cdclk);
 }
 
 static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_state *cdclk_state)
 {
 	int cdclk = cdclk_state->cdclk;
-	uint32_t val, data;
+	uint32_t val;
 	int ret;
 
 	if (WARN((I915_READ(LCPLL_CTL) &
@@ -713,19 +734,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		/* fall through */
 	case 337500:
 		val |= LCPLL_CLK_FREQ_337_5_BDW;
-		data = 2;
 		break;
 	case 450000:
 		val |= LCPLL_CLK_FREQ_450;
-		data = 0;
 		break;
 	case 540000:
 		val |= LCPLL_CLK_FREQ_54O_BDW;
-		data = 1;
 		break;
 	case 675000:
 		val |= LCPLL_CLK_FREQ_675_BDW;
-		data = 3;
 		break;
 	}
 
@@ -740,16 +757,13 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		DRM_ERROR("Switching back to LCPLL failed\n");
 
 	mutex_lock(&dev_priv->pcu_lock);
-	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
+	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
+				cdclk_state->voltage);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
 
 	intel_update_cdclk(dev_priv);
-
-	WARN(cdclk != dev_priv->cdclk.hw.cdclk,
-	     "cdclk requested %d kHz but got %d kHz\n",
-	     cdclk, dev_priv->cdclk.hw.cdclk);
 }
 
 static int skl_calc_cdclk(int min_cdclk, int vco)
@@ -1919,11 +1933,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
 	cdclk = bdw_calc_cdclk(min_cdclk);
 
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage = bdw_calc_voltage(cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = bdw_calc_cdclk(0);
 
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage = bdw_calc_voltage(cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (3 preceding siblings ...)
  2017-10-18 20:48 ` [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-19 23:47   ` Rodrigo Vivi
  2017-10-18 20:48 ` [PATCH 6/8] drm/i915: Use cdclk_state->voltage on BXT/GLK Ville Syrjala
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Track the system agent voltage we request from pcode in the cdclk state
on SKL/KBL/CFL. Annoyingly we can't actually read out the current value since
there's no pcode command to do that, so we'll have to just assume that
it worked.

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 40 +++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 7442e9443ffa..6f7b5abe6e3f 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -789,6 +789,24 @@ static int skl_calc_cdclk(int min_cdclk, int vco)
 	}
 }
 
+static u8 skl_calc_voltage(int cdclk)
+{
+	switch (cdclk) {
+	default:
+	case 308571:
+	case 337500:
+		return 0;
+	case 450000:
+	case 432000:
+		return 1;
+	case 540000:
+		return 2;
+	case 617143:
+	case 675000:
+		return 3;
+	}
+}
+
 static void skl_dpll0_update(struct drm_i915_private *dev_priv,
 			     struct intel_cdclk_state *cdclk_state)
 {
@@ -839,7 +857,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
 	cdclk_state->cdclk = cdclk_state->ref;
 
 	if (cdclk_state->vco == 0)
-		return;
+		goto out;
 
 	cdctl = I915_READ(CDCLK_CTL);
 
@@ -880,6 +898,13 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
 			break;
 		}
 	}
+
+ out:
+	/*
+	 * Can't read this out :( Let's assume it's
+	 * at least what the CDCLK frequency requires.
+	 */
+	cdclk_state->voltage = skl_calc_voltage(cdclk_state->cdclk);
 }
 
 /* convert from kHz to .1 fixpoint MHz with -1MHz offset */
@@ -964,7 +989,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 {
 	int cdclk = cdclk_state->cdclk;
 	int vco = cdclk_state->vco;
-	u32 freq_select, pcu_ack;
+	u32 freq_select;
 	int ret;
 
 	mutex_lock(&dev_priv->pcu_lock);
@@ -988,21 +1013,17 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 	case 308571:
 	case 337500:
 		freq_select = CDCLK_FREQ_337_308;
-		pcu_ack = 0;
 		break;
 	case 450000:
 	case 432000:
 		freq_select = CDCLK_FREQ_450_432;
-		pcu_ack = 1;
 		break;
 	case 540000:
 		freq_select = CDCLK_FREQ_540;
-		pcu_ack = 2;
 		break;
 	case 617143:
 	case 675000:
 		freq_select = CDCLK_FREQ_675_617;
-		pcu_ack = 3;
 		break;
 	}
 
@@ -1018,7 +1039,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 
 	/* inform PCU of the change */
 	mutex_lock(&dev_priv->pcu_lock);
-	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
+	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
+				cdclk_state->voltage);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
@@ -1097,6 +1119,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
 	if (cdclk_state.vco == 0)
 		cdclk_state.vco = 8100000;
 	cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco);
+	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
 
 	skl_set_cdclk(dev_priv, &cdclk_state);
 }
@@ -1114,6 +1137,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
 
 	cdclk_state.cdclk = cdclk_state.ref;
 	cdclk_state.vco = 0;
+	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
 
 	skl_set_cdclk(dev_priv, &cdclk_state);
 }
@@ -1970,12 +1994,14 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage = skl_calc_voltage(cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = skl_calc_cdclk(0, vco);
 
 		intel_state->cdclk.actual.vco = vco;
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage = skl_calc_voltage(cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 6/8] drm/i915: Use cdclk_state->voltage on BXT/GLK
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (4 preceding siblings ...)
  2017-10-18 20:48 ` [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-20 20:51   ` Rodrigo Vivi
  2017-10-18 20:48 ` [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL Ville Syrjala
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Track the system agent voltage we request from pcode in the cdclk state
on BXT/GLK. Annoyingly we can't actually read out the current value since
there's no pcode command to do that, so we'll have to just assume that
it worked.

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 6f7b5abe6e3f..1b4dcd9689da 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1166,6 +1166,11 @@ static int glk_calc_cdclk(int min_cdclk)
 		return 79200;
 }
 
+static u8 bxt_calc_voltage(int cdclk)
+{
+	return DIV_ROUND_UP(cdclk, 25000);
+}
+
 static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
 {
 	int ratio;
@@ -1242,7 +1247,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
 	cdclk_state->cdclk = cdclk_state->ref;
 
 	if (cdclk_state->vco == 0)
-		return;
+		goto out;
 
 	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
 
@@ -1266,6 +1271,13 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
 	}
 
 	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
+
+ out:
+	/*
+	 * Can't read this out :( Let's assume it's
+	 * at least what the CDCLK frequency requires.
+	 */
+	cdclk_state->voltage = bxt_calc_voltage(cdclk_state->cdclk);
 }
 
 static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
@@ -1368,7 +1380,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 
 	mutex_lock(&dev_priv->pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      DIV_ROUND_UP(cdclk, 25000));
+				      cdclk_state->voltage);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
@@ -1460,6 +1472,7 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv)
 		cdclk_state.cdclk = bxt_calc_cdclk(0);
 		cdclk_state.vco = bxt_de_pll_vco(dev_priv, cdclk_state.cdclk);
 	}
+	cdclk_state.voltage = bxt_calc_voltage(cdclk_state.cdclk);
 
 	bxt_set_cdclk(dev_priv, &cdclk_state);
 }
@@ -1477,6 +1490,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
 
 	cdclk_state.cdclk = cdclk_state.ref;
 	cdclk_state.vco = 0;
+	cdclk_state.voltage = bxt_calc_voltage(cdclk_state.cdclk);
 
 	bxt_set_cdclk(dev_priv, &cdclk_state);
 }
@@ -2030,6 +2044,7 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage = bxt_calc_voltage(cdclk);
 
 	if (!intel_state->active_crtcs) {
 		if (IS_GEMINILAKE(dev_priv)) {
@@ -2042,6 +2057,7 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 		intel_state->cdclk.actual.vco = vco;
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage = bxt_calc_voltage(cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (5 preceding siblings ...)
  2017-10-18 20:48 ` [PATCH 6/8] drm/i915: Use cdclk_state->voltage on BXT/GLK Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-18 21:50   ` Rodrigo Vivi
  2017-10-23 18:29   ` Rodrigo Vivi
  2017-10-18 20:48 ` [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports Ville Syrjala
                   ` (9 subsequent siblings)
  16 siblings, 2 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Track the system agent voltage we request from pcode in the cdclk state
on CNL. Annoyingly we can't actually read out the current value since
there's no pcode command to do that, so we'll have to just assume that
it worked.

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 44 ++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 1b4dcd9689da..795a18f64c4c 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
 		return 168000;
 }
 
+static u8 cnl_calc_voltage(int cdclk)
+{
+	switch (cdclk) {
+	default:
+	case 168000:
+		return 0;
+	case 336000:
+		return 1;
+	case 528000:
+		return 2;
+	}
+}
+
 static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
 				 struct intel_cdclk_state *cdclk_state)
 {
@@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
 	cdclk_state->cdclk = cdclk_state->ref;
 
 	if (cdclk_state->vco == 0)
-		return;
+		goto out;
 
 	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
 
@@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
 	}
 
 	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
+
+ out:
+	/*
+	 * Can't read this out :( Let's assume it's
+	 * at least what the CDCLK frequency requires.
+	 */
+	cdclk_state->voltage = cnl_calc_voltage(cdclk_state->cdclk);
 }
 
 static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
@@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 {
 	int cdclk = cdclk_state->cdclk;
 	int vco = cdclk_state->vco;
-	u32 val, divider, pcu_ack;
+	u32 val, divider;
 	int ret;
 
 	mutex_lock(&dev_priv->pcu_lock);
@@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 		break;
 	}
 
-	switch (cdclk) {
-	case 528000:
-		pcu_ack = 2;
-		break;
-	case 336000:
-		pcu_ack = 1;
-		break;
-	case 168000:
-	default:
-		pcu_ack = 0;
-		break;
-	}
-
 	if (dev_priv->cdclk.hw.vco != 0 &&
 	    dev_priv->cdclk.hw.vco != vco)
 		cnl_cdclk_pll_disable(dev_priv);
@@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 
 	/* inform PCU of the change */
 	mutex_lock(&dev_priv->pcu_lock);
-	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
+	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
+				cdclk_state->voltage);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
@@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv)
 
 	cdclk_state.cdclk = cnl_calc_cdclk(0);
 	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk);
+	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
 
 	cnl_set_cdclk(dev_priv, &cdclk_state);
 }
@@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
 
 	cdclk_state.cdclk = cdclk_state.ref;
 	cdclk_state.vco = 0;
+	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
 
 	cnl_set_cdclk(dev_priv, &cdclk_state);
 }
@@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = cnl_calc_cdclk(0);
@@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 		intel_state->cdclk.actual.vco = vco;
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage = cnl_calc_voltage(cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (6 preceding siblings ...)
  2017-10-18 20:48 ` [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL Ville Syrjala
@ 2017-10-18 20:48 ` Ville Syrjala
  2017-10-19 23:54   ` Rodrigo Vivi
                     ` (2 more replies)
  2017-10-18 21:07 ` ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing Patchwork
                   ` (8 subsequent siblings)
  16 siblings, 3 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-18 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

On CNL we may need to bump up the system agent voltage not only due
to CDCLK but also when driving DDI port with a sufficiently high clock.
To that end start tracking the minimum acceptable voltage for each crtc.
We do the tracking via crtcs because we don't have any kind of encoder
state. Also there's no downside to doing it this way, and it matches how
we track cdclk requirements on account of pixel rate.

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  2 ++
 drivers/gpu/drm/i915/intel_cdclk.c   | 34 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_ddi.c     | 13 +++++++++++++
 drivers/gpu/drm/i915/intel_display.c |  6 ++++++
 drivers/gpu/drm/i915/intel_dp_mst.c  |  5 +++++
 drivers/gpu/drm/i915/intel_drv.h     |  6 ++++++
 6 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d3ac58dc275f..185711a852b0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2415,6 +2415,8 @@ struct drm_i915_private {
 	unsigned int active_crtcs;
 	/* minimum acceptable cdclk for each pipe */
 	int min_cdclk[I915_MAX_PIPES];
+	/* minimum acceptable voltage for each pipe */
+	u8 min_voltage[I915_MAX_PIPES];
 
 	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
 
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 795a18f64c4c..035c44858908 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1666,6 +1666,13 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
+
+	/*
+	 * Can't read this out :( Can't rely on .get_cdclk() since it
+	 * doesn't know about DDI voltage requirements. So let's just
+	 * assume everything is as expected.
+	 */
+	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
 }
 
 static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
@@ -1935,6 +1942,29 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
 	return min_cdclk;
 }
 
+static u8 intel_compute_min_voltage(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
+	u8 min_voltage;
+	int i;
+	enum pipe pipe;
+
+	memcpy(state->min_voltage, dev_priv->min_voltage,
+	       sizeof(state->min_voltage));
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
+		state->min_voltage[i] = crtc_state->min_voltage;
+
+	min_voltage = 0;
+	for_each_pipe(dev_priv, pipe)
+		min_voltage = max(state->min_voltage[pipe],
+				  min_voltage);
+
+	return min_voltage;
+}
+
 static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
@@ -2091,7 +2121,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
-	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
+	intel_state->cdclk.logical.voltage =
+		max(cnl_calc_voltage(cdclk),
+		    intel_compute_min_voltage(intel_state));
 
 	if (!intel_state->active_crtcs) {
 		cdclk = cnl_calc_cdclk(0);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index adf51b328844..f02e3c2f4ad2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2525,6 +2525,15 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
 	return false;
 }
 
+void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
+				   struct intel_crtc_state *crtc_state)
+{
+	if (INTEL_GEN(dev_priv) >= 10 && crtc_state->port_clock > 594000)
+		crtc_state->min_voltage = 2;
+	else
+		crtc_state->min_voltage = 0;
+}
+
 void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config)
 {
@@ -2624,6 +2633,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	if (IS_GEN9_LP(dev_priv))
 		pipe_config->lane_lat_optim_mask =
 			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
+
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
 }
 
 static bool intel_ddi_compute_config(struct intel_encoder *encoder,
@@ -2650,6 +2661,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
 			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
 							     pipe_config->lane_count);
 
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
+
 	return ret;
 
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 32e7cca52da2..7d293ecb51c4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
 
 	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
 	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
+	dev_priv->min_voltage[intel_crtc->pipe] = 0;
 }
 
 /*
@@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
 	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
 
+	PIPE_CONF_CHECK_I(min_voltage);
+
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
 #undef PIPE_CONF_CHECK_P
@@ -12532,6 +12535,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	if (intel_state->modeset) {
 		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
 		       sizeof(intel_state->min_cdclk));
+		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
+		       sizeof(intel_state->min_voltage));
 		dev_priv->active_crtcs = intel_state->active_crtcs;
 		dev_priv->cdclk.logical = intel_state->cdclk.logical;
 		dev_priv->cdclk.actual = intel_state->cdclk.actual;
@@ -15042,6 +15047,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		}
 
 		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
+		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
 
 		intel_pipe_config_sanity_check(dev_priv, crtc_state);
 	}
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 772521440a9f..6c1da88b5fef 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 					struct intel_crtc_state *pipe_config,
 					struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_digital_port *intel_dig_port = intel_mst->primary;
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
@@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	pipe_config->dp_m_n.tu = slots;
 
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
+
 	return true;
 }
 
@@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
 	intel_dp_get_m_n(crtc, pipe_config);
 
 	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
+
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
 }
 
 static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 765a737700c5..002894b13d69 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -386,6 +386,8 @@ struct intel_atomic_state {
 	unsigned int active_crtcs;
 	/* minimum acceptable cdclk for each pipe */
 	int min_cdclk[I915_MAX_PIPES];
+	/* minimum acceptable voltage for each pipe */
+	u8 min_voltage[I915_MAX_PIPES];
 
 	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
 
@@ -739,6 +741,8 @@ struct intel_crtc_state {
 	 */
 	uint8_t lane_lat_optim_mask;
 
+	u8 min_voltage;
+
 	/* Panel fitter controls for gen2-gen4 + VLV */
 	struct {
 		u32 control;
@@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 				    bool state);
+void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
+				   struct intel_crtc_state *crtc_state);
 u32 bxt_signal_levels(struct intel_dp *intel_dp);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (7 preceding siblings ...)
  2017-10-18 20:48 ` [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports Ville Syrjala
@ 2017-10-18 21:07 ` Patchwork
  2017-10-19 17:31   ` Ville Syrjälä
  2017-10-19 18:17 ` ✗ Fi.CI.BAT: failure for drm/i915: CNL DVFS thing (rev2) Patchwork
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 58+ messages in thread
From: Patchwork @ 2017-10-18 21:07 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing
URL   : https://patchwork.freedesktop.org/series/32247/
State : warning

== Summary ==

Series 32247v1 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/1/mbox/

Test debugfs_test:
        Subgroup read_all_entries:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test gem_exec_suspend:
        Subgroup basic-s3:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-s4-devices:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test kms_busy:
        Subgroup basic-flip-a:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup basic-flip-b:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup basic-flip-c:
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test kms_cursor_legacy:
        Subgroup basic-busy-flip-before-cursor-atomic:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-busy-flip-before-cursor-legacy:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-after-cursor-atomic:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-after-cursor-legacy:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-after-cursor-varying-size:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-before-cursor-atomic:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-before-cursor-legacy:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-before-cursor-varying-size:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test kms_flip:
        Subgroup basic-flip-vs-dpms:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-vs-modeset:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-flip-vs-wf_vblank:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup basic-plain-flip:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test kms_force_connector_basic:
        Subgroup force-connector-state:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup force-load-detect:
                pass       -> DMESG-WARN (fi-byt-j1900)
Test kms_frontbuffer_tracking:
        Subgroup basic:
                pass       -> DMESG-WARN (fi-byt-j1900)
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test kms_pipe_crc_basic:
        Subgroup hang-read-crc-pipe-a:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup hang-read-crc-pipe-b:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup hang-read-crc-pipe-c:
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup nonblocking-crc-pipe-a:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup nonblocking-crc-pipe-a-frame-sequence:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup nonblocking-crc-pipe-b:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup nonblocking-crc-pipe-b-frame-sequence:
                pass       -> DMESG-WARN (fi-byt-j1900) fdo#102619
        Subgroup nonblocking-crc-pipe-c:
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup nonblocking-crc-pipe-c-frame-sequence:
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup read-crc-pipe-a:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup read-crc-pipe-a-frame-sequence:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup read-crc-pipe-b:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup read-crc-pipe-b-frame-sequence:
                pass       -> DMESG-WARN (fi-byt-j1900)
        Subgroup read-crc-pipe-c:
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup read-crc-pipe-c-frame-sequence:
                pass       -> DMESG-WARN (fi-bsw-n3050)
        Subgroup suspend-read-crc-pipe-a:
WARNING: Long output truncated
fi-pnv-d510 failed to connect after reboot

7edf6833df0ac2c6d24969d48074203bd305e623 drm-tip: 2017y-10m-18d-16h-29m-02s UTC integration manifest
c02f9fc7b3a5 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
22471d3e6efc drm/i915: Use cdclk_state->voltage on CNL
ce351d159829 drm/i915: Use cdclk_state->voltage on BXT/GLK
1be4a076d2df drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
1fe8bd7e3a7c drm/i915: Use cdclk_state->voltage on BDW
3c6e69440b86 drm/i915: USe cdclk_state->voltage on VLV/CHV
0cb95d769249 drm/i915: Start tracking voltage level in the cdclk state
77b5c93acd63 drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6096/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-18 20:48 ` [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL Ville Syrjala
@ 2017-10-18 21:50   ` Rodrigo Vivi
  2017-10-18 22:43     ` Rodrigo Vivi
  2017-10-19 10:48     ` Ville Syrjälä
  2017-10-23 18:29   ` Rodrigo Vivi
  1 sibling, 2 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-18 21:50 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Track the system agent voltage we request from pcode in the cdclk state
> on CNL. Annoyingly we can't actually read out the current value since
> there's no pcode command to do that, so we'll have to just assume that
> it worked.

+static u32 cnl_cur_voltage(struct drm_i915_private *dev_priv)
+{
+       u32 voltage;
+       sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &voltage);
+       return voltage;
+}
+
 static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
                         struct intel_cdclk_state *cdclk_state)
 {
@@ -1486,8 +1493,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
 
        cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
 
+       cdclk_state->voltage = cnl_cur_voltage(dev_priv);
 }
 
 static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
@@ -1594,8 +1600,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 
        intel_update_cdclk(dev_priv);
 
+       dev_priv->cdclk.hw.voltage = cnl_cur_voltage(dev_priv);


> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 44 ++++++++++++++++++++++++--------------
>  1 file changed, 28 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 1b4dcd9689da..795a18f64c4c 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
>  		return 168000;
>  }
>  
> +static u8 cnl_calc_voltage(int cdclk)
> +{
> +	switch (cdclk) {
> +	default:
> +	case 168000:
> +		return 0;
> +	case 336000:
> +		return 1;
> +	case 528000:
> +		return 2;
> +	}
> +}

where is the port_clock taking into account?

> +
>  static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
>  				 struct intel_cdclk_state *cdclk_state)
>  {
> @@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>  	cdclk_state->cdclk = cdclk_state->ref;
>  
>  	if (cdclk_state->vco == 0)
> -		return;
> +		goto out;
>  
>  	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
>  
> @@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>  	}
>  
>  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> +
> + out:
> +	/*
> +	 * Can't read this out :( Let's assume it's
> +	 * at least what the CDCLK frequency requires.
> +	 */
> +	cdclk_state->voltage = cnl_calc_voltage(cdclk_state->cdclk);
>  }
>  
>  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> @@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  {
>  	int cdclk = cdclk_state->cdclk;
>  	int vco = cdclk_state->vco;
> -	u32 val, divider, pcu_ack;
> +	u32 val, divider;
>  	int ret;
>  
>  	mutex_lock(&dev_priv->pcu_lock);
> @@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  		break;
>  	}
>  
> -	switch (cdclk) {
> -	case 528000:
> -		pcu_ack = 2;
> -		break;
> -	case 336000:
> -		pcu_ack = 1;
> -		break;
> -	case 168000:
> -	default:
> -		pcu_ack = 0;
> -		break;
> -	}
> -
>  	if (dev_priv->cdclk.hw.vco != 0 &&
>  	    dev_priv->cdclk.hw.vco != vco)
>  		cnl_cdclk_pll_disable(dev_priv);
> @@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  
>  	/* inform PCU of the change */
>  	mutex_lock(&dev_priv->pcu_lock);
> -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> +				cdclk_state->voltage);
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	intel_update_cdclk(dev_priv);
> @@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv)
>  
>  	cdclk_state.cdclk = cnl_calc_cdclk(0);
>  	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk);
> +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
>  
>  	cnl_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
>  
>  	cdclk_state.cdclk = cdclk_state.ref;
>  	cdclk_state.vco = 0;
> +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
>  
>  	cnl_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = cnl_calc_cdclk(0);
> @@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  		intel_state->cdclk.actual.vco = vco;
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage = cnl_calc_voltage(cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-18 21:50   ` Rodrigo Vivi
@ 2017-10-18 22:43     ` Rodrigo Vivi
  2017-10-19 10:48     ` Ville Syrjälä
  1 sibling, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-18 22:43 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 09:50:59PM +0000, Rodrigo Vivi wrote:
> On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Track the system agent voltage we request from pcode in the cdclk state
> > on CNL. Annoyingly we can't actually read out the current value since
> > there's no pcode command to do that, so we'll have to just assume that
> > it worked.
> 
> +static u32 cnl_cur_voltage(struct drm_i915_private *dev_priv)
> +{
> +       u32 voltage;
> +       sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &voltage);
> +       return voltage;
> +}
> +
>  static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>                          struct intel_cdclk_state *cdclk_state)
>  {
> @@ -1486,8 +1493,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>  
>         cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
>  
> +       cdclk_state->voltage = cnl_cur_voltage(dev_priv);
>  }
>  
>  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> @@ -1594,8 +1600,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  
>         intel_update_cdclk(dev_priv);
>  
> +       dev_priv->cdclk.hw.voltage = cnl_cur_voltage(dev_priv);

Hmm... read works, but it triggers a
[  337.907234] [drm:pipe_config_err [i915]] *ERROR* mismatch in min_voltage (expected 0, found 1)

Because the hw voltage is global while the minimal local is only relative to that pipe.

I'm playing here with changes on top of the branch you sent yesterday...

git://people.freedesktop.org/~vivijim/drm-intel dvfs-atomic

trying to add the port_clock to the picture and the hw_state readout..

main doubt is where to get port_clock from during
cnl_modeset_calc_cdclk?

> 
> 
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_cdclk.c | 44 ++++++++++++++++++++++++--------------
> >  1 file changed, 28 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index 1b4dcd9689da..795a18f64c4c 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
> >  		return 168000;
> >  }
> >  
> > +static u8 cnl_calc_voltage(int cdclk)
> > +{
> > +	switch (cdclk) {
> > +	default:
> > +	case 168000:
> > +		return 0;
> > +	case 336000:
> > +		return 1;
> > +	case 528000:
> > +		return 2;
> > +	}
> > +}
> 
> where is the port_clock taking into account?
> 
> > +
> >  static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
> >  				 struct intel_cdclk_state *cdclk_state)
> >  {
> > @@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >  	cdclk_state->cdclk = cdclk_state->ref;
> >  
> >  	if (cdclk_state->vco == 0)
> > -		return;
> > +		goto out;
> >  
> >  	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
> >  
> > @@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >  	}
> >  
> >  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> > +
> > + out:
> > +	/*
> > +	 * Can't read this out :( Let's assume it's
> > +	 * at least what the CDCLK frequency requires.
> > +	 */
> > +	cdclk_state->voltage = cnl_calc_voltage(cdclk_state->cdclk);
> >  }
> >  
> >  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> > @@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  {
> >  	int cdclk = cdclk_state->cdclk;
> >  	int vco = cdclk_state->vco;
> > -	u32 val, divider, pcu_ack;
> > +	u32 val, divider;
> >  	int ret;
> >  
> >  	mutex_lock(&dev_priv->pcu_lock);
> > @@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  		break;
> >  	}
> >  
> > -	switch (cdclk) {
> > -	case 528000:
> > -		pcu_ack = 2;
> > -		break;
> > -	case 336000:
> > -		pcu_ack = 1;
> > -		break;
> > -	case 168000:
> > -	default:
> > -		pcu_ack = 0;
> > -		break;
> > -	}
> > -
> >  	if (dev_priv->cdclk.hw.vco != 0 &&
> >  	    dev_priv->cdclk.hw.vco != vco)
> >  		cnl_cdclk_pll_disable(dev_priv);
> > @@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  
> >  	/* inform PCU of the change */
> >  	mutex_lock(&dev_priv->pcu_lock);
> > -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> > +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > +				cdclk_state->voltage);
> >  	mutex_unlock(&dev_priv->pcu_lock);
> >  
> >  	intel_update_cdclk(dev_priv);
> > @@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv)
> >  
> >  	cdclk_state.cdclk = cnl_calc_cdclk(0);
> >  	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk);
> > +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
> >  
> >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> >  }
> > @@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
> >  
> >  	cdclk_state.cdclk = cdclk_state.ref;
> >  	cdclk_state.vco = 0;
> > +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
> >  
> >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> >  }
> > @@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  
> >  	intel_state->cdclk.logical.vco = vco;
> >  	intel_state->cdclk.logical.cdclk = cdclk;
> > +	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> >  
> >  	if (!intel_state->active_crtcs) {
> >  		cdclk = cnl_calc_cdclk(0);
> > @@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  
> >  		intel_state->cdclk.actual.vco = vco;
> >  		intel_state->cdclk.actual.cdclk = cdclk;
> > +		intel_state->cdclk.actual.voltage = cnl_calc_voltage(cdclk);
> >  	} else {
> >  		intel_state->cdclk.actual =
> >  			intel_state->cdclk.logical;
> > -- 
> > 2.13.6
> > 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 1/8] drm/i915: Clean up some cdclk switch statements
  2017-10-18 20:48 ` [PATCH 1/8] drm/i915: Clean up some cdclk switch statements Ville Syrjala
@ 2017-10-19  7:20   ` Mika Kahola
  0 siblings, 0 replies; 58+ messages in thread
From: Mika Kahola @ 2017-10-19  7:20 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx; +Cc: Rodrigo Vivi

On Wed, 2017-10-18 at 23:48 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Redo some switch statements in the cdclk code to use a common
> fall through for the default case. Makes everything look a bit
> more uniform
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>

> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 68 +++++++++++++++++++---------
> ----------
>  1 file changed, 34 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c
> b/drivers/gpu/drm/i915/intel_cdclk.c
> index b2a6d62b71c0..4bffd31a8924 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -681,6 +681,13 @@ static void bdw_set_cdclk(struct
> drm_i915_private *dev_priv,
>  	val &= ~LCPLL_CLK_FREQ_MASK;
>  
>  	switch (cdclk) {
> +	default:
> +		MISSING_CASE(cdclk);
> +		/* fall through */
> +	case 337500:
> +		val |= LCPLL_CLK_FREQ_337_5_BDW;
> +		data = 2;
> +		break;
>  	case 450000:
>  		val |= LCPLL_CLK_FREQ_450;
>  		data = 0;
> @@ -689,17 +696,10 @@ static void bdw_set_cdclk(struct
> drm_i915_private *dev_priv,
>  		val |= LCPLL_CLK_FREQ_54O_BDW;
>  		data = 1;
>  		break;
> -	case 337500:
> -		val |= LCPLL_CLK_FREQ_337_5_BDW;
> -		data = 2;
> -		break;
>  	case 675000:
>  		val |= LCPLL_CLK_FREQ_675_BDW;
>  		data = 3;
>  		break;
> -	default:
> -		WARN(1, "invalid cdclk frequency\n");
> -		return;
>  	}
>  
>  	I915_WRITE(LCPLL_CTL, val);
> @@ -926,8 +926,6 @@ static void skl_set_cdclk(struct drm_i915_private
> *dev_priv,
>  	u32 freq_select, pcu_ack;
>  	int ret;
>  
> -	WARN_ON((cdclk == 24000) != (vco == 0));
> -
>  	mutex_lock(&dev_priv->pcu_lock);
>  	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
>  				SKL_CDCLK_PREPARE_FOR_CHANGE,
> @@ -942,6 +940,15 @@ static void skl_set_cdclk(struct
> drm_i915_private *dev_priv,
>  
>  	/* set CDCLK_CTL */
>  	switch (cdclk) {
> +	default:
> +		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
> +		WARN_ON(vco != 0);
> +		/* fall through */
> +	case 308571:
> +	case 337500:
> +		freq_select = CDCLK_FREQ_337_308;
> +		pcu_ack = 0;
> +		break;
>  	case 450000:
>  	case 432000:
>  		freq_select = CDCLK_FREQ_450_432;
> @@ -951,12 +958,6 @@ static void skl_set_cdclk(struct
> drm_i915_private *dev_priv,
>  		freq_select = CDCLK_FREQ_540;
>  		pcu_ack = 2;
>  		break;
> -	case 308571:
> -	case 337500:
> -	default:
> -		freq_select = CDCLK_FREQ_337_308;
> -		pcu_ack = 0;
> -		break;
>  	case 617143:
>  	case 675000:
>  		freq_select = CDCLK_FREQ_675_617;
> @@ -1110,6 +1111,7 @@ static int bxt_de_pll_vco(struct
> drm_i915_private *dev_priv, int cdclk)
>  	switch (cdclk) {
>  	default:
>  		MISSING_CASE(cdclk);
> +		/* fall through */
>  	case 144000:
>  	case 288000:
>  	case 384000:
> @@ -1134,6 +1136,7 @@ static int glk_de_pll_vco(struct
> drm_i915_private *dev_priv, int cdclk)
>  	switch (cdclk) {
>  	default:
>  		MISSING_CASE(cdclk);
> +		/* fall through */
>  	case  79200:
>  	case 158400:
>  	case 316800:
> @@ -1246,24 +1249,22 @@ static void bxt_set_cdclk(struct
> drm_i915_private *dev_priv,
>  
>  	/* cdclk = vco / 2 / div{1,1.5,2,4} */
>  	switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
> -	case 8:
> -		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
> -		break;
> -	case 4:
> -		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
> +	default:
> +		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
> +		WARN_ON(vco != 0);
> +		/* fall through */
> +	case 2:
> +		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
>  		break;
>  	case 3:
>  		WARN(IS_GEMINILAKE(dev_priv), "Unsupported
> divider\n");
>  		divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
>  		break;
> -	case 2:
> -		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
> +	case 4:
> +		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
>  		break;
> -	default:
> -		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
> -		WARN_ON(vco != 0);
> -
> -		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
> +	case 8:
> +		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
>  		break;
>  	}
>  
> @@ -1532,18 +1533,16 @@ static void cnl_set_cdclk(struct
> drm_i915_private *dev_priv,
>  
>  	/* cdclk = vco / 2 / div{1,2} */
>  	switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
> -	case 4:
> -		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
> -		break;
> -	case 2:
> -		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
> -		break;
>  	default:
>  		WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
>  		WARN_ON(vco != 0);
> -
> +		/* fall through */
> +	case 2:
>  		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
>  		break;
> +	case 4:
> +		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
> +		break;
>  	}
>  
>  	switch (cdclk) {
> @@ -1592,6 +1591,7 @@ static int cnl_cdclk_pll_vco(struct
> drm_i915_private *dev_priv, int cdclk)
>  	switch (cdclk) {
>  	default:
>  		MISSING_CASE(cdclk);
> +		/* fall through */
>  	case 168000:
>  	case 336000:
>  		ratio = dev_priv->cdclk.hw.ref == 19200 ? 35 : 28;
-- 
Mika Kahola - Intel OTC

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-18 21:50   ` Rodrigo Vivi
  2017-10-18 22:43     ` Rodrigo Vivi
@ 2017-10-19 10:48     ` Ville Syrjälä
  2017-10-19 10:56       ` Mika Kahola
  2017-10-19 23:52       ` Rodrigo Vivi
  1 sibling, 2 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-19 10:48 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 02:50:59PM -0700, Rodrigo Vivi wrote:
> On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Track the system agent voltage we request from pcode in the cdclk state
> > on CNL. Annoyingly we can't actually read out the current value since
> > there's no pcode command to do that, so we'll have to just assume that
> > it worked.
> 
> +static u32 cnl_cur_voltage(struct drm_i915_private *dev_priv)
> +{
> +       u32 voltage;
> +       sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &voltage);

I don't think that'll work. _pcode_read() and _pcode_write() are actually
the same thing, the only difference is whether we return the resulting value
or not. Thus if we actually tried to do this we'd end up setting the
voltage instead of reading it. 

The only way to actually read anything is for pcode to specify a
specific read command. It's a rather unfortunate design of the
mailbox interface :(

We should perhaps put some WARNS into the pcode read/write functions so
that people don't accidentally use them in the wrong way.

> +       return voltage;
> +}
> +
>  static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>                          struct intel_cdclk_state *cdclk_state)
>  {
> @@ -1486,8 +1493,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>  
>         cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
>  
> +       cdclk_state->voltage = cnl_cur_voltage(dev_priv);
>  }
>  
>  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> @@ -1594,8 +1600,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  
>         intel_update_cdclk(dev_priv);
>  
> +       dev_priv->cdclk.hw.voltage = cnl_cur_voltage(dev_priv);
> 
> 
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_cdclk.c | 44 ++++++++++++++++++++++++--------------
> >  1 file changed, 28 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index 1b4dcd9689da..795a18f64c4c 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
> >  		return 168000;
> >  }
> >  
> > +static u8 cnl_calc_voltage(int cdclk)
> > +{
> > +	switch (cdclk) {
> > +	default:
> > +	case 168000:
> > +		return 0;
> > +	case 336000:
> > +		return 1;
> > +	case 528000:
> > +		return 2;
> > +	}
> > +}
> 
> where is the port_clock taking into account?

Last patch of the series.

> 
> > +
> >  static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
> >  				 struct intel_cdclk_state *cdclk_state)
> >  {
> > @@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >  	cdclk_state->cdclk = cdclk_state->ref;
> >  
> >  	if (cdclk_state->vco == 0)
> > -		return;
> > +		goto out;
> >  
> >  	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
> >  
> > @@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >  	}
> >  
> >  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> > +
> > + out:
> > +	/*
> > +	 * Can't read this out :( Let's assume it's
> > +	 * at least what the CDCLK frequency requires.
> > +	 */
> > +	cdclk_state->voltage = cnl_calc_voltage(cdclk_state->cdclk);
> >  }
> >  
> >  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> > @@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  {
> >  	int cdclk = cdclk_state->cdclk;
> >  	int vco = cdclk_state->vco;
> > -	u32 val, divider, pcu_ack;
> > +	u32 val, divider;
> >  	int ret;
> >  
> >  	mutex_lock(&dev_priv->pcu_lock);
> > @@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  		break;
> >  	}
> >  
> > -	switch (cdclk) {
> > -	case 528000:
> > -		pcu_ack = 2;
> > -		break;
> > -	case 336000:
> > -		pcu_ack = 1;
> > -		break;
> > -	case 168000:
> > -	default:
> > -		pcu_ack = 0;
> > -		break;
> > -	}
> > -
> >  	if (dev_priv->cdclk.hw.vco != 0 &&
> >  	    dev_priv->cdclk.hw.vco != vco)
> >  		cnl_cdclk_pll_disable(dev_priv);
> > @@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  
> >  	/* inform PCU of the change */
> >  	mutex_lock(&dev_priv->pcu_lock);
> > -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> > +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > +				cdclk_state->voltage);
> >  	mutex_unlock(&dev_priv->pcu_lock);
> >  
> >  	intel_update_cdclk(dev_priv);
> > @@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv)
> >  
> >  	cdclk_state.cdclk = cnl_calc_cdclk(0);
> >  	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk);
> > +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
> >  
> >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> >  }
> > @@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
> >  
> >  	cdclk_state.cdclk = cdclk_state.ref;
> >  	cdclk_state.vco = 0;
> > +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
> >  
> >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> >  }
> > @@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  
> >  	intel_state->cdclk.logical.vco = vco;
> >  	intel_state->cdclk.logical.cdclk = cdclk;
> > +	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> >  
> >  	if (!intel_state->active_crtcs) {
> >  		cdclk = cnl_calc_cdclk(0);
> > @@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  
> >  		intel_state->cdclk.actual.vco = vco;
> >  		intel_state->cdclk.actual.cdclk = cdclk;
> > +		intel_state->cdclk.actual.voltage = cnl_calc_voltage(cdclk);
> >  	} else {
> >  		intel_state->cdclk.actual =
> >  			intel_state->cdclk.logical;
> > -- 
> > 2.13.6
> > 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-19 10:48     ` Ville Syrjälä
@ 2017-10-19 10:56       ` Mika Kahola
  2017-10-19 12:19         ` Ville Syrjälä
  2017-10-19 23:52       ` Rodrigo Vivi
  1 sibling, 1 reply; 58+ messages in thread
From: Mika Kahola @ 2017-10-19 10:56 UTC (permalink / raw)
  To: Ville Syrjälä, Rodrigo Vivi; +Cc: intel-gfx

On Thu, 2017-10-19 at 13:48 +0300, Ville Syrjälä wrote:
> On Wed, Oct 18, 2017 at 02:50:59PM -0700, Rodrigo Vivi wrote:
> > 
> > On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> > > 
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Track the system agent voltage we request from pcode in the cdclk
> > > state
> > > on CNL. Annoyingly we can't actually read out the current value
> > > since
> > > there's no pcode command to do that, so we'll have to just assume
> > > that
> > > it worked.
> > +static u32 cnl_cur_voltage(struct drm_i915_private *dev_priv)
> > +{
> > +       u32 voltage;
> > +       sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > &voltage);
> I don't think that'll work. _pcode_read() and _pcode_write() are
> actually
> the same thing, the only difference is whether we return the
> resulting value
> or not. Thus if we actually tried to do this we'd end up setting the
> voltage instead of reading it. 
> 
> The only way to actually read anything is for pcode to specify a
> specific read command. It's a rather unfortunate design of the
> mailbox interface :(
> 
> We should perhaps put some WARNS into the pcode read/write functions
> so
> that people don't accidentally use them in the wrong way.
+1 for this. I was under the assumption that *read* means just reading
out the value.

> 
> > 
> > +       return voltage;
> > +}
> > +
> >  static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >                          struct intel_cdclk_state *cdclk_state)
> >  {
> > @@ -1486,8 +1493,7 @@ static void cnl_get_cdclk(struct
> > drm_i915_private *dev_priv,
> >  
> >         cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco,
> > div);
> >  
> > +       cdclk_state->voltage = cnl_cur_voltage(dev_priv);
> >  }
> >  
> >  static void cnl_cdclk_pll_disable(struct drm_i915_private
> > *dev_priv)
> > @@ -1594,8 +1600,7 @@ static void cnl_set_cdclk(struct
> > drm_i915_private *dev_priv,
> >  
> >         intel_update_cdclk(dev_priv);
> >  
> > +       dev_priv->cdclk.hw.voltage = cnl_cur_voltage(dev_priv);
> > 
> > 
> > > 
> > > 
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_cdclk.c | 44
> > > ++++++++++++++++++++++++--------------
> > >  1 file changed, 28 insertions(+), 16 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c
> > > b/drivers/gpu/drm/i915/intel_cdclk.c
> > > index 1b4dcd9689da..795a18f64c4c 100644
> > > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > > @@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
> > >  		return 168000;
> > >  }
> > >  
> > > +static u8 cnl_calc_voltage(int cdclk)
> > > +{
> > > +	switch (cdclk) {
> > > +	default:
> > > +	case 168000:
> > > +		return 0;
> > > +	case 336000:
> > > +		return 1;
> > > +	case 528000:
> > > +		return 2;
> > > +	}
> > > +}
> > where is the port_clock taking into account?
> Last patch of the series.
> 
> > 
> > 
> > > 
> > > +
> > >  static void cnl_cdclk_pll_update(struct drm_i915_private
> > > *dev_priv,
> > >  				 struct intel_cdclk_state
> > > *cdclk_state)
> > >  {
> > > @@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct
> > > drm_i915_private *dev_priv,
> > >  	cdclk_state->cdclk = cdclk_state->ref;
> > >  
> > >  	if (cdclk_state->vco == 0)
> > > -		return;
> > > +		goto out;
> > >  
> > >  	divider = I915_READ(CDCLK_CTL) &
> > > BXT_CDCLK_CD2X_DIV_SEL_MASK;
> > >  
> > > @@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct
> > > drm_i915_private *dev_priv,
> > >  	}
> > >  
> > >  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, 
> > > div);
> > > +
> > > + out:
> > > +	/*
> > > +	 * Can't read this out :( Let's assume it's
> > > +	 * at least what the CDCLK frequency requires.
> > > +	 */
> > > +	cdclk_state->voltage = cnl_calc_voltage(cdclk_state-
> > > >cdclk);
> > >  }
> > >  
> > >  static void cnl_cdclk_pll_disable(struct drm_i915_private
> > > *dev_priv)
> > > @@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct
> > > drm_i915_private *dev_priv,
> > >  {
> > >  	int cdclk = cdclk_state->cdclk;
> > >  	int vco = cdclk_state->vco;
> > > -	u32 val, divider, pcu_ack;
> > > +	u32 val, divider;
> > >  	int ret;
> > >  
> > >  	mutex_lock(&dev_priv->pcu_lock);
> > > @@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct
> > > drm_i915_private *dev_priv,
> > >  		break;
> > >  	}
> > >  
> > > -	switch (cdclk) {
> > > -	case 528000:
> > > -		pcu_ack = 2;
> > > -		break;
> > > -	case 336000:
> > > -		pcu_ack = 1;
> > > -		break;
> > > -	case 168000:
> > > -	default:
> > > -		pcu_ack = 0;
> > > -		break;
> > > -	}
> > > -
> > >  	if (dev_priv->cdclk.hw.vco != 0 &&
> > >  	    dev_priv->cdclk.hw.vco != vco)
> > >  		cnl_cdclk_pll_disable(dev_priv);
> > > @@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct
> > > drm_i915_private *dev_priv,
> > >  
> > >  	/* inform PCU of the change */
> > >  	mutex_lock(&dev_priv->pcu_lock);
> > > -	sandybridge_pcode_write(dev_priv,
> > > SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> > > +	sandybridge_pcode_write(dev_priv,
> > > SKL_PCODE_CDCLK_CONTROL,
> > > +				cdclk_state->voltage);
> > >  	mutex_unlock(&dev_priv->pcu_lock);
> > >  
> > >  	intel_update_cdclk(dev_priv);
> > > @@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private
> > > *dev_priv)
> > >  
> > >  	cdclk_state.cdclk = cnl_calc_cdclk(0);
> > >  	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv,
> > > cdclk_state.cdclk);
> > > +	cdclk_state.voltage =
> > > cnl_calc_voltage(cdclk_state.cdclk);
> > >  
> > >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> > >  }
> > > @@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct
> > > drm_i915_private *dev_priv)
> > >  
> > >  	cdclk_state.cdclk = cdclk_state.ref;
> > >  	cdclk_state.vco = 0;
> > > +	cdclk_state.voltage =
> > > cnl_calc_voltage(cdclk_state.cdclk);
> > >  
> > >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> > >  }
> > > @@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct
> > > drm_atomic_state *state)
> > >  
> > >  	intel_state->cdclk.logical.vco = vco;
> > >  	intel_state->cdclk.logical.cdclk = cdclk;
> > > +	intel_state->cdclk.logical.voltage =
> > > cnl_calc_voltage(cdclk);
> > >  
> > >  	if (!intel_state->active_crtcs) {
> > >  		cdclk = cnl_calc_cdclk(0);
> > > @@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct
> > > drm_atomic_state *state)
> > >  
> > >  		intel_state->cdclk.actual.vco = vco;
> > >  		intel_state->cdclk.actual.cdclk = cdclk;
> > > +		intel_state->cdclk.actual.voltage =
> > > cnl_calc_voltage(cdclk);
> > >  	} else {
> > >  		intel_state->cdclk.actual =
> > >  			intel_state->cdclk.logical;
> > > -- 
> > > 2.13.6
> > > 
-- 
Mika Kahola - Intel OTC

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-19 10:56       ` Mika Kahola
@ 2017-10-19 12:19         ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-19 12:19 UTC (permalink / raw)
  To: Mika Kahola; +Cc: intel-gfx, Rodrigo Vivi

On Thu, Oct 19, 2017 at 01:56:38PM +0300, Mika Kahola wrote:
> On Thu, 2017-10-19 at 13:48 +0300, Ville Syrjälä wrote:
> > On Wed, Oct 18, 2017 at 02:50:59PM -0700, Rodrigo Vivi wrote:
> > > 
> > > On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> > > > 
> > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > 
> > > > Track the system agent voltage we request from pcode in the cdclk
> > > > state
> > > > on CNL. Annoyingly we can't actually read out the current value
> > > > since
> > > > there's no pcode command to do that, so we'll have to just assume
> > > > that
> > > > it worked.
> > > +static u32 cnl_cur_voltage(struct drm_i915_private *dev_priv)
> > > +{
> > > +       u32 voltage;
> > > +       sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > > &voltage);
> > I don't think that'll work. _pcode_read() and _pcode_write() are
> > actually
> > the same thing, the only difference is whether we return the
> > resulting value
> > or not. Thus if we actually tried to do this we'd end up setting the
> > voltage instead of reading it. 
> > 
> > The only way to actually read anything is for pcode to specify a
> > specific read command. It's a rather unfortunate design of the
> > mailbox interface :(
> > 
> > We should perhaps put some WARNS into the pcode read/write functions
> > so
> > that people don't accidentally use them in the wrong way.
> +1 for this. I was under the assumption that *read* means just reading
> out the value.

Do you want to volunteer for that?

Looking at the current _read() uses, the only one that looks a bit
suspicious is the DUTY_CYCLE_CONTROL. Not sure that's actually
working as expected... Hmm, looks like it's fine actually. Some HSW
PM doc I have says that data0=0x0 means "read dynamic RPe", and
data0=0x1 means "send PCU interrupt when we can go back to RPe".
We might want to add some defines for those magic values to make
the code look less suspicious.

Another thing we could do is deduplicate the code in the 
pcode_read/write functions. Eg. write() could just call read()
maybe, or pull the code into a common _rw() helper (like we
have for the VLV/CHV sideband stuff). Oh, and looks like
intel_sbi_read/write could use the same treatment as well.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing
  2017-10-18 21:07 ` ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing Patchwork
@ 2017-10-19 17:31   ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-19 17:31 UTC (permalink / raw)
  To: intel-gfx

On Wed, Oct 18, 2017 at 09:07:37PM -0000, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915: CNL DVFS thing
> URL   : https://patchwork.freedesktop.org/series/32247/
> State : warning
> 
> == Summary ==
> 
> Series 32247v1 drm/i915: CNL DVFS thing
> https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/1/mbox/
> 
> Test debugfs_test:
>         Subgroup read_all_entries:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)

[   57.469230] [drm:chv_set_cdclk [i915]] *ERROR* timed out waiting for CDclk change

Curious. I wonder what I broke there...

> Test gem_exec_suspend:
>         Subgroup basic-s3:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-s4-devices:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
> Test kms_busy:
>         Subgroup basic-flip-a:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup basic-flip-b:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup basic-flip-c:
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
> Test kms_cursor_legacy:
>         Subgroup basic-busy-flip-before-cursor-atomic:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-busy-flip-before-cursor-legacy:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-after-cursor-atomic:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-after-cursor-legacy:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-after-cursor-varying-size:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-before-cursor-atomic:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-before-cursor-legacy:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-before-cursor-varying-size:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
> Test kms_flip:
>         Subgroup basic-flip-vs-dpms:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-vs-modeset:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-flip-vs-wf_vblank:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup basic-plain-flip:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
> Test kms_force_connector_basic:
>         Subgroup force-connector-state:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup force-load-detect:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
> Test kms_frontbuffer_tracking:
>         Subgroup basic:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
> Test kms_pipe_crc_basic:
>         Subgroup hang-read-crc-pipe-a:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup hang-read-crc-pipe-b:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup hang-read-crc-pipe-c:
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup nonblocking-crc-pipe-a:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup nonblocking-crc-pipe-a-frame-sequence:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup nonblocking-crc-pipe-b:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup nonblocking-crc-pipe-b-frame-sequence:
>                 pass       -> DMESG-WARN (fi-byt-j1900) fdo#102619
>         Subgroup nonblocking-crc-pipe-c:
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup nonblocking-crc-pipe-c-frame-sequence:
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup read-crc-pipe-a:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup read-crc-pipe-a-frame-sequence:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup read-crc-pipe-b:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup read-crc-pipe-b-frame-sequence:
>                 pass       -> DMESG-WARN (fi-byt-j1900)
>         Subgroup read-crc-pipe-c:
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup read-crc-pipe-c-frame-sequence:
>                 pass       -> DMESG-WARN (fi-bsw-n3050)
>         Subgroup suspend-read-crc-pipe-a:
> WARNING: Long output truncated
> fi-pnv-d510 failed to connect after reboot
> 
> 7edf6833df0ac2c6d24969d48074203bd305e623 drm-tip: 2017y-10m-18d-16h-29m-02s UTC integration manifest
> c02f9fc7b3a5 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
> 22471d3e6efc drm/i915: Use cdclk_state->voltage on CNL
> ce351d159829 drm/i915: Use cdclk_state->voltage on BXT/GLK
> 1be4a076d2df drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
> 1fe8bd7e3a7c drm/i915: Use cdclk_state->voltage on BDW
> 3c6e69440b86 drm/i915: USe cdclk_state->voltage on VLV/CHV
> 0cb95d769249 drm/i915: Start tracking voltage level in the cdclk state
> 77b5c93acd63 drm/i915: Clean up some cdclk switch statements
> 
> == Logs ==
> 
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6096/

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v2 3/8] drm/i915: Use cdclk_state->voltage on VLV/CHV
  2017-10-18 20:48 ` [PATCH 3/8] drm/i915: USe cdclk_state->voltage on VLV/CHV Ville Syrjala
@ 2017-10-19 17:43   ` Ville Syrjala
  2017-10-19 23:42     ` Rodrigo Vivi
  2017-10-20 17:03   ` [PATCH v3 " Ville Syrjala
  1 sibling, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-19 17:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Store the punit DSPFREQUAR value into cdclk_state->voltage on
VLV/CHV. Since we can actually read that out from the hardware
this can give us a bit more cross checking between the hardware
and software state.

v2: Don't break waiting for cdclk change on VLV/CHV

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 66 +++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 522222f8bb50..9cc4374797eb 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -437,13 +437,45 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
 		return 200000;
 }
 
+static u8 vlv_calc_voltage(struct drm_i915_private *dev_priv, int cdclk)
+{
+	if (IS_VALLEYVIEW(dev_priv)) {
+		if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
+			return 2;
+		else if (cdclk >= 266667)
+			return 1;
+		else
+			return 0;
+	} else {
+		/*
+		 * Specs are full of misinformation, but testing on actual
+		 * hardware has shown that we just need to write the desired
+		 * CCK divider into the Punit register.
+		 */
+		return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
+	}
+}
+
 static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
 			  struct intel_cdclk_state *cdclk_state)
 {
+	u32 val;
+
 	cdclk_state->vco = vlv_get_hpll_vco(dev_priv);
 	cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
 					       CCK_DISPLAY_CLOCK_CONTROL,
 					       cdclk_state->vco);
+
+	mutex_lock(&dev_priv->pcu_lock);
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	mutex_unlock(&dev_priv->pcu_lock);
+
+	if (IS_VALLEYVIEW(dev_priv))
+		cdclk_state->voltage = (val & DSPFREQGUAR_MASK) >>
+			DSPFREQGUAR_SHIFT;
+	else
+		cdclk_state->voltage = (val & DSPFREQGUAR_MASK_CHV) >>
+			DSPFREQGUAR_SHIFT_CHV;
 }
 
 static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
@@ -486,7 +518,19 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_state *cdclk_state)
 {
 	int cdclk = cdclk_state->cdclk;
-	u32 val, cmd;
+	u32 val, cmd = cdclk_state->voltage;
+
+	switch (cdclk) {
+	case 400000:
+	case 333333:
+	case 320000:
+	case 266667:
+	case 200000:
+		break;
+	default:
+		MISSING_CASE(cdclk);
+		return;
+	}
 
 	/* There are cases where we can end up here with power domains
 	 * off and a CDCLK frequency other than the minimum, like when
@@ -496,13 +540,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
-	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
-		cmd = 2;
-	else if (cdclk == 266667)
-		cmd = 1;
-	else
-		cmd = 0;
-
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK;
@@ -562,7 +599,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_state *cdclk_state)
 {
 	int cdclk = cdclk_state->cdclk;
-	u32 val, cmd;
+	u32 val, cmd = cdclk_state->voltage;
 
 	switch (cdclk) {
 	case 333333:
@@ -583,13 +620,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
-	/*
-	 * Specs are full of misinformation, but testing on actual
-	 * hardware has shown that we just need to write the desired
-	 * CCK divider into the Punit register.
-	 */
-	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
-
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK_CHV;
@@ -1859,11 +1889,15 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
 	cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
 
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage =
+		vlv_calc_voltage(dev_priv, cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = vlv_calc_cdclk(dev_priv, 0);
 
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage =
+			vlv_calc_voltage(dev_priv, cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* ✗ Fi.CI.BAT: failure for drm/i915: CNL DVFS thing (rev2)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (8 preceding siblings ...)
  2017-10-18 21:07 ` ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing Patchwork
@ 2017-10-19 18:17 ` Patchwork
  2017-10-19 18:52 ` Patchwork
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-19 18:17 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev2)
URL   : https://patchwork.freedesktop.org/series/32247/
State : failure

== Summary ==

Series 32247v2 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/2/mbox/

Test kms_busy:
        Subgroup basic-flip-b:
                fail       -> PASS       (fi-gdg-551) fdo#102654
Test kms_cursor_legacy:
        Subgroup basic-busy-flip-before-cursor-legacy:
                fail       -> PASS       (fi-gdg-551) fdo#102618
        Subgroup basic-flip-after-cursor-varying-size:
                incomplete -> PASS       (fi-skl-6260u)
Test kms_pipe_crc_basic:
        Subgroup nonblocking-crc-pipe-a:
                pass       -> INCOMPLETE (fi-skl-6700hq)

fdo#102654 https://bugs.freedesktop.org/show_bug.cgi?id=102654
fdo#102618 https://bugs.freedesktop.org/show_bug.cgi?id=102618

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:439s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:448s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:377s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:514s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:264s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:493s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:496s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:491s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:478s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:559s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:416s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:250s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:579s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:443s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:429s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:435s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:493s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:462s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:486s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:570s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:477s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:584s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:548s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:450s
fi-skl-6700hq    total:233  pass:208  dwarn:0   dfail:0   fail:0   skip:24 
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:508s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:500s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:455s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:560s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:417s

9024f1a2827aa921560ee3f985a5b418ef296435 drm-tip: 2017y-10m-19d-12h-57m-03s UTC integration manifest
a47c474f5bb3 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
ad731a2dd2c8 drm/i915: Use cdclk_state->voltage on CNL
cef8e0749338 drm/i915: Use cdclk_state->voltage on BXT/GLK
bf835fb0553b drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
7023b46c7035 drm/i915: Use cdclk_state->voltage on BDW
888417332cda drm/i915: Use cdclk_state->voltage on VLV/CHV
42ebf0bcacda drm/i915: Start tracking voltage level in the cdclk state
2d0f7ed970e9 drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6109/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* ✗ Fi.CI.BAT: failure for drm/i915: CNL DVFS thing (rev2)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (9 preceding siblings ...)
  2017-10-19 18:17 ` ✗ Fi.CI.BAT: failure for drm/i915: CNL DVFS thing (rev2) Patchwork
@ 2017-10-19 18:52 ` Patchwork
  2017-10-19 20:07 ` ✗ Fi.CI.BAT: warning " Patchwork
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-19 18:52 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev2)
URL   : https://patchwork.freedesktop.org/series/32247/
State : failure

== Summary ==

Series 32247v2 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/2/mbox/

Test kms_busy:
        Subgroup basic-flip-a:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-b:
                fail       -> PASS       (fi-gdg-551) fdo#102654
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-c:
                pass       -> SKIP       (fi-hsw-4770r)
Test kms_cursor_legacy:
        Subgroup basic-busy-flip-before-cursor-atomic:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-busy-flip-before-cursor-legacy:
                fail       -> PASS       (fi-gdg-551) fdo#102618
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-after-cursor-atomic:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-after-cursor-legacy:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-after-cursor-varying-size:
                pass       -> SKIP       (fi-hsw-4770r)
                incomplete -> PASS       (fi-skl-6260u)
        Subgroup basic-flip-before-cursor-atomic:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-before-cursor-legacy:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-before-cursor-varying-size:
                pass       -> SKIP       (fi-hsw-4770r)
Test kms_flip:
        Subgroup basic-flip-vs-dpms:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-vs-modeset:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-vs-wf_vblank:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-plain-flip:
                pass       -> SKIP       (fi-hsw-4770r)
                pass       -> INCOMPLETE (fi-skl-6700hq)
Test kms_frontbuffer_tracking:
        Subgroup basic:
                pass       -> SKIP       (fi-hsw-4770r)
Test kms_pipe_crc_basic:
        Subgroup hang-read-crc-pipe-a:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup hang-read-crc-pipe-b:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup hang-read-crc-pipe-c:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup nonblocking-crc-pipe-a:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup nonblocking-crc-pipe-a-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup nonblocking-crc-pipe-b:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup nonblocking-crc-pipe-b-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup nonblocking-crc-pipe-c:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup nonblocking-crc-pipe-c-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup read-crc-pipe-a:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup read-crc-pipe-a-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup read-crc-pipe-b:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup read-crc-pipe-b-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r) fdo#102332
        Subgroup read-crc-pipe-c:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup read-crc-pipe-c-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup suspend-read-crc-pipe-a:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup suspend-read-crc-pipe-b:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup suspend-read-crc-pipe-c:
                pass       -> SKIP       (fi-hsw-4770r)
Test pm_rpm:
        Subgroup basic-pci-d3-state:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-rte:
                pass       -> SKIP       (fi-hsw-4770r)
Test prime_vgem:
        Subgroup basic-fence-flip:
                pass       -> SKIP       (fi-hsw-4770r)

fdo#102654 https://bugs.freedesktop.org/show_bug.cgi?id=102654
fdo#102618 https://bugs.freedesktop.org/show_bug.cgi?id=102618
fdo#102332 https://bugs.freedesktop.org/show_bug.cgi?id=102332

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:439s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:452s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:371s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:526s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:262s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:491s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:486s
WARNING: Long output truncated

9024f1a2827aa921560ee3f985a5b418ef296435 drm-tip: 2017y-10m-19d-12h-57m-03s UTC integration manifest
250796ca0521 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
ad194e769e42 drm/i915: Use cdclk_state->voltage on CNL
dc248c1f8f10 drm/i915: Use cdclk_state->voltage on BXT/GLK
b8c0996e3e8f drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
eac5bdf5ed82 drm/i915: Use cdclk_state->voltage on BDW
e1f9f68725f0 drm/i915: Use cdclk_state->voltage on VLV/CHV
c0c0b19d9766 drm/i915: Start tracking voltage level in the cdclk state
37bfe54b7bc1 drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6110/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing (rev2)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (10 preceding siblings ...)
  2017-10-19 18:52 ` Patchwork
@ 2017-10-19 20:07 ` Patchwork
  2017-10-19 23:27 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-19 20:07 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev2)
URL   : https://patchwork.freedesktop.org/series/32247/
State : warning

== Summary ==

Series 32247v2 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/2/mbox/

Test kms_flip:
        Subgroup basic-flip-vs-wf_vblank:
                incomplete -> PASS       (fi-skl-6700hq)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                pass       -> DMESG-WARN (fi-byt-n2820) fdo#101705
Test prime_vgem:
        Subgroup basic-fence-flip:
                pass       -> DMESG-WARN (fi-kbl-7567u)

fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:439s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:455s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:371s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:515s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:266s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:499s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:494s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:498s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:473s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:559s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:419s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:252s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:580s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:450s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:425s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:432s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:498s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:461s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:485s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:574s
fi-kbl-7567u     total:289  pass:268  dwarn:1   dfail:0   fail:0   skip:20  time:497s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:583s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:539s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:452s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:647s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:502s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:457s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:561s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:422s
fi-skl-6700k failed to connect after reboot

87b113da0ae43b97650ddcec6c05ef69469e2107 drm-tip: 2017y-10m-19d-18h-14m-41s UTC integration manifest
f392fa125360 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
c98ae974506a drm/i915: Use cdclk_state->voltage on CNL
4ebfa4bd61ec drm/i915: Use cdclk_state->voltage on BXT/GLK
d402b82451e2 drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
7a47d927ff10 drm/i915: Use cdclk_state->voltage on BDW
380201ee642b drm/i915: Use cdclk_state->voltage on VLV/CHV
7163b02f9819 drm/i915: Start tracking voltage level in the cdclk state
ca505a66dcdb drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6113/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev2)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (11 preceding siblings ...)
  2017-10-19 20:07 ` ✗ Fi.CI.BAT: warning " Patchwork
@ 2017-10-19 23:27 ` Patchwork
  2017-10-20  0:22 ` ✓ Fi.CI.IGT: " Patchwork
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-19 23:27 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev2)
URL   : https://patchwork.freedesktop.org/series/32247/
State : success

== Summary ==

Series 32247v2 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/2/mbox/

Test kms_flip:
        Subgroup basic-flip-vs-wf_vblank:
                incomplete -> PASS       (fi-skl-6700hq)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                pass       -> DMESG-WARN (fi-byt-n2820) fdo#101705

fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:438s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:451s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:371s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:529s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:266s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:496s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:494s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:497s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:480s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:569s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:418s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:249s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:576s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:449s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:426s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:435s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:486s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:457s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:489s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:571s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:474s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:585s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:541s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:442s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:654s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:526s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:495s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:456s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:567s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:417s

87b113da0ae43b97650ddcec6c05ef69469e2107 drm-tip: 2017y-10m-19d-18h-14m-41s UTC integration manifest
84c5e3f60750 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
d7a8a9c662a2 drm/i915: Use cdclk_state->voltage on CNL
0bfa89acae45 drm/i915: Use cdclk_state->voltage on BXT/GLK
f558caf969be drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
ade1a80f438b drm/i915: Use cdclk_state->voltage on BDW
56387c5c30c5 drm/i915: Use cdclk_state->voltage on VLV/CHV
8cc699fdd699 drm/i915: Start tracking voltage level in the cdclk state
7f610d7180b6 drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6116/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state
  2017-10-18 20:48 ` [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state Ville Syrjala
@ 2017-10-19 23:32   ` Rodrigo Vivi
  2017-10-20 14:01   ` Ville Syrjälä
  1 sibling, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-19 23:32 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 08:48:19PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> For CNL we'll need to start considering the port clocks when we select
> the voltage level for the system agent. To that end start tracking the
> voltage in the cdclk state (since that already has to adjust it).
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h         |  1 +
>  drivers/gpu/drm/i915/intel_cdclk.c      | 31 ++++++++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_display.c    |  8 ++++----
>  drivers/gpu/drm/i915/intel_drv.h        |  4 +++-
>  drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++-
>  5 files changed, 34 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index f01c80076c59..d3ac58dc275f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2227,6 +2227,7 @@ struct i915_oa_ops {
>  
>  struct intel_cdclk_state {
>  	unsigned int cdclk, vco, ref;
> +	u8 voltage;
>  };
>  
>  struct drm_i915_private {
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 4bffd31a8924..522222f8bb50 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1690,17 +1690,34 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
>  }
>  
>  /**
> - * intel_cdclk_state_compare - Determine if two CDCLK states differ
> + * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes
>   * @a: first CDCLK state
>   * @b: second CDCLK state
>   *
>   * Returns:
> - * True if the CDCLK states are identical, false if they differ.
> + * True if the CDCLK states require pipes to be off during reprogramming, false if not.
>   */
> -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
>  			       const struct intel_cdclk_state *b)
>  {
> -	return memcmp(a, b, sizeof(*a)) == 0;
> +	return a->cdclk != b->cdclk ||
> +		a->vco != b->vco ||
> +		a->ref != b->ref;
> +}
> +
> +/**
> + * intel_cdclk_changed - Determine if two CDCLK states are different
> + * @a: first CDCLK state
> + * @b: second CDCLK state
> + *
> + * Returns:
> + * True if the CDCLK states don't match, false if they do.
> + */
> +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> +			 const struct intel_cdclk_state *b)
> +{
> +	return intel_cdclk_needs_modeset(a, b) ||
> +		a->voltage != b->voltage;
>  }
>  
>  /**
> @@ -1714,15 +1731,15 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
>  void intel_set_cdclk(struct drm_i915_private *dev_priv,
>  		     const struct intel_cdclk_state *cdclk_state)
>  {
> -	if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state))
> +	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state))
>  		return;
>  
>  	if (WARN_ON_ONCE(!dev_priv->display.set_cdclk))
>  		return;
>  
> -	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n",
> +	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz, voltage %d\n",
>  			 cdclk_state->cdclk, cdclk_state->vco,
> -			 cdclk_state->ref);
> +			 cdclk_state->ref, cdclk_state->voltage);
>  
>  	dev_priv->display.set_cdclk(dev_priv, cdclk_state);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index bd62c0a65bcd..32e7cca52da2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11946,16 +11946,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  		 * holding all the crtc locks, even if we don't end up
>  		 * touching the hardware
>  		 */
> -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
> -					       &intel_state->cdclk.logical)) {
> +		if (intel_cdclk_changed(&dev_priv->cdclk.logical,
> +					&intel_state->cdclk.logical)) {
>  			ret = intel_lock_all_pipes(state);
>  			if (ret < 0)
>  				return ret;
>  		}
>  
>  		/* All pipes must be switched off while we change the cdclk. */
> -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
> -					       &intel_state->cdclk.actual)) {
> +		if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual,
> +					      &intel_state->cdclk.actual)) {
>  			ret = intel_modeset_all_pipes(state);
>  			if (ret < 0)
>  				return ret;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a05ab3a1ab27..765a737700c5 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1324,8 +1324,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
>  void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
>  void intel_update_cdclk(struct drm_i915_private *dev_priv);
>  void intel_update_rawclk(struct drm_i915_private *dev_priv);
> -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
>  			       const struct intel_cdclk_state *b);
> +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> +			 const struct intel_cdclk_state *b);
>  void intel_set_cdclk(struct drm_i915_private *dev_priv,
>  		     const struct intel_cdclk_state *cdclk_state);
>  
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index 8af286c63d3b..5ac553fab7c7 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
>  	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
>  
>  	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
> -	WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
> +	/* Can't read out the voltage so can't use intel_cdclk_changed() */
> +	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
>  
>  	gen9_assert_dbuf_enabled(dev_priv);
>  
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v2 3/8] drm/i915: Use cdclk_state->voltage on VLV/CHV
  2017-10-19 17:43   ` [PATCH v2 3/8] drm/i915: Use " Ville Syrjala
@ 2017-10-19 23:42     ` Rodrigo Vivi
  2017-10-20 16:20       ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-19 23:42 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Oct 19, 2017 at 05:43:29PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Store the punit DSPFREQUAR value into cdclk_state->voltage on
> VLV/CHV. Since we can actually read that out from the hardware
> this can give us a bit more cross checking between the hardware
> and software state.
> 
> v2: Don't break waiting for cdclk change on VLV/CHV
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 66 +++++++++++++++++++++++++++++---------
>  1 file changed, 50 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 522222f8bb50..9cc4374797eb 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -437,13 +437,45 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
>  		return 200000;
>  }
>  
> +static u8 vlv_calc_voltage(struct drm_i915_private *dev_priv, int cdclk)
> +{
> +	if (IS_VALLEYVIEW(dev_priv)) {
> +		if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
> +			return 2;
> +		else if (cdclk >= 266667)
> +			return 1;
> +		else
> +			return 0;
> +	} else {
> +		/*
> +		 * Specs are full of misinformation, but testing on actual
> +		 * hardware has shown that we just need to write the desired
> +		 * CCK divider into the Punit register.
> +		 */
> +		return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
> +	}
> +}
> +
>  static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
>  			  struct intel_cdclk_state *cdclk_state)
>  {
> +	u32 val;
> +
>  	cdclk_state->vco = vlv_get_hpll_vco(dev_priv);
>  	cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
>  					       CCK_DISPLAY_CLOCK_CONTROL,
>  					       cdclk_state->vco);
> +
> +	mutex_lock(&dev_priv->pcu_lock);
> +	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
> +	mutex_unlock(&dev_priv->pcu_lock);
> +
> +	if (IS_VALLEYVIEW(dev_priv))
> +		cdclk_state->voltage = (val & DSPFREQGUAR_MASK) >>
> +			DSPFREQGUAR_SHIFT;
> +	else
> +		cdclk_state->voltage = (val & DSPFREQGUAR_MASK_CHV) >>
> +			DSPFREQGUAR_SHIFT_CHV;

Oh interresting that vlv is the only one where we can actually read it. :(

I was going to ask pointers to spec, but just by {vlv,chv}_set_cdclk it was
possible to verify this is right.

>  }
>  
>  static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
> @@ -486,7 +518,19 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
>  			  const struct intel_cdclk_state *cdclk_state)
>  {
>  	int cdclk = cdclk_state->cdclk;
> -	u32 val, cmd;
> +	u32 val, cmd = cdclk_state->voltage;
> +
> +	switch (cdclk) {
> +	case 400000:
> +	case 333333:
> +	case 320000:
> +	case 266667:
> +	case 200000:
> +		break;
> +	default:
> +		MISSING_CASE(cdclk);
> +		return;
> +	}

I believe this should be in a separated patch, no?!
Seems something we were already missing anyways.

But anyways, if you decide to split or not

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

>  
>  	/* There are cases where we can end up here with power domains
>  	 * off and a CDCLK frequency other than the minimum, like when
> @@ -496,13 +540,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
>  	 */
>  	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
>  
> -	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
> -		cmd = 2;
> -	else if (cdclk == 266667)
> -		cmd = 1;
> -	else
> -		cmd = 0;
> -
>  	mutex_lock(&dev_priv->pcu_lock);
>  	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
>  	val &= ~DSPFREQGUAR_MASK;
> @@ -562,7 +599,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
>  			  const struct intel_cdclk_state *cdclk_state)
>  {
>  	int cdclk = cdclk_state->cdclk;
> -	u32 val, cmd;
> +	u32 val, cmd = cdclk_state->voltage;
>  
>  	switch (cdclk) {
>  	case 333333:
> @@ -583,13 +620,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
>  	 */
>  	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
>  
> -	/*
> -	 * Specs are full of misinformation, but testing on actual
> -	 * hardware has shown that we just need to write the desired
> -	 * CCK divider into the Punit register.
> -	 */
> -	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
> -
>  	mutex_lock(&dev_priv->pcu_lock);
>  	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
>  	val &= ~DSPFREQGUAR_MASK_CHV;
> @@ -1859,11 +1889,15 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
>  	cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
>  
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage =
> +		vlv_calc_voltage(dev_priv, cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = vlv_calc_cdclk(dev_priv, 0);
>  
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage =
> +			vlv_calc_voltage(dev_priv, cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW
  2017-10-18 20:48 ` [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW Ville Syrjala
@ 2017-10-19 23:44   ` Rodrigo Vivi
  2017-10-20 16:14     ` Ville Syrjälä
  2017-10-20 17:03   ` [PATCH v2 " Ville Syrjala
  1 sibling, 1 reply; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-19 23:44 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 08:48:21PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Track the system agent voltage we request from pcode in the cdclk state
> on BDW. Annoyingly we can't actually read out the current value since
> there's no pcode command to do that, so we'll have to just assume that
> it worked.
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 36 ++++++++++++++++++++++++++----------
>  1 file changed, 26 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index df71667c9fd6..7442e9443ffa 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -648,6 +648,21 @@ static int bdw_calc_cdclk(int min_cdclk)
>  		return 337500;
>  }
>  
> +static u8 bdw_calc_voltage(int cdclk)
> +{
> +	switch (cdclk) {
> +	default:
> +	case 337500:
> +		return 2;
> +	case 450000:
> +		return 0;
> +	case 540000:
> +		return 1;
> +	case 675000:
> +		return 3;
> +	}
> +}
> +
>  static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
>  			  struct intel_cdclk_state *cdclk_state)
>  {
> @@ -666,13 +681,19 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
>  		cdclk_state->cdclk = 337500;
>  	else
>  		cdclk_state->cdclk = 675000;
> +
> +	/*
> +	 * Can't read this out :( Let's assume it's
> +	 * at least what the CDCLK frequency requires.
> +	 */
> +	cdclk_state->voltage = bdw_calc_voltage(cdclk_state->cdclk);
>  }
>  
>  static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
>  			  const struct intel_cdclk_state *cdclk_state)
>  {
>  	int cdclk = cdclk_state->cdclk;
> -	uint32_t val, data;
> +	uint32_t val;
>  	int ret;
>  
>  	if (WARN((I915_READ(LCPLL_CTL) &
> @@ -713,19 +734,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
>  		/* fall through */
>  	case 337500:
>  		val |= LCPLL_CLK_FREQ_337_5_BDW;
> -		data = 2;
>  		break;
>  	case 450000:
>  		val |= LCPLL_CLK_FREQ_450;
> -		data = 0;
>  		break;
>  	case 540000:
>  		val |= LCPLL_CLK_FREQ_54O_BDW;
> -		data = 1;
>  		break;
>  	case 675000:
>  		val |= LCPLL_CLK_FREQ_675_BDW;
> -		data = 3;
>  		break;
>  	}
>  
> @@ -740,16 +757,13 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
>  		DRM_ERROR("Switching back to LCPLL failed\n");
>  
>  	mutex_lock(&dev_priv->pcu_lock);
> -	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
> +	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
> +				cdclk_state->voltage);
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
>  
>  	intel_update_cdclk(dev_priv);
> -
> -	WARN(cdclk != dev_priv->cdclk.hw.cdclk,
> -	     "cdclk requested %d kHz but got %d kHz\n",
> -	     cdclk, dev_priv->cdclk.hw.cdclk);

Why?

>  }
>  
>  static int skl_calc_cdclk(int min_cdclk, int vco)
> @@ -1919,11 +1933,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
>  	cdclk = bdw_calc_cdclk(min_cdclk);
>  
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage = bdw_calc_voltage(cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = bdw_calc_cdclk(0);
>  
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage = bdw_calc_voltage(cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
  2017-10-18 20:48 ` [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL Ville Syrjala
@ 2017-10-19 23:47   ` Rodrigo Vivi
  2017-10-20 11:18     ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-19 23:47 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 08:48:22PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Track the system agent voltage we request from pcode in the cdclk state
> on SKL/KBL/CFL. Annoyingly we can't actually read out the current value since
> there's no pcode command to do that, so we'll have to just assume that
> it worked.
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 40 +++++++++++++++++++++++++++++++-------
>  1 file changed, 33 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 7442e9443ffa..6f7b5abe6e3f 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -789,6 +789,24 @@ static int skl_calc_cdclk(int min_cdclk, int vco)
>  	}
>  }
>  
> +static u8 skl_calc_voltage(int cdclk)
> +{
> +	switch (cdclk) {
> +	default:
> +	case 308571:
> +	case 337500:
> +		return 0;
> +	case 450000:
> +	case 432000:
> +		return 1;
> +	case 540000:
> +		return 2;
> +	case 617143:
> +	case 675000:
> +		return 3;
> +	}
> +}
> +
>  static void skl_dpll0_update(struct drm_i915_private *dev_priv,
>  			     struct intel_cdclk_state *cdclk_state)
>  {
> @@ -839,7 +857,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
>  	cdclk_state->cdclk = cdclk_state->ref;
>  
>  	if (cdclk_state->vco == 0)
> -		return;
> +		goto out;

why do we need this case?

>  
>  	cdctl = I915_READ(CDCLK_CTL);
>  
> @@ -880,6 +898,13 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
>  			break;
>  		}
>  	}
> +
> + out:
> +	/*
> +	 * Can't read this out :( Let's assume it's
> +	 * at least what the CDCLK frequency requires.
> +	 */
> +	cdclk_state->voltage = skl_calc_voltage(cdclk_state->cdclk);
>  }
>  
>  /* convert from kHz to .1 fixpoint MHz with -1MHz offset */
> @@ -964,7 +989,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
>  {
>  	int cdclk = cdclk_state->cdclk;
>  	int vco = cdclk_state->vco;
> -	u32 freq_select, pcu_ack;
> +	u32 freq_select;
>  	int ret;
>  
>  	mutex_lock(&dev_priv->pcu_lock);
> @@ -988,21 +1013,17 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
>  	case 308571:
>  	case 337500:
>  		freq_select = CDCLK_FREQ_337_308;
> -		pcu_ack = 0;
>  		break;
>  	case 450000:
>  	case 432000:
>  		freq_select = CDCLK_FREQ_450_432;
> -		pcu_ack = 1;
>  		break;
>  	case 540000:
>  		freq_select = CDCLK_FREQ_540;
> -		pcu_ack = 2;
>  		break;
>  	case 617143:
>  	case 675000:
>  		freq_select = CDCLK_FREQ_675_617;
> -		pcu_ack = 3;
>  		break;
>  	}
>  
> @@ -1018,7 +1039,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
>  
>  	/* inform PCU of the change */
>  	mutex_lock(&dev_priv->pcu_lock);
> -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> +				cdclk_state->voltage);
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	intel_update_cdclk(dev_priv);
> @@ -1097,6 +1119,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
>  	if (cdclk_state.vco == 0)
>  		cdclk_state.vco = 8100000;
>  	cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco);
> +	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
>  
>  	skl_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -1114,6 +1137,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
>  
>  	cdclk_state.cdclk = cdclk_state.ref;
>  	cdclk_state.vco = 0;
> +	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
>  
>  	skl_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -1970,12 +1994,14 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage = skl_calc_voltage(cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = skl_calc_cdclk(0, vco);
>  
>  		intel_state->cdclk.actual.vco = vco;
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage = skl_calc_voltage(cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-19 10:48     ` Ville Syrjälä
  2017-10-19 10:56       ` Mika Kahola
@ 2017-10-19 23:52       ` Rodrigo Vivi
  1 sibling, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-19 23:52 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Oct 19, 2017 at 10:48:04AM +0000, Ville Syrjälä wrote:
> On Wed, Oct 18, 2017 at 02:50:59PM -0700, Rodrigo Vivi wrote:
> > On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Track the system agent voltage we request from pcode in the cdclk state
> > > on CNL. Annoyingly we can't actually read out the current value since
> > > there's no pcode command to do that, so we'll have to just assume that
> > > it worked.
> > 
> > +static u32 cnl_cur_voltage(struct drm_i915_private *dev_priv)
> > +{
> > +       u32 voltage;
> > +       sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &voltage);
> 
> I don't think that'll work. _pcode_read() and _pcode_write() are actually
> the same thing, the only difference is whether we return the resulting value
> or not. Thus if we actually tried to do this we'd end up setting the
> voltage instead of reading it.

:(

> 
> The only way to actually read anything is for pcode to specify a
> specific read command. It's a rather unfortunate design of the
> mailbox interface :(
> 
> We should perhaps put some WARNS into the pcode read/write functions so
> that people don't accidentally use them in the wrong way.
> 
> > +       return voltage;
> > +}
> > +
> >  static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >                          struct intel_cdclk_state *cdclk_state)
> >  {
> > @@ -1486,8 +1493,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> >  
> >         cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> >  
> > +       cdclk_state->voltage = cnl_cur_voltage(dev_priv);
> >  }
> >  
> >  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> > @@ -1594,8 +1600,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  
> >         intel_update_cdclk(dev_priv);
> >  
> > +       dev_priv->cdclk.hw.voltage = cnl_cur_voltage(dev_priv);
> > 
> > 
> > > 
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_cdclk.c | 44 ++++++++++++++++++++++++--------------
> > >  1 file changed, 28 insertions(+), 16 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > > index 1b4dcd9689da..795a18f64c4c 100644
> > > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > > @@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
> > >  		return 168000;
> > >  }
> > >  
> > > +static u8 cnl_calc_voltage(int cdclk)
> > > +{
> > > +	switch (cdclk) {
> > > +	default:
> > > +	case 168000:
> > > +		return 0;
> > > +	case 336000:
> > > +		return 1;
> > > +	case 528000:
> > > +		return 2;
> > > +	}
> > > +}
> > 
> > where is the port_clock taking into account?
> 
> Last patch of the series.
> 
> > 
> > > +
> > >  static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
> > >  				 struct intel_cdclk_state *cdclk_state)
> > >  {
> > > @@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> > >  	cdclk_state->cdclk = cdclk_state->ref;
> > >  
> > >  	if (cdclk_state->vco == 0)
> > > -		return;
> > > +		goto out;
> > >  
> > >  	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
> > >  
> > > @@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
> > >  	}
> > >  
> > >  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> > > +
> > > + out:
> > > +	/*
> > > +	 * Can't read this out :( Let's assume it's
> > > +	 * at least what the CDCLK frequency requires.
> > > +	 */
> > > +	cdclk_state->voltage = cnl_calc_voltage(cdclk_state->cdclk);
> > >  }
> > >  
> > >  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> > > @@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  {
> > >  	int cdclk = cdclk_state->cdclk;
> > >  	int vco = cdclk_state->vco;
> > > -	u32 val, divider, pcu_ack;
> > > +	u32 val, divider;
> > >  	int ret;
> > >  
> > >  	mutex_lock(&dev_priv->pcu_lock);
> > > @@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  		break;
> > >  	}
> > >  
> > > -	switch (cdclk) {
> > > -	case 528000:
> > > -		pcu_ack = 2;
> > > -		break;
> > > -	case 336000:
> > > -		pcu_ack = 1;
> > > -		break;
> > > -	case 168000:
> > > -	default:
> > > -		pcu_ack = 0;
> > > -		break;
> > > -	}
> > > -
> > >  	if (dev_priv->cdclk.hw.vco != 0 &&
> > >  	    dev_priv->cdclk.hw.vco != vco)
> > >  		cnl_cdclk_pll_disable(dev_priv);
> > > @@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  
> > >  	/* inform PCU of the change */
> > >  	mutex_lock(&dev_priv->pcu_lock);
> > > -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> > > +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > > +				cdclk_state->voltage);
> > >  	mutex_unlock(&dev_priv->pcu_lock);
> > >  
> > >  	intel_update_cdclk(dev_priv);
> > > @@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv)
> > >  
> > >  	cdclk_state.cdclk = cnl_calc_cdclk(0);
> > >  	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk);
> > > +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
> > >  
> > >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> > >  }
> > > @@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
> > >  
> > >  	cdclk_state.cdclk = cdclk_state.ref;
> > >  	cdclk_state.vco = 0;
> > > +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
> > >  
> > >  	cnl_set_cdclk(dev_priv, &cdclk_state);
> > >  }
> > > @@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> > >  
> > >  	intel_state->cdclk.logical.vco = vco;
> > >  	intel_state->cdclk.logical.cdclk = cdclk;
> > > +	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> > >  
> > >  	if (!intel_state->active_crtcs) {
> > >  		cdclk = cnl_calc_cdclk(0);
> > > @@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> > >  
> > >  		intel_state->cdclk.actual.vco = vco;
> > >  		intel_state->cdclk.actual.cdclk = cdclk;
> > > +		intel_state->cdclk.actual.voltage = cnl_calc_voltage(cdclk);
> > >  	} else {
> > >  		intel_state->cdclk.actual =
> > >  			intel_state->cdclk.logical;
> > > -- 
> > > 2.13.6
> > > 
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-18 20:48 ` [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports Ville Syrjala
@ 2017-10-19 23:54   ` Rodrigo Vivi
  2017-10-20 11:11     ` Ville Syrjälä
  2017-10-20 14:18     ` Ville Syrjälä
  2017-10-20 16:09   ` [PATCH v2 " Ville Syrjala
  2017-10-20 17:05   ` [PATCH v3 " Ville Syrjala
  2 siblings, 2 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-19 23:54 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx


On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> On CNL we may need to bump up the system agent voltage not only due
> to CDCLK but also when driving DDI port with a sufficiently high clock.
> To that end start tracking the minimum acceptable voltage for each crtc.
> We do the tracking via crtcs because we don't have any kind of encoder
> state. Also there's no downside to doing it this way, and it matches how
> we track cdclk requirements on account of pixel rate.
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>


Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(Although I didn't find cases where I could force a higher voltage level,
everything works well on CNL with this.)


> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  2 ++
>  drivers/gpu/drm/i915/intel_cdclk.c   | 34 +++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_ddi.c     | 13 +++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |  6 ++++++
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  5 +++++
>  drivers/gpu/drm/i915/intel_drv.h     |  6 ++++++
>  6 files changed, 65 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d3ac58dc275f..185711a852b0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2415,6 +2415,8 @@ struct drm_i915_private {
>  	unsigned int active_crtcs;
>  	/* minimum acceptable cdclk for each pipe */
>  	int min_cdclk[I915_MAX_PIPES];
> +	/* minimum acceptable voltage for each pipe */
> +	u8 min_voltage[I915_MAX_PIPES];
>  
>  	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
>  
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 795a18f64c4c..035c44858908 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1666,6 +1666,13 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	intel_update_cdclk(dev_priv);
> +
> +	/*
> +	 * Can't read this out :( Can't rely on .get_cdclk() since it
> +	 * doesn't know about DDI voltage requirements. So let's just
> +	 * assume everything is as expected.
> +	 */
> +	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
>  }
>  
>  static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
> @@ -1935,6 +1942,29 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
>  	return min_cdclk;
>  }
>  
> +static u8 intel_compute_min_voltage(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc *crtc;
> +	struct intel_crtc_state *crtc_state;
> +	u8 min_voltage;
> +	int i;
> +	enum pipe pipe;
> +
> +	memcpy(state->min_voltage, dev_priv->min_voltage,
> +	       sizeof(state->min_voltage));
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
> +		state->min_voltage[i] = crtc_state->min_voltage;
> +
> +	min_voltage = 0;
> +	for_each_pipe(dev_priv, pipe)
> +		min_voltage = max(state->min_voltage[pipe],
> +				  min_voltage);
> +
> +	return min_voltage;
> +}
> +
>  static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> @@ -2091,7 +2121,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> -	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> +	intel_state->cdclk.logical.voltage =
> +		max(cnl_calc_voltage(cdclk),
> +		    intel_compute_min_voltage(intel_state));
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = cnl_calc_cdclk(0);
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index adf51b328844..f02e3c2f4ad2 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2525,6 +2525,15 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
>  	return false;
>  }
>  
> +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> +				   struct intel_crtc_state *crtc_state)
> +{
> +	if (INTEL_GEN(dev_priv) >= 10 && crtc_state->port_clock > 594000)
> +		crtc_state->min_voltage = 2;
> +	else
> +		crtc_state->min_voltage = 0;
> +}
> +
>  void intel_ddi_get_config(struct intel_encoder *encoder,
>  			  struct intel_crtc_state *pipe_config)
>  {
> @@ -2624,6 +2633,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	if (IS_GEN9_LP(dev_priv))
>  		pipe_config->lane_lat_optim_mask =
>  			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
> +
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
>  }
>  
>  static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> @@ -2650,6 +2661,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
>  			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
>  							     pipe_config->lane_count);
>  
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> +
>  	return ret;
>  
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 32e7cca52da2..7d293ecb51c4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
>  
>  	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
>  	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
> +	dev_priv->min_voltage[intel_crtc->pipe] = 0;
>  }
>  
>  /*
> @@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
>  	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
>  	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
>  
> +	PIPE_CONF_CHECK_I(min_voltage);
> +
>  #undef PIPE_CONF_CHECK_X
>  #undef PIPE_CONF_CHECK_I
>  #undef PIPE_CONF_CHECK_P
> @@ -12532,6 +12535,8 @@ static int intel_atomic_commit(struct drm_device *dev,
>  	if (intel_state->modeset) {
>  		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
>  		       sizeof(intel_state->min_cdclk));
> +		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
> +		       sizeof(intel_state->min_voltage));
>  		dev_priv->active_crtcs = intel_state->active_crtcs;
>  		dev_priv->cdclk.logical = intel_state->cdclk.logical;
>  		dev_priv->cdclk.actual = intel_state->cdclk.actual;
> @@ -15042,6 +15047,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		}
>  
>  		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
> +		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
>  
>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 772521440a9f..6c1da88b5fef 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  					struct intel_crtc_state *pipe_config,
>  					struct drm_connector_state *conn_state)
>  {
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
>  	struct intel_digital_port *intel_dig_port = intel_mst->primary;
>  	struct intel_dp *intel_dp = &intel_dig_port->dp;
> @@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  
>  	pipe_config->dp_m_n.tu = slots;
>  
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> +
>  	return true;
>  }
>  
> @@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
>  	intel_dp_get_m_n(crtc, pipe_config);
>  
>  	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
> +
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
>  }
>  
>  static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 765a737700c5..002894b13d69 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -386,6 +386,8 @@ struct intel_atomic_state {
>  	unsigned int active_crtcs;
>  	/* minimum acceptable cdclk for each pipe */
>  	int min_cdclk[I915_MAX_PIPES];
> +	/* minimum acceptable voltage for each pipe */
> +	u8 min_voltage[I915_MAX_PIPES];
>  
>  	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
>  
> @@ -739,6 +741,8 @@ struct intel_crtc_state {
>  	 */
>  	uint8_t lane_lat_optim_mask;
>  
> +	u8 min_voltage;
> +
>  	/* Panel fitter controls for gen2-gen4 + VLV */
>  	struct {
>  		u32 control;
> @@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
>  			 struct intel_crtc_state *pipe_config);
>  void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
>  				    bool state);
> +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> +				   struct intel_crtc_state *crtc_state);
>  u32 bxt_signal_levels(struct intel_dp *intel_dp);
>  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
>  u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915: CNL DVFS thing (rev2)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (12 preceding siblings ...)
  2017-10-19 23:27 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2017-10-20  0:22 ` Patchwork
  2017-10-20 16:28 ` ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev3) Patchwork
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-20  0:22 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev2)
URL   : https://patchwork.freedesktop.org/series/32247/
State : success

== Summary ==

Test kms_busy:
        Subgroup extended-modeset-hang-oldfb-with-reset-render-C:
                pass       -> DMESG-WARN (shard-hsw) fdo#102249 +1
Test kms_force_connector_basic:
        Subgroup force-load-detect:
                skip       -> PASS       (shard-hsw)
Test drv_module_reload:
        Subgroup basic-reload-inject:
                pass       -> DMESG-WARN (shard-hsw) fdo#102707

fdo#102249 https://bugs.freedesktop.org/show_bug.cgi?id=102249
fdo#102707 https://bugs.freedesktop.org/show_bug.cgi?id=102707

shard-hsw        total:2540 pass:1430 dwarn:2   dfail:0   fail:8   skip:1100 time:9186s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6116/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-19 23:54   ` Rodrigo Vivi
@ 2017-10-20 11:11     ` Ville Syrjälä
  2017-10-20 17:48       ` Runyan, Arthur J
  2017-10-20 14:18     ` Ville Syrjälä
  1 sibling, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 11:11 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx, Runyan, Arthur J

On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> 
> On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > On CNL we may need to bump up the system agent voltage not only due
> > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > To that end start tracking the minimum acceptable voltage for each crtc.
> > We do the tracking via crtcs because we don't have any kind of encoder
> > state. Also there's no downside to doing it this way, and it matches how
> > we track cdclk requirements on account of pixel rate.
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> (Although I didn't find cases where I could force a higher voltage level,
> everything works well on CNL with this.)

I went and actually read the spec now :) so I can now see that this
doesn't really match the sequence listed in the spec.

For example, let's assume we have a modeset where we have to disable
a DPLL, change CDCLK, and finally enable a DPLL again.

What the spec says we should do is something like this:
1.  DVFS pre sequence
2.  disable DPLL
3.  DVFS post sequence
4.  disable DPLL power
...
5.  DVFS pre sequence
6.  configure CDCLK_CTL
7.  DVFS post sequence
...
8.  enable DPLL power
9.  DVFS pre sequence
10. enable DPLL
11. DVFS post sequence

With my code what we'd end up doing is this instead:
1. disable DPLL
2. disable DPLL power
...
3. DVFS pre sequence
4. configure CDCLK_CTL
5. DVFS post sequence
...
6. enable DPLL power
7. enable DPLL

So my way always results in running the DVFS sequences at most once.
With the way the spec has things listed we might have to run the
sequences multiple times. 

Art, is there a good reason why we'd actually have to run the
DVFS sequences around each DPLL_ENABLE write, instead of just
doing it once at any point between disabling and enabling
DPLLs?

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
  2017-10-19 23:47   ` Rodrigo Vivi
@ 2017-10-20 11:18     ` Ville Syrjälä
  2017-10-20 20:45       ` Rodrigo Vivi
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 11:18 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Thu, Oct 19, 2017 at 04:47:08PM -0700, Rodrigo Vivi wrote:
> On Wed, Oct 18, 2017 at 08:48:22PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Track the system agent voltage we request from pcode in the cdclk state
> > on SKL/KBL/CFL. Annoyingly we can't actually read out the current value since
> > there's no pcode command to do that, so we'll have to just assume that
> > it worked.
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_cdclk.c | 40 +++++++++++++++++++++++++++++++-------
> >  1 file changed, 33 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index 7442e9443ffa..6f7b5abe6e3f 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -789,6 +789,24 @@ static int skl_calc_cdclk(int min_cdclk, int vco)
> >  	}
> >  }
> >  
> > +static u8 skl_calc_voltage(int cdclk)
> > +{
> > +	switch (cdclk) {
> > +	default:
> > +	case 308571:
> > +	case 337500:
> > +		return 0;
> > +	case 450000:
> > +	case 432000:
> > +		return 1;
> > +	case 540000:
> > +		return 2;
> > +	case 617143:
> > +	case 675000:
> > +		return 3;
> > +	}
> > +}
> > +
> >  static void skl_dpll0_update(struct drm_i915_private *dev_priv,
> >  			     struct intel_cdclk_state *cdclk_state)
> >  {
> > @@ -839,7 +857,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
> >  	cdclk_state->cdclk = cdclk_state->ref;
> >  
> >  	if (cdclk_state->vco == 0)
> > -		return;
> > +		goto out;
> 
> why do we need this case?

Mainly just to make sure the entire state is consistent.

> 
> >  
> >  	cdctl = I915_READ(CDCLK_CTL);
> >  
> > @@ -880,6 +898,13 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
> >  			break;
> >  		}
> >  	}
> > +
> > + out:
> > +	/*
> > +	 * Can't read this out :( Let's assume it's
> > +	 * at least what the CDCLK frequency requires.
> > +	 */
> > +	cdclk_state->voltage = skl_calc_voltage(cdclk_state->cdclk);
> >  }
> >  
> >  /* convert from kHz to .1 fixpoint MHz with -1MHz offset */
> > @@ -964,7 +989,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
> >  {
> >  	int cdclk = cdclk_state->cdclk;
> >  	int vco = cdclk_state->vco;
> > -	u32 freq_select, pcu_ack;
> > +	u32 freq_select;
> >  	int ret;
> >  
> >  	mutex_lock(&dev_priv->pcu_lock);
> > @@ -988,21 +1013,17 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
> >  	case 308571:
> >  	case 337500:
> >  		freq_select = CDCLK_FREQ_337_308;
> > -		pcu_ack = 0;
> >  		break;
> >  	case 450000:
> >  	case 432000:
> >  		freq_select = CDCLK_FREQ_450_432;
> > -		pcu_ack = 1;
> >  		break;
> >  	case 540000:
> >  		freq_select = CDCLK_FREQ_540;
> > -		pcu_ack = 2;
> >  		break;
> >  	case 617143:
> >  	case 675000:
> >  		freq_select = CDCLK_FREQ_675_617;
> > -		pcu_ack = 3;
> >  		break;
> >  	}
> >  
> > @@ -1018,7 +1039,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
> >  
> >  	/* inform PCU of the change */
> >  	mutex_lock(&dev_priv->pcu_lock);
> > -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> > +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > +				cdclk_state->voltage);
> >  	mutex_unlock(&dev_priv->pcu_lock);
> >  
> >  	intel_update_cdclk(dev_priv);
> > @@ -1097,6 +1119,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
> >  	if (cdclk_state.vco == 0)
> >  		cdclk_state.vco = 8100000;
> >  	cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco);
> > +	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
> >  
> >  	skl_set_cdclk(dev_priv, &cdclk_state);
> >  }
> > @@ -1114,6 +1137,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
> >  
> >  	cdclk_state.cdclk = cdclk_state.ref;
> >  	cdclk_state.vco = 0;
> > +	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
> >  
> >  	skl_set_cdclk(dev_priv, &cdclk_state);
> >  }
> > @@ -1970,12 +1994,14 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  
> >  	intel_state->cdclk.logical.vco = vco;
> >  	intel_state->cdclk.logical.cdclk = cdclk;
> > +	intel_state->cdclk.logical.voltage = skl_calc_voltage(cdclk);
> >  
> >  	if (!intel_state->active_crtcs) {
> >  		cdclk = skl_calc_cdclk(0, vco);
> >  
> >  		intel_state->cdclk.actual.vco = vco;
> >  		intel_state->cdclk.actual.cdclk = cdclk;
> > +		intel_state->cdclk.actual.voltage = skl_calc_voltage(cdclk);
> >  	} else {
> >  		intel_state->cdclk.actual =
> >  			intel_state->cdclk.logical;
> > -- 
> > 2.13.6
> > 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state
  2017-10-18 20:48 ` [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state Ville Syrjala
  2017-10-19 23:32   ` Rodrigo Vivi
@ 2017-10-20 14:01   ` Ville Syrjälä
  2017-10-20 20:43     ` Rodrigo Vivi
  1 sibling, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 14:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

On Wed, Oct 18, 2017 at 11:48:19PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> For CNL we'll need to start considering the port clocks when we select
> the voltage level for the system agent. To that end start tracking the
> voltage in the cdclk state (since that already has to adjust it).
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h         |  1 +
>  drivers/gpu/drm/i915/intel_cdclk.c      | 31 ++++++++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_display.c    |  8 ++++----
>  drivers/gpu/drm/i915/intel_drv.h        |  4 +++-
>  drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++-
>  5 files changed, 34 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index f01c80076c59..d3ac58dc275f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2227,6 +2227,7 @@ struct i915_oa_ops {
>  
>  struct intel_cdclk_state {
>  	unsigned int cdclk, vco, ref;
> +	u8 voltage;

BTW now that I decided to abuse this for all platforms the name
"voltage" might not be entirely accurate anymore. Especially on VLV/CHV
the DSPFREQUAR value isn't directly a voltage value, but instead a
request to punit to change the cdclk frequency to a specific value.
Although naturally punit will also make sure the voltage will be
set sufficiently high as well.

So I'm not entirely sure we want to call it "voltage" anymore. Something
abstract like "level" is also what came to mind when I was thingking
about this. If anyone is irked by "voltage" and would like to see
something different there, let me know. Otherwise I think I might just
leave it as is for now.

>  };
>  
>  struct drm_i915_private {
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 4bffd31a8924..522222f8bb50 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1690,17 +1690,34 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
>  }
>  
>  /**
> - * intel_cdclk_state_compare - Determine if two CDCLK states differ
> + * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes
>   * @a: first CDCLK state
>   * @b: second CDCLK state
>   *
>   * Returns:
> - * True if the CDCLK states are identical, false if they differ.
> + * True if the CDCLK states require pipes to be off during reprogramming, false if not.
>   */
> -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
>  			       const struct intel_cdclk_state *b)
>  {
> -	return memcmp(a, b, sizeof(*a)) == 0;
> +	return a->cdclk != b->cdclk ||
> +		a->vco != b->vco ||
> +		a->ref != b->ref;
> +}
> +
> +/**
> + * intel_cdclk_changed - Determine if two CDCLK states are different
> + * @a: first CDCLK state
> + * @b: second CDCLK state
> + *
> + * Returns:
> + * True if the CDCLK states don't match, false if they do.
> + */
> +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> +			 const struct intel_cdclk_state *b)
> +{
> +	return intel_cdclk_needs_modeset(a, b) ||
> +		a->voltage != b->voltage;
>  }
>  
>  /**
> @@ -1714,15 +1731,15 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
>  void intel_set_cdclk(struct drm_i915_private *dev_priv,
>  		     const struct intel_cdclk_state *cdclk_state)
>  {
> -	if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state))
> +	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state))
>  		return;
>  
>  	if (WARN_ON_ONCE(!dev_priv->display.set_cdclk))
>  		return;
>  
> -	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n",
> +	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz, voltage %d\n",
>  			 cdclk_state->cdclk, cdclk_state->vco,
> -			 cdclk_state->ref);
> +			 cdclk_state->ref, cdclk_state->voltage);
>  
>  	dev_priv->display.set_cdclk(dev_priv, cdclk_state);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index bd62c0a65bcd..32e7cca52da2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11946,16 +11946,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  		 * holding all the crtc locks, even if we don't end up
>  		 * touching the hardware
>  		 */
> -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
> -					       &intel_state->cdclk.logical)) {
> +		if (intel_cdclk_changed(&dev_priv->cdclk.logical,
> +					&intel_state->cdclk.logical)) {
>  			ret = intel_lock_all_pipes(state);
>  			if (ret < 0)
>  				return ret;
>  		}
>  
>  		/* All pipes must be switched off while we change the cdclk. */
> -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
> -					       &intel_state->cdclk.actual)) {
> +		if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual,
> +					      &intel_state->cdclk.actual)) {
>  			ret = intel_modeset_all_pipes(state);
>  			if (ret < 0)
>  				return ret;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a05ab3a1ab27..765a737700c5 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1324,8 +1324,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
>  void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
>  void intel_update_cdclk(struct drm_i915_private *dev_priv);
>  void intel_update_rawclk(struct drm_i915_private *dev_priv);
> -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
>  			       const struct intel_cdclk_state *b);
> +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> +			 const struct intel_cdclk_state *b);
>  void intel_set_cdclk(struct drm_i915_private *dev_priv,
>  		     const struct intel_cdclk_state *cdclk_state);
>  
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index 8af286c63d3b..5ac553fab7c7 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
>  	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
>  
>  	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
> -	WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
> +	/* Can't read out the voltage so can't use intel_cdclk_changed() */
> +	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
>  
>  	gen9_assert_dbuf_enabled(dev_priv);
>  
> -- 
> 2.13.6

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-19 23:54   ` Rodrigo Vivi
  2017-10-20 11:11     ` Ville Syrjälä
@ 2017-10-20 14:18     ` Ville Syrjälä
  2017-10-20 16:11       ` Ville Syrjälä
  1 sibling, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 14:18 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> 
> On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > On CNL we may need to bump up the system agent voltage not only due
> > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > To that end start tracking the minimum acceptable voltage for each crtc.
> > We do the tracking via crtcs because we don't have any kind of encoder
> > state. Also there's no downside to doing it this way, and it matches how
> > we track cdclk requirements on account of pixel rate.
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> (Although I didn't find cases where I could force a higher voltage level,
> everything works well on CNL with this.)

For a quick test hack you could just reduce the port clock limit in
intel_ddi_compute_min_voltage() to something you can reach.

So probably something like:
1. enable one pipe with low port clock that can operate at min voltage
2. enable a second pipe with higher port clock that need max voltage
3. stare at the logs to make sure we ramp up the voltage correctly,
   and that the first pipe didn't undergo a modeset needlessly

Oh, and I guess you'd have to make sure that both pipes can operate at
the same low cdclk value so that cdclk changes won't interfere with
your observations.

Actually this kind of hack could be tested on any platform, assuming
they will tolerate voltage changes with pipes on. I guess I can give
it a quick whirl on my SKL here and see if the smoke escapes ;)

> 
> 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h      |  2 ++
> >  drivers/gpu/drm/i915/intel_cdclk.c   | 34 +++++++++++++++++++++++++++++++++-
> >  drivers/gpu/drm/i915/intel_ddi.c     | 13 +++++++++++++
> >  drivers/gpu/drm/i915/intel_display.c |  6 ++++++
> >  drivers/gpu/drm/i915/intel_dp_mst.c  |  5 +++++
> >  drivers/gpu/drm/i915/intel_drv.h     |  6 ++++++
> >  6 files changed, 65 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index d3ac58dc275f..185711a852b0 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2415,6 +2415,8 @@ struct drm_i915_private {
> >  	unsigned int active_crtcs;
> >  	/* minimum acceptable cdclk for each pipe */
> >  	int min_cdclk[I915_MAX_PIPES];
> > +	/* minimum acceptable voltage for each pipe */
> > +	u8 min_voltage[I915_MAX_PIPES];
> >  
> >  	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index 795a18f64c4c..035c44858908 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -1666,6 +1666,13 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> >  	mutex_unlock(&dev_priv->pcu_lock);
> >  
> >  	intel_update_cdclk(dev_priv);
> > +
> > +	/*
> > +	 * Can't read this out :( Can't rely on .get_cdclk() since it
> > +	 * doesn't know about DDI voltage requirements. So let's just
> > +	 * assume everything is as expected.
> > +	 */
> > +	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
> >  }
> >  
> >  static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
> > @@ -1935,6 +1942,29 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
> >  	return min_cdclk;
> >  }
> >  
> > +static u8 intel_compute_min_voltage(struct intel_atomic_state *state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > +	struct intel_crtc *crtc;
> > +	struct intel_crtc_state *crtc_state;
> > +	u8 min_voltage;
> > +	int i;
> > +	enum pipe pipe;
> > +
> > +	memcpy(state->min_voltage, dev_priv->min_voltage,
> > +	       sizeof(state->min_voltage));
> > +
> > +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
> > +		state->min_voltage[i] = crtc_state->min_voltage;
> > +
> > +	min_voltage = 0;
> > +	for_each_pipe(dev_priv, pipe)
> > +		min_voltage = max(state->min_voltage[pipe],
> > +				  min_voltage);
> > +
> > +	return min_voltage;
> > +}
> > +
> >  static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> > @@ -2091,7 +2121,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  
> >  	intel_state->cdclk.logical.vco = vco;
> >  	intel_state->cdclk.logical.cdclk = cdclk;
> > -	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> > +	intel_state->cdclk.logical.voltage =
> > +		max(cnl_calc_voltage(cdclk),
> > +		    intel_compute_min_voltage(intel_state));
> >  
> >  	if (!intel_state->active_crtcs) {
> >  		cdclk = cnl_calc_cdclk(0);
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index adf51b328844..f02e3c2f4ad2 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -2525,6 +2525,15 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
> >  	return false;
> >  }
> >  
> > +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> > +				   struct intel_crtc_state *crtc_state)
> > +{
> > +	if (INTEL_GEN(dev_priv) >= 10 && crtc_state->port_clock > 594000)
> > +		crtc_state->min_voltage = 2;
> > +	else
> > +		crtc_state->min_voltage = 0;
> > +}
> > +
> >  void intel_ddi_get_config(struct intel_encoder *encoder,
> >  			  struct intel_crtc_state *pipe_config)
> >  {
> > @@ -2624,6 +2633,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >  	if (IS_GEN9_LP(dev_priv))
> >  		pipe_config->lane_lat_optim_mask =
> >  			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
> > +
> > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> >  }
> >  
> >  static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> > @@ -2650,6 +2661,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> >  			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
> >  							     pipe_config->lane_count);
> >  
> > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> > +
> >  	return ret;
> >  
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 32e7cca52da2..7d293ecb51c4 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
> >  
> >  	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
> >  	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
> > +	dev_priv->min_voltage[intel_crtc->pipe] = 0;
> >  }
> >  
> >  /*
> > @@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
> >  	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
> >  	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
> >  
> > +	PIPE_CONF_CHECK_I(min_voltage);
> > +
> >  #undef PIPE_CONF_CHECK_X
> >  #undef PIPE_CONF_CHECK_I
> >  #undef PIPE_CONF_CHECK_P
> > @@ -12532,6 +12535,8 @@ static int intel_atomic_commit(struct drm_device *dev,
> >  	if (intel_state->modeset) {
> >  		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
> >  		       sizeof(intel_state->min_cdclk));
> > +		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
> > +		       sizeof(intel_state->min_voltage));
> >  		dev_priv->active_crtcs = intel_state->active_crtcs;
> >  		dev_priv->cdclk.logical = intel_state->cdclk.logical;
> >  		dev_priv->cdclk.actual = intel_state->cdclk.actual;
> > @@ -15042,6 +15047,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  		}
> >  
> >  		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
> > +		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
> >  
> >  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
> >  	}
> > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> > index 772521440a9f..6c1da88b5fef 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> > @@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
> >  					struct intel_crtc_state *pipe_config,
> >  					struct drm_connector_state *conn_state)
> >  {
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
> >  	struct intel_digital_port *intel_dig_port = intel_mst->primary;
> >  	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > @@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
> >  
> >  	pipe_config->dp_m_n.tu = slots;
> >  
> > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> > +
> >  	return true;
> >  }
> >  
> > @@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
> >  	intel_dp_get_m_n(crtc, pipe_config);
> >  
> >  	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
> > +
> > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> >  }
> >  
> >  static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 765a737700c5..002894b13d69 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -386,6 +386,8 @@ struct intel_atomic_state {
> >  	unsigned int active_crtcs;
> >  	/* minimum acceptable cdclk for each pipe */
> >  	int min_cdclk[I915_MAX_PIPES];
> > +	/* minimum acceptable voltage for each pipe */
> > +	u8 min_voltage[I915_MAX_PIPES];
> >  
> >  	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
> >  
> > @@ -739,6 +741,8 @@ struct intel_crtc_state {
> >  	 */
> >  	uint8_t lane_lat_optim_mask;
> >  
> > +	u8 min_voltage;
> > +
> >  	/* Panel fitter controls for gen2-gen4 + VLV */
> >  	struct {
> >  		u32 control;
> > @@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
> >  			 struct intel_crtc_state *pipe_config);
> >  void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
> >  				    bool state);
> > +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> > +				   struct intel_crtc_state *crtc_state);
> >  u32 bxt_signal_levels(struct intel_dp *intel_dp);
> >  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
> >  u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
> > -- 
> > 2.13.6
> > 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v2 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-18 20:48 ` [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports Ville Syrjala
  2017-10-19 23:54   ` Rodrigo Vivi
@ 2017-10-20 16:09   ` Ville Syrjala
  2017-10-20 16:52     ` Ville Syrjälä
  2017-10-20 17:05   ` [PATCH v3 " Ville Syrjala
  2 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-20 16:09 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

On CNL we may need to bump up the system agent voltage not only due
to CDCLK but also when driving DDI port with a sufficiently high clock.
To that end start tracking the minimum acceptable voltage for each crtc.
We do the tracking via crtcs because we don't have any kind of encoder
state. Also there's no downside to doing it this way, and it matches how
we track cdclk requirements on account of pixel rate.

v2: Allow disabled crtcs to use the min voltage
    Add IS_CNL check to intel_ddi_compute_min_voltage() since
    we're using CNL specific values there
    s/intel_compute_min_voltage/cnl_compute_min_voltage/ since
    the function makes hw specific assumptions about the voltage
    values

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  2 ++
 drivers/gpu/drm/i915/intel_cdclk.c   | 50 ++++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_ddi.c     | 11 ++++++++
 drivers/gpu/drm/i915/intel_display.c |  9 +++++++
 drivers/gpu/drm/i915/intel_dp_mst.c  |  5 ++++
 drivers/gpu/drm/i915/intel_drv.h     |  6 +++++
 6 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d3ac58dc275f..185711a852b0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2415,6 +2415,8 @@ struct drm_i915_private {
 	unsigned int active_crtcs;
 	/* minimum acceptable cdclk for each pipe */
 	int min_cdclk[I915_MAX_PIPES];
+	/* minimum acceptable voltage for each pipe */
+	u8 min_voltage[I915_MAX_PIPES];
 
 	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
 
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 5bbf9f6023a2..78029f70e6ea 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1669,6 +1669,12 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
+
+	/*
+	 * Can't read out the voltage :( So let's
+	 * just assume everything is as expected.
+	 */
+	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
 }
 
 static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
@@ -1938,6 +1944,42 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
 	return min_cdclk;
 }
 
+/*
+ * Note that this functions assumes that 0 is
+ * the lowest voltage value, and higher values
+ * correspond to increasingly higher voltages.
+ *
+ * Should that relationship no longer hold on
+ * future platforms this code will need to be
+ * adjusted.
+ */
+static u8 cnl_compute_min_voltage(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
+	u8 min_voltage;
+	int i;
+	enum pipe pipe;
+
+	memcpy(state->min_voltage, dev_priv->min_voltage,
+	       sizeof(state->min_voltage));
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+		if (crtc_state->base.enable)
+			state->min_voltage[i] = crtc_state->min_voltage;
+		else
+			state->min_voltage[i] = 0;
+	}
+
+	min_voltage = 0;
+	for_each_pipe(dev_priv, pipe)
+		min_voltage = max(state->min_voltage[pipe],
+				  min_voltage);
+
+	return min_voltage;
+}
+
 static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
@@ -2021,7 +2063,9 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
-	intel_state->cdclk.logical.voltage = skl_calc_voltage(cdclk);
+	intel_state->cdclk.logical.voltage =
+		max(skl_calc_voltage(cdclk),
+		    cnl_compute_min_voltage(intel_state));
 
 	if (!intel_state->active_crtcs) {
 		cdclk = skl_calc_cdclk(0, vco);
@@ -2094,7 +2138,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
-	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
+	intel_state->cdclk.logical.voltage =
+		max(cnl_calc_voltage(cdclk),
+		    cnl_compute_min_voltage(intel_state));
 
 	if (!intel_state->active_crtcs) {
 		cdclk = cnl_calc_cdclk(0);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index adf51b328844..f707134b4f65 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2525,6 +2525,13 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
 	return false;
 }
 
+void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
+				   struct intel_crtc_state *crtc_state)
+{
+	if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000)
+		crtc_state->min_voltage = 2;
+}
+
 void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config)
 {
@@ -2624,6 +2631,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	if (IS_GEN9_LP(dev_priv))
 		pipe_config->lane_lat_optim_mask =
 			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
+
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
 }
 
 static bool intel_ddi_compute_config(struct intel_encoder *encoder,
@@ -2650,6 +2659,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
 			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
 							     pipe_config->lane_count);
 
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
+
 	return ret;
 
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 32e7cca52da2..83024956a74d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
 
 	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
 	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
+	dev_priv->min_voltage[intel_crtc->pipe] = 0;
 }
 
 /*
@@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
 	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
 
+	PIPE_CONF_CHECK_I(min_voltage);
+
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
 #undef PIPE_CONF_CHECK_P
@@ -11964,6 +11967,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 		DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n",
 			      intel_state->cdclk.logical.cdclk,
 			      intel_state->cdclk.actual.cdclk);
+		DRM_DEBUG_KMS("New voltage calculated to be logical %u, actual %u\n",
+			      intel_state->cdclk.logical.voltage,
+			      intel_state->cdclk.actual.voltage);
 	} else {
 		to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical;
 	}
@@ -12532,6 +12538,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	if (intel_state->modeset) {
 		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
 		       sizeof(intel_state->min_cdclk));
+		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
+		       sizeof(intel_state->min_voltage));
 		dev_priv->active_crtcs = intel_state->active_crtcs;
 		dev_priv->cdclk.logical = intel_state->cdclk.logical;
 		dev_priv->cdclk.actual = intel_state->cdclk.actual;
@@ -15042,6 +15050,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		}
 
 		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
+		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
 
 		intel_pipe_config_sanity_check(dev_priv, crtc_state);
 	}
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 772521440a9f..6c1da88b5fef 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 					struct intel_crtc_state *pipe_config,
 					struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_digital_port *intel_dig_port = intel_mst->primary;
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
@@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	pipe_config->dp_m_n.tu = slots;
 
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
+
 	return true;
 }
 
@@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
 	intel_dp_get_m_n(crtc, pipe_config);
 
 	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
+
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
 }
 
 static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 765a737700c5..002894b13d69 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -386,6 +386,8 @@ struct intel_atomic_state {
 	unsigned int active_crtcs;
 	/* minimum acceptable cdclk for each pipe */
 	int min_cdclk[I915_MAX_PIPES];
+	/* minimum acceptable voltage for each pipe */
+	u8 min_voltage[I915_MAX_PIPES];
 
 	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
 
@@ -739,6 +741,8 @@ struct intel_crtc_state {
 	 */
 	uint8_t lane_lat_optim_mask;
 
+	u8 min_voltage;
+
 	/* Panel fitter controls for gen2-gen4 + VLV */
 	struct {
 		u32 control;
@@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 				    bool state);
+void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
+				   struct intel_crtc_state *crtc_state);
 u32 bxt_signal_levels(struct intel_dp *intel_dp);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 14:18     ` Ville Syrjälä
@ 2017-10-20 16:11       ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 16:11 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Fri, Oct 20, 2017 at 05:18:04PM +0300, Ville Syrjälä wrote:
> On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> > 
> > On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > On CNL we may need to bump up the system agent voltage not only due
> > > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > > To that end start tracking the minimum acceptable voltage for each crtc.
> > > We do the tracking via crtcs because we don't have any kind of encoder
> > > state. Also there's no downside to doing it this way, and it matches how
> > > we track cdclk requirements on account of pixel rate.
> > > 
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > 
> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > 
> > Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > (Although I didn't find cases where I could force a higher voltage level,
> > everything works well on CNL with this.)
> 
> For a quick test hack you could just reduce the port clock limit in
> intel_ddi_compute_min_voltage() to something you can reach.
> 
> So probably something like:
> 1. enable one pipe with low port clock that can operate at min voltage
> 2. enable a second pipe with higher port clock that need max voltage
> 3. stare at the logs to make sure we ramp up the voltage correctly,
>    and that the first pipe didn't undergo a modeset needlessly
> 
> Oh, and I guess you'd have to make sure that both pipes can operate at
> the same low cdclk value so that cdclk changes won't interfere with
> your observations.
> 
> Actually this kind of hack could be tested on any platform, assuming
> they will tolerate voltage changes with pipes on. I guess I can give
> it a quick whirl on my SKL here and see if the smoke escapes ;)

OK, quick test here found some bugs. I sent a v2 which seems to do the
right thing on my SKL with the aforementioned hacks in place.

> 
> > 
> > 
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h      |  2 ++
> > >  drivers/gpu/drm/i915/intel_cdclk.c   | 34 +++++++++++++++++++++++++++++++++-
> > >  drivers/gpu/drm/i915/intel_ddi.c     | 13 +++++++++++++
> > >  drivers/gpu/drm/i915/intel_display.c |  6 ++++++
> > >  drivers/gpu/drm/i915/intel_dp_mst.c  |  5 +++++
> > >  drivers/gpu/drm/i915/intel_drv.h     |  6 ++++++
> > >  6 files changed, 65 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index d3ac58dc275f..185711a852b0 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -2415,6 +2415,8 @@ struct drm_i915_private {
> > >  	unsigned int active_crtcs;
> > >  	/* minimum acceptable cdclk for each pipe */
> > >  	int min_cdclk[I915_MAX_PIPES];
> > > +	/* minimum acceptable voltage for each pipe */
> > > +	u8 min_voltage[I915_MAX_PIPES];
> > >  
> > >  	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > > index 795a18f64c4c..035c44858908 100644
> > > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > > @@ -1666,6 +1666,13 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  	mutex_unlock(&dev_priv->pcu_lock);
> > >  
> > >  	intel_update_cdclk(dev_priv);
> > > +
> > > +	/*
> > > +	 * Can't read this out :( Can't rely on .get_cdclk() since it
> > > +	 * doesn't know about DDI voltage requirements. So let's just
> > > +	 * assume everything is as expected.
> > > +	 */
> > > +	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
> > >  }
> > >  
> > >  static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
> > > @@ -1935,6 +1942,29 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
> > >  	return min_cdclk;
> > >  }
> > >  
> > > +static u8 intel_compute_min_voltage(struct intel_atomic_state *state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > > +	struct intel_crtc *crtc;
> > > +	struct intel_crtc_state *crtc_state;
> > > +	u8 min_voltage;
> > > +	int i;
> > > +	enum pipe pipe;
> > > +
> > > +	memcpy(state->min_voltage, dev_priv->min_voltage,
> > > +	       sizeof(state->min_voltage));
> > > +
> > > +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
> > > +		state->min_voltage[i] = crtc_state->min_voltage;
> > > +
> > > +	min_voltage = 0;
> > > +	for_each_pipe(dev_priv, pipe)
> > > +		min_voltage = max(state->min_voltage[pipe],
> > > +				  min_voltage);
> > > +
> > > +	return min_voltage;
> > > +}
> > > +
> > >  static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
> > >  {
> > >  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> > > @@ -2091,7 +2121,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
> > >  
> > >  	intel_state->cdclk.logical.vco = vco;
> > >  	intel_state->cdclk.logical.cdclk = cdclk;
> > > -	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> > > +	intel_state->cdclk.logical.voltage =
> > > +		max(cnl_calc_voltage(cdclk),
> > > +		    intel_compute_min_voltage(intel_state));
> > >  
> > >  	if (!intel_state->active_crtcs) {
> > >  		cdclk = cnl_calc_cdclk(0);
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > > index adf51b328844..f02e3c2f4ad2 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -2525,6 +2525,15 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
> > >  	return false;
> > >  }
> > >  
> > > +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> > > +				   struct intel_crtc_state *crtc_state)
> > > +{
> > > +	if (INTEL_GEN(dev_priv) >= 10 && crtc_state->port_clock > 594000)
> > > +		crtc_state->min_voltage = 2;
> > > +	else
> > > +		crtc_state->min_voltage = 0;
> > > +}
> > > +
> > >  void intel_ddi_get_config(struct intel_encoder *encoder,
> > >  			  struct intel_crtc_state *pipe_config)
> > >  {
> > > @@ -2624,6 +2633,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> > >  	if (IS_GEN9_LP(dev_priv))
> > >  		pipe_config->lane_lat_optim_mask =
> > >  			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
> > > +
> > > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> > >  }
> > >  
> > >  static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> > > @@ -2650,6 +2661,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> > >  			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
> > >  							     pipe_config->lane_count);
> > >  
> > > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> > > +
> > >  	return ret;
> > >  
> > >  }
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > index 32e7cca52da2..7d293ecb51c4 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
> > >  
> > >  	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
> > >  	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
> > > +	dev_priv->min_voltage[intel_crtc->pipe] = 0;
> > >  }
> > >  
> > >  /*
> > > @@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
> > >  	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
> > >  	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
> > >  
> > > +	PIPE_CONF_CHECK_I(min_voltage);
> > > +
> > >  #undef PIPE_CONF_CHECK_X
> > >  #undef PIPE_CONF_CHECK_I
> > >  #undef PIPE_CONF_CHECK_P
> > > @@ -12532,6 +12535,8 @@ static int intel_atomic_commit(struct drm_device *dev,
> > >  	if (intel_state->modeset) {
> > >  		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
> > >  		       sizeof(intel_state->min_cdclk));
> > > +		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
> > > +		       sizeof(intel_state->min_voltage));
> > >  		dev_priv->active_crtcs = intel_state->active_crtcs;
> > >  		dev_priv->cdclk.logical = intel_state->cdclk.logical;
> > >  		dev_priv->cdclk.actual = intel_state->cdclk.actual;
> > > @@ -15042,6 +15047,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > >  		}
> > >  
> > >  		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
> > > +		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
> > >  
> > >  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
> > >  	}
> > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> > > index 772521440a9f..6c1da88b5fef 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> > > @@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
> > >  					struct intel_crtc_state *pipe_config,
> > >  					struct drm_connector_state *conn_state)
> > >  {
> > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > >  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
> > >  	struct intel_digital_port *intel_dig_port = intel_mst->primary;
> > >  	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > @@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
> > >  
> > >  	pipe_config->dp_m_n.tu = slots;
> > >  
> > > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> > > +
> > >  	return true;
> > >  }
> > >  
> > > @@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
> > >  	intel_dp_get_m_n(crtc, pipe_config);
> > >  
> > >  	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
> > > +
> > > +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> > >  }
> > >  
> > >  static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index 765a737700c5..002894b13d69 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -386,6 +386,8 @@ struct intel_atomic_state {
> > >  	unsigned int active_crtcs;
> > >  	/* minimum acceptable cdclk for each pipe */
> > >  	int min_cdclk[I915_MAX_PIPES];
> > > +	/* minimum acceptable voltage for each pipe */
> > > +	u8 min_voltage[I915_MAX_PIPES];
> > >  
> > >  	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
> > >  
> > > @@ -739,6 +741,8 @@ struct intel_crtc_state {
> > >  	 */
> > >  	uint8_t lane_lat_optim_mask;
> > >  
> > > +	u8 min_voltage;
> > > +
> > >  	/* Panel fitter controls for gen2-gen4 + VLV */
> > >  	struct {
> > >  		u32 control;
> > > @@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
> > >  			 struct intel_crtc_state *pipe_config);
> > >  void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
> > >  				    bool state);
> > > +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> > > +				   struct intel_crtc_state *crtc_state);
> > >  u32 bxt_signal_levels(struct intel_dp *intel_dp);
> > >  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
> > >  u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
> > > -- 
> > > 2.13.6
> > > 
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW
  2017-10-19 23:44   ` Rodrigo Vivi
@ 2017-10-20 16:14     ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 16:14 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Thu, Oct 19, 2017 at 04:44:34PM -0700, Rodrigo Vivi wrote:
> On Wed, Oct 18, 2017 at 08:48:21PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Track the system agent voltage we request from pcode in the cdclk state
> > on BDW. Annoyingly we can't actually read out the current value since
> > there's no pcode command to do that, so we'll have to just assume that
> > it worked.
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_cdclk.c | 36 ++++++++++++++++++++++++++----------
> >  1 file changed, 26 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index df71667c9fd6..7442e9443ffa 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -648,6 +648,21 @@ static int bdw_calc_cdclk(int min_cdclk)
> >  		return 337500;
> >  }
> >  
> > +static u8 bdw_calc_voltage(int cdclk)
> > +{
> > +	switch (cdclk) {
> > +	default:
> > +	case 337500:
> > +		return 2;
> > +	case 450000:
> > +		return 0;
> > +	case 540000:
> > +		return 1;
> > +	case 675000:
> > +		return 3;
> > +	}
> > +}
> > +
> >  static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
> >  			  struct intel_cdclk_state *cdclk_state)
> >  {
> > @@ -666,13 +681,19 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
> >  		cdclk_state->cdclk = 337500;
> >  	else
> >  		cdclk_state->cdclk = 675000;
> > +
> > +	/*
> > +	 * Can't read this out :( Let's assume it's
> > +	 * at least what the CDCLK frequency requires.
> > +	 */
> > +	cdclk_state->voltage = bdw_calc_voltage(cdclk_state->cdclk);
> >  }
> >  
> >  static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
> >  			  const struct intel_cdclk_state *cdclk_state)
> >  {
> >  	int cdclk = cdclk_state->cdclk;
> > -	uint32_t val, data;
> > +	uint32_t val;
> >  	int ret;
> >  
> >  	if (WARN((I915_READ(LCPLL_CTL) &
> > @@ -713,19 +734,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
> >  		/* fall through */
> >  	case 337500:
> >  		val |= LCPLL_CLK_FREQ_337_5_BDW;
> > -		data = 2;
> >  		break;
> >  	case 450000:
> >  		val |= LCPLL_CLK_FREQ_450;
> > -		data = 0;
> >  		break;
> >  	case 540000:
> >  		val |= LCPLL_CLK_FREQ_54O_BDW;
> > -		data = 1;
> >  		break;
> >  	case 675000:
> >  		val |= LCPLL_CLK_FREQ_675_BDW;
> > -		data = 3;
> >  		break;
> >  	}
> >  
> > @@ -740,16 +757,13 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
> >  		DRM_ERROR("Switching back to LCPLL failed\n");
> >  
> >  	mutex_lock(&dev_priv->pcu_lock);
> > -	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
> > +	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
> > +				cdclk_state->voltage);
> >  	mutex_unlock(&dev_priv->pcu_lock);
> >  
> >  	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
> >  
> >  	intel_update_cdclk(dev_priv);
> > -
> > -	WARN(cdclk != dev_priv->cdclk.hw.cdclk,
> > -	     "cdclk requested %d kHz but got %d kHz\n",
> > -	     cdclk, dev_priv->cdclk.hw.cdclk);
> 
> Why?

We don't have such a thing anywhere else either. It would be better
to stick something like that into a more central location. Probably
we should just go for a full cdclk state verification somewhere.

Apparently I forgot to split this out to a separate patch.

> 
> >  }
> >  
> >  static int skl_calc_cdclk(int min_cdclk, int vco)
> > @@ -1919,11 +1933,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  	cdclk = bdw_calc_cdclk(min_cdclk);
> >  
> >  	intel_state->cdclk.logical.cdclk = cdclk;
> > +	intel_state->cdclk.logical.voltage = bdw_calc_voltage(cdclk);
> >  
> >  	if (!intel_state->active_crtcs) {
> >  		cdclk = bdw_calc_cdclk(0);
> >  
> >  		intel_state->cdclk.actual.cdclk = cdclk;
> > +		intel_state->cdclk.actual.voltage = bdw_calc_voltage(cdclk);
> >  	} else {
> >  		intel_state->cdclk.actual =
> >  			intel_state->cdclk.logical;
> > -- 
> > 2.13.6
> > 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v2 3/8] drm/i915: Use cdclk_state->voltage on VLV/CHV
  2017-10-19 23:42     ` Rodrigo Vivi
@ 2017-10-20 16:20       ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 16:20 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Thu, Oct 19, 2017 at 04:42:52PM -0700, Rodrigo Vivi wrote:
> On Thu, Oct 19, 2017 at 05:43:29PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Store the punit DSPFREQUAR value into cdclk_state->voltage on
> > VLV/CHV. Since we can actually read that out from the hardware
> > this can give us a bit more cross checking between the hardware
> > and software state.
> > 
> > v2: Don't break waiting for cdclk change on VLV/CHV
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_cdclk.c | 66 +++++++++++++++++++++++++++++---------
> >  1 file changed, 50 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index 522222f8bb50..9cc4374797eb 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -437,13 +437,45 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
> >  		return 200000;
> >  }
> >  
> > +static u8 vlv_calc_voltage(struct drm_i915_private *dev_priv, int cdclk)
> > +{
> > +	if (IS_VALLEYVIEW(dev_priv)) {
> > +		if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
> > +			return 2;
> > +		else if (cdclk >= 266667)
> > +			return 1;
> > +		else
> > +			return 0;
> > +	} else {
> > +		/*
> > +		 * Specs are full of misinformation, but testing on actual
> > +		 * hardware has shown that we just need to write the desired
> > +		 * CCK divider into the Punit register.
> > +		 */
> > +		return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
> > +	}
> > +}
> > +
> >  static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
> >  			  struct intel_cdclk_state *cdclk_state)
> >  {
> > +	u32 val;
> > +
> >  	cdclk_state->vco = vlv_get_hpll_vco(dev_priv);
> >  	cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
> >  					       CCK_DISPLAY_CLOCK_CONTROL,
> >  					       cdclk_state->vco);
> > +
> > +	mutex_lock(&dev_priv->pcu_lock);
> > +	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
> > +	mutex_unlock(&dev_priv->pcu_lock);
> > +
> > +	if (IS_VALLEYVIEW(dev_priv))
> > +		cdclk_state->voltage = (val & DSPFREQGUAR_MASK) >>
> > +			DSPFREQGUAR_SHIFT;
> > +	else
> > +		cdclk_state->voltage = (val & DSPFREQGUAR_MASK_CHV) >>
> > +			DSPFREQGUAR_SHIFT_CHV;
> 
> Oh interresting that vlv is the only one where we can actually read it. :(
> 
> I was going to ask pointers to spec, but just by {vlv,chv}_set_cdclk it was
> possible to verify this is right.

Yeah, the iosf sideband mailbox is much nicer because you have actual
read vs. write opcodes in addition to the port+register offset
information which just specify what you want to access.

> 
> >  }
> >  
> >  static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
> > @@ -486,7 +518,19 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
> >  			  const struct intel_cdclk_state *cdclk_state)
> >  {
> >  	int cdclk = cdclk_state->cdclk;
> > -	u32 val, cmd;
> > +	u32 val, cmd = cdclk_state->voltage;
> > +
> > +	switch (cdclk) {
> > +	case 400000:
> > +	case 333333:
> > +	case 320000:
> > +	case 266667:
> > +	case 200000:
> > +		break;
> > +	default:
> > +		MISSING_CASE(cdclk);
> > +		return;
> > +	}
> 
> I believe this should be in a separated patch, no?!
> Seems something we were already missing anyways.

I was going back and forth between removing this from the
chv_set_cdclk(), and in the end I decided to keep it. And looks like I
then accidentally added it into vlv_set_cdclk() as well thinking both
had it originally. I guess I'm still leaning towards keeping it, so
I'll go ahead and split this out to a separate patch.

> 
> But anyways, if you decide to split or not
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> >  
> >  	/* There are cases where we can end up here with power domains
> >  	 * off and a CDCLK frequency other than the minimum, like when
> > @@ -496,13 +540,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
> >  	 */
> >  	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
> >  
> > -	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
> > -		cmd = 2;
> > -	else if (cdclk == 266667)
> > -		cmd = 1;
> > -	else
> > -		cmd = 0;
> > -
> >  	mutex_lock(&dev_priv->pcu_lock);
> >  	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
> >  	val &= ~DSPFREQGUAR_MASK;
> > @@ -562,7 +599,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
> >  			  const struct intel_cdclk_state *cdclk_state)
> >  {
> >  	int cdclk = cdclk_state->cdclk;
> > -	u32 val, cmd;
> > +	u32 val, cmd = cdclk_state->voltage;
> >  
> >  	switch (cdclk) {
> >  	case 333333:
> > @@ -583,13 +620,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
> >  	 */
> >  	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
> >  
> > -	/*
> > -	 * Specs are full of misinformation, but testing on actual
> > -	 * hardware has shown that we just need to write the desired
> > -	 * CCK divider into the Punit register.
> > -	 */
> > -	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
> > -
> >  	mutex_lock(&dev_priv->pcu_lock);
> >  	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
> >  	val &= ~DSPFREQGUAR_MASK_CHV;
> > @@ -1859,11 +1889,15 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
> >  	cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
> >  
> >  	intel_state->cdclk.logical.cdclk = cdclk;
> > +	intel_state->cdclk.logical.voltage =
> > +		vlv_calc_voltage(dev_priv, cdclk);
> >  
> >  	if (!intel_state->active_crtcs) {
> >  		cdclk = vlv_calc_cdclk(dev_priv, 0);
> >  
> >  		intel_state->cdclk.actual.cdclk = cdclk;
> > +		intel_state->cdclk.actual.voltage =
> > +			vlv_calc_voltage(dev_priv, cdclk);
> >  	} else {
> >  		intel_state->cdclk.actual =
> >  			intel_state->cdclk.logical;
> > -- 
> > 2.13.6
> > 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev3)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (13 preceding siblings ...)
  2017-10-20  0:22 ` ✓ Fi.CI.IGT: " Patchwork
@ 2017-10-20 16:28 ` Patchwork
  2017-10-20 17:48 ` ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev6) Patchwork
  2017-10-20 19:19 ` ✓ Fi.CI.IGT: " Patchwork
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-20 16:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev3)
URL   : https://patchwork.freedesktop.org/series/32247/
State : success

== Summary ==

Series 32247v3 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/3/mbox/

Test chamelium:
        Subgroup dp-crc-fast:
                pass       -> FAIL       (fi-kbl-7500u) fdo#102514
Test kms_pipe_crc_basic:
        Subgroup read-crc-pipe-b-frame-sequence:
                incomplete -> PASS       (fi-skl-6700hq) fdo#102035
Test prime_vgem:
        Subgroup basic-fence-flip:
                dmesg-warn -> PASS       (fi-kbl-7567u) fdo#103165 +1

fdo#102514 https://bugs.freedesktop.org/show_bug.cgi?id=102514
fdo#102035 https://bugs.freedesktop.org/show_bug.cgi?id=102035
fdo#103165 https://bugs.freedesktop.org/show_bug.cgi?id=103165

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:447s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:458s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:370s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:536s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:265s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:495s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:497s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:490s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:473s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:561s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:417s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:249s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:576s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:447s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:428s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:429s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:490s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:457s
fi-kbl-7500u     total:289  pass:263  dwarn:1   dfail:0   fail:1   skip:24  time:479s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:569s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:474s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:584s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:539s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:453s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:646s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:526s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:500s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:452s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:562s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:418s

75b85b0dce2faee585046d3ce19d76bcb163c3e7 drm-tip: 2017y-10m-20d-10h-07m-16s UTC integration manifest
741f1bd0da40 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
22db0740f919 drm/i915: Use cdclk_state->voltage on CNL
f0412da619c1 drm/i915: Use cdclk_state->voltage on BXT/GLK
ca3383da1f77 drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
3da21b55cd88 drm/i915: Use cdclk_state->voltage on BDW
7c6e87108fea drm/i915: Use cdclk_state->voltage on VLV/CHV
68348ba1d43a drm/i915: Start tracking voltage level in the cdclk state
0ee31a853816 drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6126/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v2 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 16:09   ` [PATCH v2 " Ville Syrjala
@ 2017-10-20 16:52     ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 16:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

On Fri, Oct 20, 2017 at 07:09:45PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> On CNL we may need to bump up the system agent voltage not only due
> to CDCLK but also when driving DDI port with a sufficiently high clock.
> To that end start tracking the minimum acceptable voltage for each crtc.
> We do the tracking via crtcs because we don't have any kind of encoder
> state. Also there's no downside to doing it this way, and it matches how
> we track cdclk requirements on account of pixel rate.
> 
> v2: Allow disabled crtcs to use the min voltage
>     Add IS_CNL check to intel_ddi_compute_min_voltage() since
>     we're using CNL specific values there
>     s/intel_compute_min_voltage/cnl_compute_min_voltage/ since
>     the function makes hw specific assumptions about the voltage
>     values
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  2 ++
>  drivers/gpu/drm/i915/intel_cdclk.c   | 50 ++++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_ddi.c     | 11 ++++++++
>  drivers/gpu/drm/i915/intel_display.c |  9 +++++++
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  5 ++++
>  drivers/gpu/drm/i915/intel_drv.h     |  6 +++++
>  6 files changed, 81 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d3ac58dc275f..185711a852b0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2415,6 +2415,8 @@ struct drm_i915_private {
>  	unsigned int active_crtcs;
>  	/* minimum acceptable cdclk for each pipe */
>  	int min_cdclk[I915_MAX_PIPES];
> +	/* minimum acceptable voltage for each pipe */
> +	u8 min_voltage[I915_MAX_PIPES];
>  
>  	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
>  
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 5bbf9f6023a2..78029f70e6ea 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1669,6 +1669,12 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	intel_update_cdclk(dev_priv);
> +
> +	/*
> +	 * Can't read out the voltage :( So let's
> +	 * just assume everything is as expected.
> +	 */
> +	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
>  }
>  
>  static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
> @@ -1938,6 +1944,42 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
>  	return min_cdclk;
>  }
>  
> +/*
> + * Note that this functions assumes that 0 is
> + * the lowest voltage value, and higher values
> + * correspond to increasingly higher voltages.
> + *
> + * Should that relationship no longer hold on
> + * future platforms this code will need to be
> + * adjusted.
> + */
> +static u8 cnl_compute_min_voltage(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc *crtc;
> +	struct intel_crtc_state *crtc_state;
> +	u8 min_voltage;
> +	int i;
> +	enum pipe pipe;
> +
> +	memcpy(state->min_voltage, dev_priv->min_voltage,
> +	       sizeof(state->min_voltage));
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> +		if (crtc_state->base.enable)
> +			state->min_voltage[i] = crtc_state->min_voltage;
> +		else
> +			state->min_voltage[i] = 0;
> +	}
> +
> +	min_voltage = 0;
> +	for_each_pipe(dev_priv, pipe)
> +		min_voltage = max(state->min_voltage[pipe],
> +				  min_voltage);
> +
> +	return min_voltage;
> +}
> +
>  static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> @@ -2021,7 +2063,9 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> -	intel_state->cdclk.logical.voltage = skl_calc_voltage(cdclk);
> +	intel_state->cdclk.logical.voltage =
> +		max(skl_calc_voltage(cdclk),
> +		    cnl_compute_min_voltage(intel_state));

And of course this hunk shouldn't be here. It was part of my test hack.
v3 coming up.

>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = skl_calc_cdclk(0, vco);

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 3/8] drm/i915: Use cdclk_state->voltage on VLV/CHV
  2017-10-18 20:48 ` [PATCH 3/8] drm/i915: USe cdclk_state->voltage on VLV/CHV Ville Syrjala
  2017-10-19 17:43   ` [PATCH v2 3/8] drm/i915: Use " Ville Syrjala
@ 2017-10-20 17:03   ` Ville Syrjala
  1 sibling, 0 replies; 58+ messages in thread
From: Ville Syrjala @ 2017-10-20 17:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Store the punit DSPFREQUAR value into cdclk_state->voltage on
VLV/CHV. Since we can actually read that out from the hardware
this can give us a bit more cross checking between the hardware
and software state.

v2: Don't break waiting for cdclk change on VLV/CHV
v3: Split out the cdclk sanity check in vlv_set_cdclk() (Rodrigo)

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 54 +++++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 522222f8bb50..e2f18545d20c 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -437,13 +437,45 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
 		return 200000;
 }
 
+static u8 vlv_calc_voltage(struct drm_i915_private *dev_priv, int cdclk)
+{
+	if (IS_VALLEYVIEW(dev_priv)) {
+		if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
+			return 2;
+		else if (cdclk >= 266667)
+			return 1;
+		else
+			return 0;
+	} else {
+		/*
+		 * Specs are full of misinformation, but testing on actual
+		 * hardware has shown that we just need to write the desired
+		 * CCK divider into the Punit register.
+		 */
+		return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
+	}
+}
+
 static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
 			  struct intel_cdclk_state *cdclk_state)
 {
+	u32 val;
+
 	cdclk_state->vco = vlv_get_hpll_vco(dev_priv);
 	cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
 					       CCK_DISPLAY_CLOCK_CONTROL,
 					       cdclk_state->vco);
+
+	mutex_lock(&dev_priv->pcu_lock);
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	mutex_unlock(&dev_priv->pcu_lock);
+
+	if (IS_VALLEYVIEW(dev_priv))
+		cdclk_state->voltage = (val & DSPFREQGUAR_MASK) >>
+			DSPFREQGUAR_SHIFT;
+	else
+		cdclk_state->voltage = (val & DSPFREQGUAR_MASK_CHV) >>
+			DSPFREQGUAR_SHIFT_CHV;
 }
 
 static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
@@ -486,7 +518,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_state *cdclk_state)
 {
 	int cdclk = cdclk_state->cdclk;
-	u32 val, cmd;
+	u32 val, cmd = cdclk_state->voltage;
 
 	/* There are cases where we can end up here with power domains
 	 * off and a CDCLK frequency other than the minimum, like when
@@ -496,13 +528,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
-	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
-		cmd = 2;
-	else if (cdclk == 266667)
-		cmd = 1;
-	else
-		cmd = 0;
-
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK;
@@ -562,7 +587,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_state *cdclk_state)
 {
 	int cdclk = cdclk_state->cdclk;
-	u32 val, cmd;
+	u32 val, cmd = cdclk_state->voltage;
 
 	switch (cdclk) {
 	case 333333:
@@ -583,13 +608,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
-	/*
-	 * Specs are full of misinformation, but testing on actual
-	 * hardware has shown that we just need to write the desired
-	 * CCK divider into the Punit register.
-	 */
-	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
-
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK_CHV;
@@ -1859,11 +1877,15 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
 	cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
 
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage =
+		vlv_calc_voltage(dev_priv, cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = vlv_calc_cdclk(dev_priv, 0);
 
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage =
+			vlv_calc_voltage(dev_priv, cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v2 4/8] drm/i915: Use cdclk_state->voltage on BDW
  2017-10-18 20:48 ` [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW Ville Syrjala
  2017-10-19 23:44   ` Rodrigo Vivi
@ 2017-10-20 17:03   ` Ville Syrjala
  2017-10-20 20:47     ` Rodrigo Vivi
  1 sibling, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-20 17:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

Track the system agent voltage we request from pcode in the cdclk state
on BDW. Annoyingly we can't actually read out the current value since
there's no pcode command to do that, so we'll have to just assume that
it worked.

v2: Keep the WARN_ON (Rodrigo)

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_cdclk.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index e2f18545d20c..ab0481183bae 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -639,6 +639,21 @@ static int bdw_calc_cdclk(int min_cdclk)
 		return 337500;
 }
 
+static u8 bdw_calc_voltage(int cdclk)
+{
+	switch (cdclk) {
+	default:
+	case 337500:
+		return 2;
+	case 450000:
+		return 0;
+	case 540000:
+		return 1;
+	case 675000:
+		return 3;
+	}
+}
+
 static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
 			  struct intel_cdclk_state *cdclk_state)
 {
@@ -657,13 +672,19 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
 		cdclk_state->cdclk = 337500;
 	else
 		cdclk_state->cdclk = 675000;
+
+	/*
+	 * Can't read this out :( Let's assume it's
+	 * at least what the CDCLK frequency requires.
+	 */
+	cdclk_state->voltage = bdw_calc_voltage(cdclk_state->cdclk);
 }
 
 static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_state *cdclk_state)
 {
 	int cdclk = cdclk_state->cdclk;
-	uint32_t val, data;
+	uint32_t val;
 	int ret;
 
 	if (WARN((I915_READ(LCPLL_CTL) &
@@ -704,19 +725,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		/* fall through */
 	case 337500:
 		val |= LCPLL_CLK_FREQ_337_5_BDW;
-		data = 2;
 		break;
 	case 450000:
 		val |= LCPLL_CLK_FREQ_450;
-		data = 0;
 		break;
 	case 540000:
 		val |= LCPLL_CLK_FREQ_54O_BDW;
-		data = 1;
 		break;
 	case 675000:
 		val |= LCPLL_CLK_FREQ_675_BDW;
-		data = 3;
 		break;
 	}
 
@@ -731,7 +748,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		DRM_ERROR("Switching back to LCPLL failed\n");
 
 	mutex_lock(&dev_priv->pcu_lock);
-	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
+	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
+				cdclk_state->voltage);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
@@ -1910,11 +1928,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
 	cdclk = bdw_calc_cdclk(min_cdclk);
 
 	intel_state->cdclk.logical.cdclk = cdclk;
+	intel_state->cdclk.logical.voltage = bdw_calc_voltage(cdclk);
 
 	if (!intel_state->active_crtcs) {
 		cdclk = bdw_calc_cdclk(0);
 
 		intel_state->cdclk.actual.cdclk = cdclk;
+		intel_state->cdclk.actual.voltage = bdw_calc_voltage(cdclk);
 	} else {
 		intel_state->cdclk.actual =
 			intel_state->cdclk.logical;
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-18 20:48 ` [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports Ville Syrjala
  2017-10-19 23:54   ` Rodrigo Vivi
  2017-10-20 16:09   ` [PATCH v2 " Ville Syrjala
@ 2017-10-20 17:05   ` Ville Syrjala
  2017-10-23 18:39     ` Rodrigo Vivi
  2 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjala @ 2017-10-20 17:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

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

On CNL we may need to bump up the system agent voltage not only due
to CDCLK but also when driving DDI port with a sufficiently high clock.
To that end start tracking the minimum acceptable voltage for each crtc.
We do the tracking via crtcs because we don't have any kind of encoder
state. Also there's no downside to doing it this way, and it matches how
we track cdclk requirements on account of pixel rate.

v2: Allow disabled crtcs to use the min voltage
    Add IS_CNL check to intel_ddi_compute_min_voltage() since
    we're using CNL specific values there
    s/intel_compute_min_voltage/cnl_compute_min_voltage/ since
    the function makes hw specific assumptions about the voltage
    values
v3: Drop the test hack leftovers from skl_modeset_calc_cdclk()

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  2 ++
 drivers/gpu/drm/i915/intel_cdclk.c   | 46 +++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_ddi.c     | 11 +++++++++
 drivers/gpu/drm/i915/intel_display.c |  9 +++++++
 drivers/gpu/drm/i915/intel_dp_mst.c  |  5 ++++
 drivers/gpu/drm/i915/intel_drv.h     |  6 +++++
 6 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d3ac58dc275f..185711a852b0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2415,6 +2415,8 @@ struct drm_i915_private {
 	unsigned int active_crtcs;
 	/* minimum acceptable cdclk for each pipe */
 	int min_cdclk[I915_MAX_PIPES];
+	/* minimum acceptable voltage for each pipe */
+	u8 min_voltage[I915_MAX_PIPES];
 
 	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
 
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 2a0cc9aafa5a..0f5f2ce4bd3e 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1661,6 +1661,12 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
+
+	/*
+	 * Can't read out the voltage :( So let's
+	 * just assume everything is as expected.
+	 */
+	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
 }
 
 static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
@@ -1930,6 +1936,42 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
 	return min_cdclk;
 }
 
+/*
+ * Note that this functions assumes that 0 is
+ * the lowest voltage value, and higher values
+ * correspond to increasingly higher voltages.
+ *
+ * Should that relationship no longer hold on
+ * future platforms this code will need to be
+ * adjusted.
+ */
+static u8 cnl_compute_min_voltage(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
+	u8 min_voltage;
+	int i;
+	enum pipe pipe;
+
+	memcpy(state->min_voltage, dev_priv->min_voltage,
+	       sizeof(state->min_voltage));
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+		if (crtc_state->base.enable)
+			state->min_voltage[i] = crtc_state->min_voltage;
+		else
+			state->min_voltage[i] = 0;
+	}
+
+	min_voltage = 0;
+	for_each_pipe(dev_priv, pipe)
+		min_voltage = max(state->min_voltage[pipe],
+				  min_voltage);
+
+	return min_voltage;
+}
+
 static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
@@ -2086,7 +2128,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
 
 	intel_state->cdclk.logical.vco = vco;
 	intel_state->cdclk.logical.cdclk = cdclk;
-	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
+	intel_state->cdclk.logical.voltage =
+		max(cnl_calc_voltage(cdclk),
+		    cnl_compute_min_voltage(intel_state));
 
 	if (!intel_state->active_crtcs) {
 		cdclk = cnl_calc_cdclk(0);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index adf51b328844..f707134b4f65 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2525,6 +2525,13 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
 	return false;
 }
 
+void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
+				   struct intel_crtc_state *crtc_state)
+{
+	if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000)
+		crtc_state->min_voltage = 2;
+}
+
 void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config)
 {
@@ -2624,6 +2631,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	if (IS_GEN9_LP(dev_priv))
 		pipe_config->lane_lat_optim_mask =
 			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
+
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
 }
 
 static bool intel_ddi_compute_config(struct intel_encoder *encoder,
@@ -2650,6 +2659,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
 			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
 							     pipe_config->lane_count);
 
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
+
 	return ret;
 
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 32e7cca52da2..83024956a74d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
 
 	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
 	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
+	dev_priv->min_voltage[intel_crtc->pipe] = 0;
 }
 
 /*
@@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
 	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
 
+	PIPE_CONF_CHECK_I(min_voltage);
+
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
 #undef PIPE_CONF_CHECK_P
@@ -11964,6 +11967,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 		DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n",
 			      intel_state->cdclk.logical.cdclk,
 			      intel_state->cdclk.actual.cdclk);
+		DRM_DEBUG_KMS("New voltage calculated to be logical %u, actual %u\n",
+			      intel_state->cdclk.logical.voltage,
+			      intel_state->cdclk.actual.voltage);
 	} else {
 		to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical;
 	}
@@ -12532,6 +12538,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	if (intel_state->modeset) {
 		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
 		       sizeof(intel_state->min_cdclk));
+		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
+		       sizeof(intel_state->min_voltage));
 		dev_priv->active_crtcs = intel_state->active_crtcs;
 		dev_priv->cdclk.logical = intel_state->cdclk.logical;
 		dev_priv->cdclk.actual = intel_state->cdclk.actual;
@@ -15042,6 +15050,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		}
 
 		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
+		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
 
 		intel_pipe_config_sanity_check(dev_priv, crtc_state);
 	}
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 772521440a9f..6c1da88b5fef 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 					struct intel_crtc_state *pipe_config,
 					struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_digital_port *intel_dig_port = intel_mst->primary;
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
@@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	pipe_config->dp_m_n.tu = slots;
 
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
+
 	return true;
 }
 
@@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
 	intel_dp_get_m_n(crtc, pipe_config);
 
 	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
+
+	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
 }
 
 static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 765a737700c5..002894b13d69 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -386,6 +386,8 @@ struct intel_atomic_state {
 	unsigned int active_crtcs;
 	/* minimum acceptable cdclk for each pipe */
 	int min_cdclk[I915_MAX_PIPES];
+	/* minimum acceptable voltage for each pipe */
+	u8 min_voltage[I915_MAX_PIPES];
 
 	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
 
@@ -739,6 +741,8 @@ struct intel_crtc_state {
 	 */
 	uint8_t lane_lat_optim_mask;
 
+	u8 min_voltage;
+
 	/* Panel fitter controls for gen2-gen4 + VLV */
 	struct {
 		u32 control;
@@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 				    bool state);
+void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
+				   struct intel_crtc_state *crtc_state);
 u32 bxt_signal_levels(struct intel_dp *intel_dp);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
-- 
2.13.6

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev6)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (14 preceding siblings ...)
  2017-10-20 16:28 ` ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev3) Patchwork
@ 2017-10-20 17:48 ` Patchwork
  2017-10-20 19:19 ` ✓ Fi.CI.IGT: " Patchwork
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-20 17:48 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev6)
URL   : https://patchwork.freedesktop.org/series/32247/
State : success

== Summary ==

Series 32247v6 drm/i915: CNL DVFS thing
https://patchwork.freedesktop.org/api/1.0/series/32247/revisions/6/mbox/

Test kms_frontbuffer_tracking:
        Subgroup basic:
                dmesg-warn -> PASS       (fi-bdw-5557u) fdo#102473
Test kms_pipe_crc_basic:
        Subgroup hang-read-crc-pipe-b:
                incomplete -> PASS       (fi-skl-6700hq)
        Subgroup suspend-read-crc-pipe-b:
                dmesg-warn -> PASS       (fi-byt-j1900) fdo#101705

fdo#102473 https://bugs.freedesktop.org/show_bug.cgi?id=102473
fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:439s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:458s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:367s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:531s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:263s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:495s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:495s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:493s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:484s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:556s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:414s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:249s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:577s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:453s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:429s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:435s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:494s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:457s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:493s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:570s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:476s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:584s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:545s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:447s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:645s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:515s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:497s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:455s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:563s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:420s

e9b02ebe67a3f104fff3ab668cbdaad8d551c08a drm-tip: 2017y-10m-20d-17h-05m-26s UTC integration manifest
9dbc36c72492 drm/i915: Adjust system agent voltage on CNL if required by DDI ports
fd72f10243b3 drm/i915: Use cdclk_state->voltage on CNL
62390241003e drm/i915: Use cdclk_state->voltage on BXT/GLK
e5aca2bccef8 drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
94ab9cb948fa drm/i915: Use cdclk_state->voltage on BDW
f94e00229b58 drm/i915: Use cdclk_state->voltage on VLV/CHV
d42f5a0951aa drm/i915: Start tracking voltage level in the cdclk state
0d1bf43cd851 drm/i915: Clean up some cdclk switch statements

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6127/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 11:11     ` Ville Syrjälä
@ 2017-10-20 17:48       ` Runyan, Arthur J
  2017-10-20 20:07         ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Runyan, Arthur J @ 2017-10-20 17:48 UTC (permalink / raw)
  To: Ville Syrjälä, Vivi, Rodrigo; +Cc: intel-gfx

Sorry about top reply from corporate email...
If you know in advance that you will just be temporarily disabling the PLL, then your sequence works. 

-----Original Message-----
From: Ville Syrjälä [mailto:ville.syrjala@linux.intel.com] 
Sent: Friday, 20 October, 2017 4:12 AM
To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
Cc: intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>; Runyan, Arthur J <arthur.j.runyan@intel.com>
Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports

On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> 
> On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > On CNL we may need to bump up the system agent voltage not only due
> > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > To that end start tracking the minimum acceptable voltage for each crtc.
> > We do the tracking via crtcs because we don't have any kind of encoder
> > state. Also there's no downside to doing it this way, and it matches how
> > we track cdclk requirements on account of pixel rate.
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> (Although I didn't find cases where I could force a higher voltage level,
> everything works well on CNL with this.)

I went and actually read the spec now :) so I can now see that this
doesn't really match the sequence listed in the spec.

For example, let's assume we have a modeset where we have to disable
a DPLL, change CDCLK, and finally enable a DPLL again.

What the spec says we should do is something like this:
1.  DVFS pre sequence
2.  disable DPLL
3.  DVFS post sequence
4.  disable DPLL power
...
5.  DVFS pre sequence
6.  configure CDCLK_CTL
7.  DVFS post sequence
...
8.  enable DPLL power
9.  DVFS pre sequence
10. enable DPLL
11. DVFS post sequence

With my code what we'd end up doing is this instead:
1. disable DPLL
2. disable DPLL power
...
3. DVFS pre sequence
4. configure CDCLK_CTL
5. DVFS post sequence
...
6. enable DPLL power
7. enable DPLL

So my way always results in running the DVFS sequences at most once.
With the way the spec has things listed we might have to run the
sequences multiple times. 

Art, is there a good reason why we'd actually have to run the
DVFS sequences around each DPLL_ENABLE write, instead of just
doing it once at any point between disabling and enabling
DPLLs?

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915: CNL DVFS thing (rev6)
  2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
                   ` (15 preceding siblings ...)
  2017-10-20 17:48 ` ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev6) Patchwork
@ 2017-10-20 19:19 ` Patchwork
  16 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2017-10-20 19:19 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: CNL DVFS thing (rev6)
URL   : https://patchwork.freedesktop.org/series/32247/
State : success

== Summary ==

Test kms_busy:
        Subgroup extended-modeset-hang-oldfb-with-reset-render-A:
                pass       -> DMESG-WARN (shard-hsw) fdo#102249

fdo#102249 https://bugs.freedesktop.org/show_bug.cgi?id=102249

shard-hsw        total:2540 pass:1429 dwarn:2   dfail:0   fail:8   skip:1101 time:9296s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6127/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 17:48       ` Runyan, Arthur J
@ 2017-10-20 20:07         ` Ville Syrjälä
  2017-10-20 20:36           ` Rodrigo Vivi
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-20 20:07 UTC (permalink / raw)
  To: Runyan, Arthur J; +Cc: intel-gfx, Vivi, Rodrigo

On Fri, Oct 20, 2017 at 05:48:54PM +0000, Runyan, Arthur J wrote:
> Sorry about top reply from corporate email...
> If you know in advance that you will just be temporarily disabling the PLL, then your sequence works. 

Actually we would end up using this sequence even if disable the PLL for
good.

Eg. if we're just disabling the entire pipe+DPLL, we'd do this (assuming
cdclk doesn't need changing, but voltage can be lowered due to the port
no longer requiring it):
1. disable DPLL
2. disable DPLL power
...
3. DVFS pre sequence
4. DVFS post sequence

And when starting up a pipe from the cold with a new DPLL we'd conversly
do this (again assuming no cdclk change, but voltage would have to be
ramped up for the port):
1. DVFS pre sequence
2. DVFS post sequence
...
3. enable DPLL power
4. enable DPLL

It does look a bit strange doing the DVFS sequences on their own like
that, but I don't see why that should be problem. From where I'm sitting
it doesn't really look any different than the following seqeunces:

Disable with cdclk changing but port clock not having any effect
on the voltage:
1. disable DPLL
2. disable DPLL power
...
3. DVFS pre sequence
4. change cdclk
5. DVFS post sequence

Enable with cdclk changing but port clock not having any effect
on the voltage:
1. DVFS pre sequence
2. change cdclk
3. DVFS post sequence
...
4. enable DPLL power
5. enable DPLL

So unless something is snooping the actual state of the DPLLs, and based
on that second guessing our choice of voltage, I don't really see how
these two cases differ at all.

> 
> -----Original Message-----
> From: Ville Syrjälä [mailto:ville.syrjala@linux.intel.com] 
> Sent: Friday, 20 October, 2017 4:12 AM
> To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> Cc: intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>; Runyan, Arthur J <arthur.j.runyan@intel.com>
> Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
> 
> On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> > 
> > On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > On CNL we may need to bump up the system agent voltage not only due
> > > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > > To that end start tracking the minimum acceptable voltage for each crtc.
> > > We do the tracking via crtcs because we don't have any kind of encoder
> > > state. Also there's no downside to doing it this way, and it matches how
> > > we track cdclk requirements on account of pixel rate.
> > > 
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > 
> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > 
> > Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > (Although I didn't find cases where I could force a higher voltage level,
> > everything works well on CNL with this.)
> 
> I went and actually read the spec now :) so I can now see that this
> doesn't really match the sequence listed in the spec.
> 
> For example, let's assume we have a modeset where we have to disable
> a DPLL, change CDCLK, and finally enable a DPLL again.
> 
> What the spec says we should do is something like this:
> 1.  DVFS pre sequence
> 2.  disable DPLL
> 3.  DVFS post sequence
> 4.  disable DPLL power
> ...
> 5.  DVFS pre sequence
> 6.  configure CDCLK_CTL
> 7.  DVFS post sequence
> ...
> 8.  enable DPLL power
> 9.  DVFS pre sequence
> 10. enable DPLL
> 11. DVFS post sequence
> 
> With my code what we'd end up doing is this instead:
> 1. disable DPLL
> 2. disable DPLL power
> ...
> 3. DVFS pre sequence
> 4. configure CDCLK_CTL
> 5. DVFS post sequence
> ...
> 6. enable DPLL power
> 7. enable DPLL
> 
> So my way always results in running the DVFS sequences at most once.
> With the way the spec has things listed we might have to run the
> sequences multiple times. 
> 
> Art, is there a good reason why we'd actually have to run the
> DVFS sequences around each DPLL_ENABLE write, instead of just
> doing it once at any point between disabling and enabling
> DPLLs?
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 20:07         ` Ville Syrjälä
@ 2017-10-20 20:36           ` Rodrigo Vivi
  2017-10-20 21:44             ` Runyan, Arthur J
  2017-10-23 11:48             ` Ville Syrjälä
  0 siblings, 2 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-20 20:36 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Runyan, Arthur J

On Fri, Oct 20, 2017 at 08:07:07PM +0000, Ville Syrjälä wrote:
> On Fri, Oct 20, 2017 at 05:48:54PM +0000, Runyan, Arthur J wrote:
> > Sorry about top reply from corporate email...
> > If you know in advance that you will just be temporarily disabling the PLL, then your sequence works. 
> 
> Actually we would end up using this sequence even if disable the PLL for
> good.
> 
> Eg. if we're just disabling the entire pipe+DPLL, we'd do this (assuming
> cdclk doesn't need changing, but voltage can be lowered due to the port
> no longer requiring it):
> 1. disable DPLL
> 2. disable DPLL power
> ...
> 3. DVFS pre sequence
> 4. DVFS post sequence
> 
> And when starting up a pipe from the cold with a new DPLL we'd conversly
> do this (again assuming no cdclk change, but voltage would have to be
> ramped up for the port):
> 1. DVFS pre sequence
> 2. DVFS post sequence
> ...
> 3. enable DPLL power
> 4. enable DPLL
> 
> It does look a bit strange doing the DVFS sequences on their own like
> that, but I don't see why that should be problem. From where I'm sitting
> it doesn't really look any different than the following seqeunces:
> 
> Disable with cdclk changing but port clock not having any effect
> on the voltage:
> 1. disable DPLL
> 2. disable DPLL power
> ...
> 3. DVFS pre sequence
> 4. change cdclk
> 5. DVFS post sequence
> 
> Enable with cdclk changing but port clock not having any effect
> on the voltage:
> 1. DVFS pre sequence
> 2. change cdclk
> 3. DVFS post sequence
> ...
> 4. enable DPLL power
> 5. enable DPLL
> 
> So unless something is snooping the actual state of the DPLLs, and based
> on that second guessing our choice of voltage, I don't really see how
> these two cases differ at all.

Well, I admit that I'm kind of lost on the discussion now.

but spec tells that we need use pre and post DVFS sequence
always on CDCLK part and on DPLL only "If the frequency will result in a
change to the voltage requirement,"
So in the temporary disable-re-enable case we would be safe, because
there woulnd't be no need to keep tweaking the voltage...

However on the other case you mentioned for the full pipe disable
it seems that we have a situation of non optimal power getting
wasted, right?!

Any idea how to solve that in the atomic way?
Maybe caching the global min voltage required outside cdclk struct
in a place where we can have access from both cdclk and pll state?

> 
> > 
> > -----Original Message-----
> > From: Ville Syrjälä [mailto:ville.syrjala@linux.intel.com] 
> > Sent: Friday, 20 October, 2017 4:12 AM
> > To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > Cc: intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>; Runyan, Arthur J <arthur.j.runyan@intel.com>
> > Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
> > 
> > On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> > > 
> > > On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > 
> > > > On CNL we may need to bump up the system agent voltage not only due
> > > > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > > > To that end start tracking the minimum acceptable voltage for each crtc.
> > > > We do the tracking via crtcs because we don't have any kind of encoder
> > > > state. Also there's no downside to doing it this way, and it matches how
> > > > we track cdclk requirements on account of pixel rate.
> > > > 
> > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > 
> > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > 
> > > Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > (Although I didn't find cases where I could force a higher voltage level,
> > > everything works well on CNL with this.)
> > 
> > I went and actually read the spec now :) so I can now see that this
> > doesn't really match the sequence listed in the spec.
> > 
> > For example, let's assume we have a modeset where we have to disable
> > a DPLL, change CDCLK, and finally enable a DPLL again.
> > 
> > What the spec says we should do is something like this:
> > 1.  DVFS pre sequence
> > 2.  disable DPLL
> > 3.  DVFS post sequence
> > 4.  disable DPLL power
> > ...
> > 5.  DVFS pre sequence
> > 6.  configure CDCLK_CTL
> > 7.  DVFS post sequence
> > ...
> > 8.  enable DPLL power
> > 9.  DVFS pre sequence
> > 10. enable DPLL
> > 11. DVFS post sequence
> > 
> > With my code what we'd end up doing is this instead:
> > 1. disable DPLL
> > 2. disable DPLL power
> > ...
> > 3. DVFS pre sequence
> > 4. configure CDCLK_CTL
> > 5. DVFS post sequence
> > ...
> > 6. enable DPLL power
> > 7. enable DPLL
> > 
> > So my way always results in running the DVFS sequences at most once.
> > With the way the spec has things listed we might have to run the
> > sequences multiple times. 
> > 
> > Art, is there a good reason why we'd actually have to run the
> > DVFS sequences around each DPLL_ENABLE write, instead of just
> > doing it once at any point between disabling and enabling
> > DPLLs?
> > 
> > -- 
> > Ville Syrjälä
> > Intel OTC
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state
  2017-10-20 14:01   ` Ville Syrjälä
@ 2017-10-20 20:43     ` Rodrigo Vivi
  2017-10-23 12:13       ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-20 20:43 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Oct 20, 2017 at 02:01:37PM +0000, Ville Syrjälä wrote:
> On Wed, Oct 18, 2017 at 11:48:19PM +0300, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > For CNL we'll need to start considering the port clocks when we select
> > the voltage level for the system agent. To that end start tracking the
> > voltage in the cdclk state (since that already has to adjust it).
> > 
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h         |  1 +
> >  drivers/gpu/drm/i915/intel_cdclk.c      | 31 ++++++++++++++++++++++++-------
> >  drivers/gpu/drm/i915/intel_display.c    |  8 ++++----
> >  drivers/gpu/drm/i915/intel_drv.h        |  4 +++-
> >  drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++-
> >  5 files changed, 34 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index f01c80076c59..d3ac58dc275f 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2227,6 +2227,7 @@ struct i915_oa_ops {
> >  
> >  struct intel_cdclk_state {
> >  	unsigned int cdclk, vco, ref;
> > +	u8 voltage;
> 
> BTW now that I decided to abuse this for all platforms the name
> "voltage" might not be entirely accurate anymore. Especially on VLV/CHV
> the DSPFREQUAR value isn't directly a voltage value, but instead a
> request to punit to change the cdclk frequency to a specific value.
> Although naturally punit will also make sure the voltage will be
> set sufficiently high as well.
> 
> So I'm not entirely sure we want to call it "voltage" anymore. Something
> abstract like "level" is also what came to mind when I was thingking
> about this. If anyone is irked by "voltage" and would like to see
> something different there, let me know. Otherwise I think I might just
> leave it as is for now.

I honestly prefer "dvfs_level", voltage_level or anything_level.

Even if on VLV/CHV if it was also voltage related and not
frequency related. It is strange for my brain to read
voltage 1,2,3... my poor braing automatically reads 1V, 2V, 3V!
So level would be better imho.

But it is up to you.

> 
> >  };
> >  
> >  struct drm_i915_private {
> > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > index 4bffd31a8924..522222f8bb50 100644
> > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > @@ -1690,17 +1690,34 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
> >  }
> >  
> >  /**
> > - * intel_cdclk_state_compare - Determine if two CDCLK states differ
> > + * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes
> >   * @a: first CDCLK state
> >   * @b: second CDCLK state
> >   *
> >   * Returns:
> > - * True if the CDCLK states are identical, false if they differ.
> > + * True if the CDCLK states require pipes to be off during reprogramming, false if not.
> >   */
> > -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
> >  			       const struct intel_cdclk_state *b)
> >  {
> > -	return memcmp(a, b, sizeof(*a)) == 0;
> > +	return a->cdclk != b->cdclk ||
> > +		a->vco != b->vco ||
> > +		a->ref != b->ref;
> > +}
> > +
> > +/**
> > + * intel_cdclk_changed - Determine if two CDCLK states are different
> > + * @a: first CDCLK state
> > + * @b: second CDCLK state
> > + *
> > + * Returns:
> > + * True if the CDCLK states don't match, false if they do.
> > + */
> > +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> > +			 const struct intel_cdclk_state *b)
> > +{
> > +	return intel_cdclk_needs_modeset(a, b) ||
> > +		a->voltage != b->voltage;
> >  }
> >  
> >  /**
> > @@ -1714,15 +1731,15 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> >  void intel_set_cdclk(struct drm_i915_private *dev_priv,
> >  		     const struct intel_cdclk_state *cdclk_state)
> >  {
> > -	if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state))
> > +	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state))
> >  		return;
> >  
> >  	if (WARN_ON_ONCE(!dev_priv->display.set_cdclk))
> >  		return;
> >  
> > -	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n",
> > +	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz, voltage %d\n",
> >  			 cdclk_state->cdclk, cdclk_state->vco,
> > -			 cdclk_state->ref);
> > +			 cdclk_state->ref, cdclk_state->voltage);
> >  
> >  	dev_priv->display.set_cdclk(dev_priv, cdclk_state);
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index bd62c0a65bcd..32e7cca52da2 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -11946,16 +11946,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
> >  		 * holding all the crtc locks, even if we don't end up
> >  		 * touching the hardware
> >  		 */
> > -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
> > -					       &intel_state->cdclk.logical)) {
> > +		if (intel_cdclk_changed(&dev_priv->cdclk.logical,
> > +					&intel_state->cdclk.logical)) {
> >  			ret = intel_lock_all_pipes(state);
> >  			if (ret < 0)
> >  				return ret;
> >  		}
> >  
> >  		/* All pipes must be switched off while we change the cdclk. */
> > -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
> > -					       &intel_state->cdclk.actual)) {
> > +		if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual,
> > +					      &intel_state->cdclk.actual)) {
> >  			ret = intel_modeset_all_pipes(state);
> >  			if (ret < 0)
> >  				return ret;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index a05ab3a1ab27..765a737700c5 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1324,8 +1324,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
> >  void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
> >  void intel_update_cdclk(struct drm_i915_private *dev_priv);
> >  void intel_update_rawclk(struct drm_i915_private *dev_priv);
> > -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
> >  			       const struct intel_cdclk_state *b);
> > +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> > +			 const struct intel_cdclk_state *b);
> >  void intel_set_cdclk(struct drm_i915_private *dev_priv,
> >  		     const struct intel_cdclk_state *cdclk_state);
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > index 8af286c63d3b..5ac553fab7c7 100644
> > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > @@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
> >  	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
> >  
> >  	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
> > -	WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
> > +	/* Can't read out the voltage so can't use intel_cdclk_changed() */
> > +	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
> >  
> >  	gen9_assert_dbuf_enabled(dev_priv);
> >  
> > -- 
> > 2.13.6
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL
  2017-10-20 11:18     ` Ville Syrjälä
@ 2017-10-20 20:45       ` Rodrigo Vivi
  0 siblings, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-20 20:45 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Oct 20, 2017 at 11:18:12AM +0000, Ville Syrjälä wrote:
> On Thu, Oct 19, 2017 at 04:47:08PM -0700, Rodrigo Vivi wrote:
> > On Wed, Oct 18, 2017 at 08:48:22PM +0000, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Track the system agent voltage we request from pcode in the cdclk state
> > > on SKL/KBL/CFL. Annoyingly we can't actually read out the current value since
> > > there's no pcode command to do that, so we'll have to just assume that
> > > it worked.
> > > 
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_cdclk.c | 40 +++++++++++++++++++++++++++++++-------
> > >  1 file changed, 33 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > > index 7442e9443ffa..6f7b5abe6e3f 100644
> > > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > > @@ -789,6 +789,24 @@ static int skl_calc_cdclk(int min_cdclk, int vco)
> > >  	}
> > >  }
> > >  
> > > +static u8 skl_calc_voltage(int cdclk)
> > > +{
> > > +	switch (cdclk) {
> > > +	default:
> > > +	case 308571:
> > > +	case 337500:
> > > +		return 0;
> > > +	case 450000:
> > > +	case 432000:
> > > +		return 1;
> > > +	case 540000:
> > > +		return 2;
> > > +	case 617143:
> > > +	case 675000:
> > > +		return 3;
> > > +	}
> > > +}
> > > +
> > >  static void skl_dpll0_update(struct drm_i915_private *dev_priv,
> > >  			     struct intel_cdclk_state *cdclk_state)
> > >  {
> > > @@ -839,7 +857,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
> > >  	cdclk_state->cdclk = cdclk_state->ref;
> > >  
> > >  	if (cdclk_state->vco == 0)
> > > -		return;
> > > +		goto out;
> > 
> > why do we need this case?
> 
> Mainly just to make sure the entire state is consistent.

thanks.
I don't see why not, so

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>



> 
> > 
> > >  
> > >  	cdctl = I915_READ(CDCLK_CTL);
> > >  
> > > @@ -880,6 +898,13 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
> > >  			break;
> > >  		}
> > >  	}
> > > +
> > > + out:
> > > +	/*
> > > +	 * Can't read this out :( Let's assume it's
> > > +	 * at least what the CDCLK frequency requires.
> > > +	 */
> > > +	cdclk_state->voltage = skl_calc_voltage(cdclk_state->cdclk);
> > >  }
> > >  
> > >  /* convert from kHz to .1 fixpoint MHz with -1MHz offset */
> > > @@ -964,7 +989,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  {
> > >  	int cdclk = cdclk_state->cdclk;
> > >  	int vco = cdclk_state->vco;
> > > -	u32 freq_select, pcu_ack;
> > > +	u32 freq_select;
> > >  	int ret;
> > >  
> > >  	mutex_lock(&dev_priv->pcu_lock);
> > > @@ -988,21 +1013,17 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  	case 308571:
> > >  	case 337500:
> > >  		freq_select = CDCLK_FREQ_337_308;
> > > -		pcu_ack = 0;
> > >  		break;
> > >  	case 450000:
> > >  	case 432000:
> > >  		freq_select = CDCLK_FREQ_450_432;
> > > -		pcu_ack = 1;
> > >  		break;
> > >  	case 540000:
> > >  		freq_select = CDCLK_FREQ_540;
> > > -		pcu_ack = 2;
> > >  		break;
> > >  	case 617143:
> > >  	case 675000:
> > >  		freq_select = CDCLK_FREQ_675_617;
> > > -		pcu_ack = 3;
> > >  		break;
> > >  	}
> > >  
> > > @@ -1018,7 +1039,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
> > >  
> > >  	/* inform PCU of the change */
> > >  	mutex_lock(&dev_priv->pcu_lock);
> > > -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> > > +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> > > +				cdclk_state->voltage);
> > >  	mutex_unlock(&dev_priv->pcu_lock);
> > >  
> > >  	intel_update_cdclk(dev_priv);
> > > @@ -1097,6 +1119,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
> > >  	if (cdclk_state.vco == 0)
> > >  		cdclk_state.vco = 8100000;
> > >  	cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco);
> > > +	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
> > >  
> > >  	skl_set_cdclk(dev_priv, &cdclk_state);
> > >  }
> > > @@ -1114,6 +1137,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
> > >  
> > >  	cdclk_state.cdclk = cdclk_state.ref;
> > >  	cdclk_state.vco = 0;
> > > +	cdclk_state.voltage = skl_calc_voltage(cdclk_state.cdclk);
> > >  
> > >  	skl_set_cdclk(dev_priv, &cdclk_state);
> > >  }
> > > @@ -1970,12 +1994,14 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
> > >  
> > >  	intel_state->cdclk.logical.vco = vco;
> > >  	intel_state->cdclk.logical.cdclk = cdclk;
> > > +	intel_state->cdclk.logical.voltage = skl_calc_voltage(cdclk);
> > >  
> > >  	if (!intel_state->active_crtcs) {
> > >  		cdclk = skl_calc_cdclk(0, vco);
> > >  
> > >  		intel_state->cdclk.actual.vco = vco;
> > >  		intel_state->cdclk.actual.cdclk = cdclk;
> > > +		intel_state->cdclk.actual.voltage = skl_calc_voltage(cdclk);
> > >  	} else {
> > >  		intel_state->cdclk.actual =
> > >  			intel_state->cdclk.logical;
> > > -- 
> > > 2.13.6
> > > 
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v2 4/8] drm/i915: Use cdclk_state->voltage on BDW
  2017-10-20 17:03   ` [PATCH v2 " Ville Syrjala
@ 2017-10-20 20:47     ` Rodrigo Vivi
  0 siblings, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-20 20:47 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Fri, Oct 20, 2017 at 05:03:58PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Track the system agent voltage we request from pcode in the cdclk state
> on BDW. Annoyingly we can't actually read out the current value since
> there's no pcode command to do that, so we'll have to just assume that
> it worked.
> 
> v2: Keep the WARN_ON (Rodrigo)

thanks

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 32 ++++++++++++++++++++++++++------
>  1 file changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index e2f18545d20c..ab0481183bae 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -639,6 +639,21 @@ static int bdw_calc_cdclk(int min_cdclk)
>  		return 337500;
>  }
>  
> +static u8 bdw_calc_voltage(int cdclk)
> +{
> +	switch (cdclk) {
> +	default:
> +	case 337500:
> +		return 2;
> +	case 450000:
> +		return 0;
> +	case 540000:
> +		return 1;
> +	case 675000:
> +		return 3;
> +	}
> +}
> +
>  static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
>  			  struct intel_cdclk_state *cdclk_state)
>  {
> @@ -657,13 +672,19 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
>  		cdclk_state->cdclk = 337500;
>  	else
>  		cdclk_state->cdclk = 675000;
> +
> +	/*
> +	 * Can't read this out :( Let's assume it's
> +	 * at least what the CDCLK frequency requires.
> +	 */
> +	cdclk_state->voltage = bdw_calc_voltage(cdclk_state->cdclk);
>  }
>  
>  static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
>  			  const struct intel_cdclk_state *cdclk_state)
>  {
>  	int cdclk = cdclk_state->cdclk;
> -	uint32_t val, data;
> +	uint32_t val;
>  	int ret;
>  
>  	if (WARN((I915_READ(LCPLL_CTL) &
> @@ -704,19 +725,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
>  		/* fall through */
>  	case 337500:
>  		val |= LCPLL_CLK_FREQ_337_5_BDW;
> -		data = 2;
>  		break;
>  	case 450000:
>  		val |= LCPLL_CLK_FREQ_450;
> -		data = 0;
>  		break;
>  	case 540000:
>  		val |= LCPLL_CLK_FREQ_54O_BDW;
> -		data = 1;
>  		break;
>  	case 675000:
>  		val |= LCPLL_CLK_FREQ_675_BDW;
> -		data = 3;
>  		break;
>  	}
>  
> @@ -731,7 +748,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
>  		DRM_ERROR("Switching back to LCPLL failed\n");
>  
>  	mutex_lock(&dev_priv->pcu_lock);
> -	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
> +	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
> +				cdclk_state->voltage);
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
> @@ -1910,11 +1928,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
>  	cdclk = bdw_calc_cdclk(min_cdclk);
>  
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage = bdw_calc_voltage(cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = bdw_calc_cdclk(0);
>  
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage = bdw_calc_voltage(cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 6/8] drm/i915: Use cdclk_state->voltage on BXT/GLK
  2017-10-18 20:48 ` [PATCH 6/8] drm/i915: Use cdclk_state->voltage on BXT/GLK Ville Syrjala
@ 2017-10-20 20:51   ` Rodrigo Vivi
  0 siblings, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-20 20:51 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 08:48:23PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Track the system agent voltage we request from pcode in the cdclk state
> on BXT/GLK. Annoyingly we can't actually read out the current value since
> there's no pcode command to do that, so we'll have to just assume that
> it worked.
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 6f7b5abe6e3f..1b4dcd9689da 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1166,6 +1166,11 @@ static int glk_calc_cdclk(int min_cdclk)
>  		return 79200;
>  }
>  
> +static u8 bxt_calc_voltage(int cdclk)
> +{
> +	return DIV_ROUND_UP(cdclk, 25000);
> +}
> +
>  static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
>  {
>  	int ratio;
> @@ -1242,7 +1247,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
>  	cdclk_state->cdclk = cdclk_state->ref;
>  
>  	if (cdclk_state->vco == 0)
> -		return;
> +		goto out;
>  
>  	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
>  
> @@ -1266,6 +1271,13 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
>  	}
>  
>  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> +
> + out:
> +	/*
> +	 * Can't read this out :( Let's assume it's
> +	 * at least what the CDCLK frequency requires.
> +	 */
> +	cdclk_state->voltage = bxt_calc_voltage(cdclk_state->cdclk);
>  }
>  
>  static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
> @@ -1368,7 +1380,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
>  
>  	mutex_lock(&dev_priv->pcu_lock);
>  	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
> -				      DIV_ROUND_UP(cdclk, 25000));
> +				      cdclk_state->voltage);
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	if (ret) {
> @@ -1460,6 +1472,7 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv)
>  		cdclk_state.cdclk = bxt_calc_cdclk(0);
>  		cdclk_state.vco = bxt_de_pll_vco(dev_priv, cdclk_state.cdclk);
>  	}
> +	cdclk_state.voltage = bxt_calc_voltage(cdclk_state.cdclk);
>  
>  	bxt_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -1477,6 +1490,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
>  
>  	cdclk_state.cdclk = cdclk_state.ref;
>  	cdclk_state.vco = 0;
> +	cdclk_state.voltage = bxt_calc_voltage(cdclk_state.cdclk);
>  
>  	bxt_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -2030,6 +2044,7 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage = bxt_calc_voltage(cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		if (IS_GEMINILAKE(dev_priv)) {
> @@ -2042,6 +2057,7 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  		intel_state->cdclk.actual.vco = vco;
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage = bxt_calc_voltage(cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 20:36           ` Rodrigo Vivi
@ 2017-10-20 21:44             ` Runyan, Arthur J
  2017-10-23 12:03               ` Ville Syrjälä
  2017-10-23 11:48             ` Ville Syrjälä
  1 sibling, 1 reply; 58+ messages in thread
From: Runyan, Arthur J @ 2017-10-20 21:44 UTC (permalink / raw)
  To: Vivi, Rodrigo, Ville Syrjälä; +Cc: intel-gfx

If you know which direction voltage is moving, then you can optimize.  Nobody snooping PLL.  Really only the DVFS post sequence is needed, placed either before or after the clock programming, depending on whether voltage is increasing or decreasing.  But you shouldn't optimize that far since nobody is validating it that way.
You do want to lower voltage to save power.

-----Original Message-----
From: Vivi, Rodrigo 
Sent: Friday, 20 October, 2017 1:37 PM
To: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Runyan, Arthur J <arthur.j.runyan@intel.com>; intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>
Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports

On Fri, Oct 20, 2017 at 08:07:07PM +0000, Ville Syrjälä wrote:
> On Fri, Oct 20, 2017 at 05:48:54PM +0000, Runyan, Arthur J wrote:
> > Sorry about top reply from corporate email...
> > If you know in advance that you will just be temporarily disabling the PLL, then your sequence works. 
> 
> Actually we would end up using this sequence even if disable the PLL for
> good.
> 
> Eg. if we're just disabling the entire pipe+DPLL, we'd do this (assuming
> cdclk doesn't need changing, but voltage can be lowered due to the port
> no longer requiring it):
> 1. disable DPLL
> 2. disable DPLL power
> ...
> 3. DVFS pre sequence
> 4. DVFS post sequence
> 
> And when starting up a pipe from the cold with a new DPLL we'd conversly
> do this (again assuming no cdclk change, but voltage would have to be
> ramped up for the port):
> 1. DVFS pre sequence
> 2. DVFS post sequence
> ...
> 3. enable DPLL power
> 4. enable DPLL
> 
> It does look a bit strange doing the DVFS sequences on their own like
> that, but I don't see why that should be problem. From where I'm sitting
> it doesn't really look any different than the following seqeunces:
> 
> Disable with cdclk changing but port clock not having any effect
> on the voltage:
> 1. disable DPLL
> 2. disable DPLL power
> ...
> 3. DVFS pre sequence
> 4. change cdclk
> 5. DVFS post sequence
> 
> Enable with cdclk changing but port clock not having any effect
> on the voltage:
> 1. DVFS pre sequence
> 2. change cdclk
> 3. DVFS post sequence
> ...
> 4. enable DPLL power
> 5. enable DPLL
> 
> So unless something is snooping the actual state of the DPLLs, and based
> on that second guessing our choice of voltage, I don't really see how
> these two cases differ at all.

Well, I admit that I'm kind of lost on the discussion now.

but spec tells that we need use pre and post DVFS sequence
always on CDCLK part and on DPLL only "If the frequency will result in a
change to the voltage requirement,"
So in the temporary disable-re-enable case we would be safe, because
there woulnd't be no need to keep tweaking the voltage...

However on the other case you mentioned for the full pipe disable
it seems that we have a situation of non optimal power getting
wasted, right?!

Any idea how to solve that in the atomic way?
Maybe caching the global min voltage required outside cdclk struct
in a place where we can have access from both cdclk and pll state?

> 
> > 
> > -----Original Message-----
> > From: Ville Syrjälä [mailto:ville.syrjala@linux.intel.com] 
> > Sent: Friday, 20 October, 2017 4:12 AM
> > To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > Cc: intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>; Runyan, Arthur J <arthur.j.runyan@intel.com>
> > Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
> > 
> > On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> > > 
> > > On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > 
> > > > On CNL we may need to bump up the system agent voltage not only due
> > > > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > > > To that end start tracking the minimum acceptable voltage for each crtc.
> > > > We do the tracking via crtcs because we don't have any kind of encoder
> > > > state. Also there's no downside to doing it this way, and it matches how
> > > > we track cdclk requirements on account of pixel rate.
> > > > 
> > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > 
> > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > 
> > > Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > (Although I didn't find cases where I could force a higher voltage level,
> > > everything works well on CNL with this.)
> > 
> > I went and actually read the spec now :) so I can now see that this
> > doesn't really match the sequence listed in the spec.
> > 
> > For example, let's assume we have a modeset where we have to disable
> > a DPLL, change CDCLK, and finally enable a DPLL again.
> > 
> > What the spec says we should do is something like this:
> > 1.  DVFS pre sequence
> > 2.  disable DPLL
> > 3.  DVFS post sequence
> > 4.  disable DPLL power
> > ...
> > 5.  DVFS pre sequence
> > 6.  configure CDCLK_CTL
> > 7.  DVFS post sequence
> > ...
> > 8.  enable DPLL power
> > 9.  DVFS pre sequence
> > 10. enable DPLL
> > 11. DVFS post sequence
> > 
> > With my code what we'd end up doing is this instead:
> > 1. disable DPLL
> > 2. disable DPLL power
> > ...
> > 3. DVFS pre sequence
> > 4. configure CDCLK_CTL
> > 5. DVFS post sequence
> > ...
> > 6. enable DPLL power
> > 7. enable DPLL
> > 
> > So my way always results in running the DVFS sequences at most once.
> > With the way the spec has things listed we might have to run the
> > sequences multiple times. 
> > 
> > Art, is there a good reason why we'd actually have to run the
> > DVFS sequences around each DPLL_ENABLE write, instead of just
> > doing it once at any point between disabling and enabling
> > DPLLs?
> > 
> > -- 
> > Ville Syrjälä
> > Intel OTC
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 20:36           ` Rodrigo Vivi
  2017-10-20 21:44             ` Runyan, Arthur J
@ 2017-10-23 11:48             ` Ville Syrjälä
  1 sibling, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-23 11:48 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx, Runyan, Arthur J

On Fri, Oct 20, 2017 at 01:36:42PM -0700, Rodrigo Vivi wrote:
> On Fri, Oct 20, 2017 at 08:07:07PM +0000, Ville Syrjälä wrote:
> > On Fri, Oct 20, 2017 at 05:48:54PM +0000, Runyan, Arthur J wrote:
> > > Sorry about top reply from corporate email...
> > > If you know in advance that you will just be temporarily disabling the PLL, then your sequence works. 
> > 
> > Actually we would end up using this sequence even if disable the PLL for
> > good.
> > 
> > Eg. if we're just disabling the entire pipe+DPLL, we'd do this (assuming
> > cdclk doesn't need changing, but voltage can be lowered due to the port
> > no longer requiring it):
> > 1. disable DPLL
> > 2. disable DPLL power
> > ...
> > 3. DVFS pre sequence
> > 4. DVFS post sequence
> > 
> > And when starting up a pipe from the cold with a new DPLL we'd conversly
> > do this (again assuming no cdclk change, but voltage would have to be
> > ramped up for the port):
> > 1. DVFS pre sequence
> > 2. DVFS post sequence
> > ...
> > 3. enable DPLL power
> > 4. enable DPLL
> > 
> > It does look a bit strange doing the DVFS sequences on their own like
> > that, but I don't see why that should be problem. From where I'm sitting
> > it doesn't really look any different than the following seqeunces:
> > 
> > Disable with cdclk changing but port clock not having any effect
> > on the voltage:
> > 1. disable DPLL
> > 2. disable DPLL power
> > ...
> > 3. DVFS pre sequence
> > 4. change cdclk
> > 5. DVFS post sequence
> > 
> > Enable with cdclk changing but port clock not having any effect
> > on the voltage:
> > 1. DVFS pre sequence
> > 2. change cdclk
> > 3. DVFS post sequence
> > ...
> > 4. enable DPLL power
> > 5. enable DPLL
> > 
> > So unless something is snooping the actual state of the DPLLs, and based
> > on that second guessing our choice of voltage, I don't really see how
> > these two cases differ at all.
> 
> Well, I admit that I'm kind of lost on the discussion now.
> 
> but spec tells that we need use pre and post DVFS sequence
> always on CDCLK part and on DPLL only "If the frequency will result in a
> change to the voltage requirement,"
> So in the temporary disable-re-enable case we would be safe, because
> there woulnd't be no need to keep tweaking the voltage...
> 
> However on the other case you mentioned for the full pipe disable
> it seems that we have a situation of non optimal power getting
> wasted, right?!

No. The voltage will be reduced, but only after all relevant DPLLs have
been disabled. And conversly the voltage will be increased before any
relevant DPLLs will be enabled. So instead of talking to pcode around
the actual DPLL enable/disable register writes we do it well before/after
we touch the DPLL(s).

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 21:44             ` Runyan, Arthur J
@ 2017-10-23 12:03               ` Ville Syrjälä
  0 siblings, 0 replies; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-23 12:03 UTC (permalink / raw)
  To: Runyan, Arthur J; +Cc: intel-gfx, Vivi, Rodrigo

On Fri, Oct 20, 2017 at 09:44:53PM +0000, Runyan, Arthur J wrote:
> If you know which direction voltage is moving, then you can optimize.  Nobody snooping PLL.  Really only the DVFS post sequence is needed, placed either before or after the clock programming, depending on whether voltage is increasing or decreasing.  But you shouldn't optimize that far since nobody is validating it that way.
> You do want to lower voltage to save power.

OK, so it looks like what I had in mind will work pefectly fine then.

And it's good that you mentioned the validation angle. We'll definitely
want to stick to using both the pre and post sequences just to be on the
safe side.

Thanks Art.

> 
> -----Original Message-----
> From: Vivi, Rodrigo 
> Sent: Friday, 20 October, 2017 1:37 PM
> To: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Runyan, Arthur J <arthur.j.runyan@intel.com>; intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>
> Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
> 
> On Fri, Oct 20, 2017 at 08:07:07PM +0000, Ville Syrjälä wrote:
> > On Fri, Oct 20, 2017 at 05:48:54PM +0000, Runyan, Arthur J wrote:
> > > Sorry about top reply from corporate email...
> > > If you know in advance that you will just be temporarily disabling the PLL, then your sequence works. 
> > 
> > Actually we would end up using this sequence even if disable the PLL for
> > good.
> > 
> > Eg. if we're just disabling the entire pipe+DPLL, we'd do this (assuming
> > cdclk doesn't need changing, but voltage can be lowered due to the port
> > no longer requiring it):
> > 1. disable DPLL
> > 2. disable DPLL power
> > ...
> > 3. DVFS pre sequence
> > 4. DVFS post sequence
> > 
> > And when starting up a pipe from the cold with a new DPLL we'd conversly
> > do this (again assuming no cdclk change, but voltage would have to be
> > ramped up for the port):
> > 1. DVFS pre sequence
> > 2. DVFS post sequence
> > ...
> > 3. enable DPLL power
> > 4. enable DPLL
> > 
> > It does look a bit strange doing the DVFS sequences on their own like
> > that, but I don't see why that should be problem. From where I'm sitting
> > it doesn't really look any different than the following seqeunces:
> > 
> > Disable with cdclk changing but port clock not having any effect
> > on the voltage:
> > 1. disable DPLL
> > 2. disable DPLL power
> > ...
> > 3. DVFS pre sequence
> > 4. change cdclk
> > 5. DVFS post sequence
> > 
> > Enable with cdclk changing but port clock not having any effect
> > on the voltage:
> > 1. DVFS pre sequence
> > 2. change cdclk
> > 3. DVFS post sequence
> > ...
> > 4. enable DPLL power
> > 5. enable DPLL
> > 
> > So unless something is snooping the actual state of the DPLLs, and based
> > on that second guessing our choice of voltage, I don't really see how
> > these two cases differ at all.
> 
> Well, I admit that I'm kind of lost on the discussion now.
> 
> but spec tells that we need use pre and post DVFS sequence
> always on CDCLK part and on DPLL only "If the frequency will result in a
> change to the voltage requirement,"
> So in the temporary disable-re-enable case we would be safe, because
> there woulnd't be no need to keep tweaking the voltage...
> 
> However on the other case you mentioned for the full pipe disable
> it seems that we have a situation of non optimal power getting
> wasted, right?!
> 
> Any idea how to solve that in the atomic way?
> Maybe caching the global min voltage required outside cdclk struct
> in a place where we can have access from both cdclk and pll state?
> 
> > 
> > > 
> > > -----Original Message-----
> > > From: Ville Syrjälä [mailto:ville.syrjala@linux.intel.com] 
> > > Sent: Friday, 20 October, 2017 4:12 AM
> > > To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > > Cc: intel-gfx@lists.freedesktop.org; Kahola, Mika <mika.kahola@intel.com>; Navare, Manasi D <manasi.d.navare@intel.com>; Runyan, Arthur J <arthur.j.runyan@intel.com>
> > > Subject: Re: [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
> > > 
> > > On Thu, Oct 19, 2017 at 04:54:56PM -0700, Rodrigo Vivi wrote:
> > > > 
> > > > On Wed, Oct 18, 2017 at 08:48:25PM +0000, Ville Syrjala wrote:
> > > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > 
> > > > > On CNL we may need to bump up the system agent voltage not only due
> > > > > to CDCLK but also when driving DDI port with a sufficiently high clock.
> > > > > To that end start tracking the minimum acceptable voltage for each crtc.
> > > > > We do the tracking via crtcs because we don't have any kind of encoder
> > > > > state. Also there's no downside to doing it this way, and it matches how
> > > > > we track cdclk requirements on account of pixel rate.
> > > > > 
> > > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > 
> > > > 
> > > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > 
> > > > Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > (Although I didn't find cases where I could force a higher voltage level,
> > > > everything works well on CNL with this.)
> > > 
> > > I went and actually read the spec now :) so I can now see that this
> > > doesn't really match the sequence listed in the spec.
> > > 
> > > For example, let's assume we have a modeset where we have to disable
> > > a DPLL, change CDCLK, and finally enable a DPLL again.
> > > 
> > > What the spec says we should do is something like this:
> > > 1.  DVFS pre sequence
> > > 2.  disable DPLL
> > > 3.  DVFS post sequence
> > > 4.  disable DPLL power
> > > ...
> > > 5.  DVFS pre sequence
> > > 6.  configure CDCLK_CTL
> > > 7.  DVFS post sequence
> > > ...
> > > 8.  enable DPLL power
> > > 9.  DVFS pre sequence
> > > 10. enable DPLL
> > > 11. DVFS post sequence
> > > 
> > > With my code what we'd end up doing is this instead:
> > > 1. disable DPLL
> > > 2. disable DPLL power
> > > ...
> > > 3. DVFS pre sequence
> > > 4. configure CDCLK_CTL
> > > 5. DVFS post sequence
> > > ...
> > > 6. enable DPLL power
> > > 7. enable DPLL
> > > 
> > > So my way always results in running the DVFS sequences at most once.
> > > With the way the spec has things listed we might have to run the
> > > sequences multiple times. 
> > > 
> > > Art, is there a good reason why we'd actually have to run the
> > > DVFS sequences around each DPLL_ENABLE write, instead of just
> > > doing it once at any point between disabling and enabling
> > > DPLLs?
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel OTC
> > 
> > -- 
> > Ville Syrjälä
> > Intel OTC

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state
  2017-10-20 20:43     ` Rodrigo Vivi
@ 2017-10-23 12:13       ` Ville Syrjälä
  2017-10-23 17:14         ` Rodrigo Vivi
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2017-10-23 12:13 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Fri, Oct 20, 2017 at 01:43:51PM -0700, Rodrigo Vivi wrote:
> On Fri, Oct 20, 2017 at 02:01:37PM +0000, Ville Syrjälä wrote:
> > On Wed, Oct 18, 2017 at 11:48:19PM +0300, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > For CNL we'll need to start considering the port clocks when we select
> > > the voltage level for the system agent. To that end start tracking the
> > > voltage in the cdclk state (since that already has to adjust it).
> > > 
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h         |  1 +
> > >  drivers/gpu/drm/i915/intel_cdclk.c      | 31 ++++++++++++++++++++++++-------
> > >  drivers/gpu/drm/i915/intel_display.c    |  8 ++++----
> > >  drivers/gpu/drm/i915/intel_drv.h        |  4 +++-
> > >  drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++-
> > >  5 files changed, 34 insertions(+), 13 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index f01c80076c59..d3ac58dc275f 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -2227,6 +2227,7 @@ struct i915_oa_ops {
> > >  
> > >  struct intel_cdclk_state {
> > >  	unsigned int cdclk, vco, ref;
> > > +	u8 voltage;
> > 
> > BTW now that I decided to abuse this for all platforms the name
> > "voltage" might not be entirely accurate anymore. Especially on VLV/CHV
> > the DSPFREQUAR value isn't directly a voltage value, but instead a
> > request to punit to change the cdclk frequency to a specific value.
> > Although naturally punit will also make sure the voltage will be
> > set sufficiently high as well.
> > 
> > So I'm not entirely sure we want to call it "voltage" anymore. Something
> > abstract like "level" is also what came to mind when I was thingking
> > about this. If anyone is irked by "voltage" and would like to see
> > something different there, let me know. Otherwise I think I might just
> > leave it as is for now.
> 
> I honestly prefer "dvfs_level", voltage_level or anything_level.

I think voltage_level makes a ton of sense, and looks like that's
actually what the CNL spec calls it as well (at least in some places).
While still not 100% accurate for VLV/CHV I suppose, I think it's more
clear than just "level" for more recent platforms.

Any objections to "voltage_level"?

> 
> Even if on VLV/CHV if it was also voltage related and not
> frequency related. It is strange for my brain to read
> voltage 1,2,3... my poor braing automatically reads 1V, 2V, 3V!
> So level would be better imho.
> 
> But it is up to you.
> 
> > 
> > >  };
> > >  
> > >  struct drm_i915_private {
> > > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > > index 4bffd31a8924..522222f8bb50 100644
> > > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > > @@ -1690,17 +1690,34 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
> > >  }
> > >  
> > >  /**
> > > - * intel_cdclk_state_compare - Determine if two CDCLK states differ
> > > + * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes
> > >   * @a: first CDCLK state
> > >   * @b: second CDCLK state
> > >   *
> > >   * Returns:
> > > - * True if the CDCLK states are identical, false if they differ.
> > > + * True if the CDCLK states require pipes to be off during reprogramming, false if not.
> > >   */
> > > -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > > +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
> > >  			       const struct intel_cdclk_state *b)
> > >  {
> > > -	return memcmp(a, b, sizeof(*a)) == 0;
> > > +	return a->cdclk != b->cdclk ||
> > > +		a->vco != b->vco ||
> > > +		a->ref != b->ref;
> > > +}
> > > +
> > > +/**
> > > + * intel_cdclk_changed - Determine if two CDCLK states are different
> > > + * @a: first CDCLK state
> > > + * @b: second CDCLK state
> > > + *
> > > + * Returns:
> > > + * True if the CDCLK states don't match, false if they do.
> > > + */
> > > +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> > > +			 const struct intel_cdclk_state *b)
> > > +{
> > > +	return intel_cdclk_needs_modeset(a, b) ||
> > > +		a->voltage != b->voltage;
> > >  }
> > >  
> > >  /**
> > > @@ -1714,15 +1731,15 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > >  void intel_set_cdclk(struct drm_i915_private *dev_priv,
> > >  		     const struct intel_cdclk_state *cdclk_state)
> > >  {
> > > -	if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state))
> > > +	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state))
> > >  		return;
> > >  
> > >  	if (WARN_ON_ONCE(!dev_priv->display.set_cdclk))
> > >  		return;
> > >  
> > > -	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n",
> > > +	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz, voltage %d\n",
> > >  			 cdclk_state->cdclk, cdclk_state->vco,
> > > -			 cdclk_state->ref);
> > > +			 cdclk_state->ref, cdclk_state->voltage);
> > >  
> > >  	dev_priv->display.set_cdclk(dev_priv, cdclk_state);
> > >  }
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > index bd62c0a65bcd..32e7cca52da2 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -11946,16 +11946,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
> > >  		 * holding all the crtc locks, even if we don't end up
> > >  		 * touching the hardware
> > >  		 */
> > > -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
> > > -					       &intel_state->cdclk.logical)) {
> > > +		if (intel_cdclk_changed(&dev_priv->cdclk.logical,
> > > +					&intel_state->cdclk.logical)) {
> > >  			ret = intel_lock_all_pipes(state);
> > >  			if (ret < 0)
> > >  				return ret;
> > >  		}
> > >  
> > >  		/* All pipes must be switched off while we change the cdclk. */
> > > -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
> > > -					       &intel_state->cdclk.actual)) {
> > > +		if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual,
> > > +					      &intel_state->cdclk.actual)) {
> > >  			ret = intel_modeset_all_pipes(state);
> > >  			if (ret < 0)
> > >  				return ret;
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index a05ab3a1ab27..765a737700c5 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -1324,8 +1324,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
> > >  void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
> > >  void intel_update_cdclk(struct drm_i915_private *dev_priv);
> > >  void intel_update_rawclk(struct drm_i915_private *dev_priv);
> > > -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > > +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
> > >  			       const struct intel_cdclk_state *b);
> > > +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> > > +			 const struct intel_cdclk_state *b);
> > >  void intel_set_cdclk(struct drm_i915_private *dev_priv,
> > >  		     const struct intel_cdclk_state *cdclk_state);
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > > index 8af286c63d3b..5ac553fab7c7 100644
> > > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > > @@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
> > >  	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
> > >  
> > >  	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
> > > -	WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
> > > +	/* Can't read out the voltage so can't use intel_cdclk_changed() */
> > > +	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
> > >  
> > >  	gen9_assert_dbuf_enabled(dev_priv);
> > >  
> > > -- 
> > > 2.13.6
> > 
> > -- 
> > Ville Syrjälä
> > Intel OTC

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state
  2017-10-23 12:13       ` Ville Syrjälä
@ 2017-10-23 17:14         ` Rodrigo Vivi
  0 siblings, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-23 17:14 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Oct 23, 2017 at 12:13:46PM +0000, Ville Syrjälä wrote:
> On Fri, Oct 20, 2017 at 01:43:51PM -0700, Rodrigo Vivi wrote:
> > On Fri, Oct 20, 2017 at 02:01:37PM +0000, Ville Syrjälä wrote:
> > > On Wed, Oct 18, 2017 at 11:48:19PM +0300, Ville Syrjala wrote:
> > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > 
> > > > For CNL we'll need to start considering the port clocks when we select
> > > > the voltage level for the system agent. To that end start tracking the
> > > > voltage in the cdclk state (since that already has to adjust it).
> > > > 
> > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/i915_drv.h         |  1 +
> > > >  drivers/gpu/drm/i915/intel_cdclk.c      | 31 ++++++++++++++++++++++++-------
> > > >  drivers/gpu/drm/i915/intel_display.c    |  8 ++++----
> > > >  drivers/gpu/drm/i915/intel_drv.h        |  4 +++-
> > > >  drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++-
> > > >  5 files changed, 34 insertions(+), 13 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > > index f01c80076c59..d3ac58dc275f 100644
> > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > @@ -2227,6 +2227,7 @@ struct i915_oa_ops {
> > > >  
> > > >  struct intel_cdclk_state {
> > > >  	unsigned int cdclk, vco, ref;
> > > > +	u8 voltage;
> > > 
> > > BTW now that I decided to abuse this for all platforms the name
> > > "voltage" might not be entirely accurate anymore. Especially on VLV/CHV
> > > the DSPFREQUAR value isn't directly a voltage value, but instead a
> > > request to punit to change the cdclk frequency to a specific value.
> > > Although naturally punit will also make sure the voltage will be
> > > set sufficiently high as well.
> > > 
> > > So I'm not entirely sure we want to call it "voltage" anymore. Something
> > > abstract like "level" is also what came to mind when I was thingking
> > > about this. If anyone is irked by "voltage" and would like to see
> > > something different there, let me know. Otherwise I think I might just
> > > leave it as is for now.
> > 
> > I honestly prefer "dvfs_level", voltage_level or anything_level.
> 
> I think voltage_level makes a ton of sense, and looks like that's
> actually what the CNL spec calls it as well (at least in some places).
> While still not 100% accurate for VLV/CHV I suppose, I think it's more
> clear than just "level" for more recent platforms.
> 
> Any objections to "voltage_level"?

none from my side.
feel free to carry the rv-b on patches changing to new name.

> 
> > 
> > Even if on VLV/CHV if it was also voltage related and not
> > frequency related. It is strange for my brain to read
> > voltage 1,2,3... my poor braing automatically reads 1V, 2V, 3V!
> > So level would be better imho.
> > 
> > But it is up to you.
> > 
> > > 
> > > >  };
> > > >  
> > > >  struct drm_i915_private {
> > > > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> > > > index 4bffd31a8924..522222f8bb50 100644
> > > > --- a/drivers/gpu/drm/i915/intel_cdclk.c
> > > > +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> > > > @@ -1690,17 +1690,34 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
> > > >  }
> > > >  
> > > >  /**
> > > > - * intel_cdclk_state_compare - Determine if two CDCLK states differ
> > > > + * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes
> > > >   * @a: first CDCLK state
> > > >   * @b: second CDCLK state
> > > >   *
> > > >   * Returns:
> > > > - * True if the CDCLK states are identical, false if they differ.
> > > > + * True if the CDCLK states require pipes to be off during reprogramming, false if not.
> > > >   */
> > > > -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > > > +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
> > > >  			       const struct intel_cdclk_state *b)
> > > >  {
> > > > -	return memcmp(a, b, sizeof(*a)) == 0;
> > > > +	return a->cdclk != b->cdclk ||
> > > > +		a->vco != b->vco ||
> > > > +		a->ref != b->ref;
> > > > +}
> > > > +
> > > > +/**
> > > > + * intel_cdclk_changed - Determine if two CDCLK states are different
> > > > + * @a: first CDCLK state
> > > > + * @b: second CDCLK state
> > > > + *
> > > > + * Returns:
> > > > + * True if the CDCLK states don't match, false if they do.
> > > > + */
> > > > +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> > > > +			 const struct intel_cdclk_state *b)
> > > > +{
> > > > +	return intel_cdclk_needs_modeset(a, b) ||
> > > > +		a->voltage != b->voltage;
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -1714,15 +1731,15 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > > >  void intel_set_cdclk(struct drm_i915_private *dev_priv,
> > > >  		     const struct intel_cdclk_state *cdclk_state)
> > > >  {
> > > > -	if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state))
> > > > +	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state))
> > > >  		return;
> > > >  
> > > >  	if (WARN_ON_ONCE(!dev_priv->display.set_cdclk))
> > > >  		return;
> > > >  
> > > > -	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n",
> > > > +	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz, voltage %d\n",
> > > >  			 cdclk_state->cdclk, cdclk_state->vco,
> > > > -			 cdclk_state->ref);
> > > > +			 cdclk_state->ref, cdclk_state->voltage);
> > > >  
> > > >  	dev_priv->display.set_cdclk(dev_priv, cdclk_state);
> > > >  }
> > > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > > index bd62c0a65bcd..32e7cca52da2 100644
> > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > @@ -11946,16 +11946,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
> > > >  		 * holding all the crtc locks, even if we don't end up
> > > >  		 * touching the hardware
> > > >  		 */
> > > > -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
> > > > -					       &intel_state->cdclk.logical)) {
> > > > +		if (intel_cdclk_changed(&dev_priv->cdclk.logical,
> > > > +					&intel_state->cdclk.logical)) {
> > > >  			ret = intel_lock_all_pipes(state);
> > > >  			if (ret < 0)
> > > >  				return ret;
> > > >  		}
> > > >  
> > > >  		/* All pipes must be switched off while we change the cdclk. */
> > > > -		if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
> > > > -					       &intel_state->cdclk.actual)) {
> > > > +		if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual,
> > > > +					      &intel_state->cdclk.actual)) {
> > > >  			ret = intel_modeset_all_pipes(state);
> > > >  			if (ret < 0)
> > > >  				return ret;
> > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > > index a05ab3a1ab27..765a737700c5 100644
> > > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > > @@ -1324,8 +1324,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
> > > >  void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
> > > >  void intel_update_cdclk(struct drm_i915_private *dev_priv);
> > > >  void intel_update_rawclk(struct drm_i915_private *dev_priv);
> > > > -bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
> > > > +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a,
> > > >  			       const struct intel_cdclk_state *b);
> > > > +bool intel_cdclk_changed(const struct intel_cdclk_state *a,
> > > > +			 const struct intel_cdclk_state *b);
> > > >  void intel_set_cdclk(struct drm_i915_private *dev_priv,
> > > >  		     const struct intel_cdclk_state *cdclk_state);
> > > >  
> > > > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > > > index 8af286c63d3b..5ac553fab7c7 100644
> > > > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > > > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > > > @@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
> > > >  	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
> > > >  
> > > >  	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
> > > > -	WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
> > > > +	/* Can't read out the voltage so can't use intel_cdclk_changed() */
> > > > +	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
> > > >  
> > > >  	gen9_assert_dbuf_enabled(dev_priv);
> > > >  
> > > > -- 
> > > > 2.13.6
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel OTC
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL
  2017-10-18 20:48 ` [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL Ville Syrjala
  2017-10-18 21:50   ` Rodrigo Vivi
@ 2017-10-23 18:29   ` Rodrigo Vivi
  1 sibling, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-23 18:29 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Oct 18, 2017 at 08:48:24PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Track the system agent voltage we request from pcode in the cdclk state
> on CNL. Annoyingly we can't actually read out the current value since
> there's no pcode command to do that, so we'll have to just assume that
> it worked.
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(even with new v with voltage_level name)

Thanks for all explanations and discussions, this seems the
right approach.

> ---
>  drivers/gpu/drm/i915/intel_cdclk.c | 44 ++++++++++++++++++++++++--------------
>  1 file changed, 28 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 1b4dcd9689da..795a18f64c4c 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1505,6 +1505,19 @@ static int cnl_calc_cdclk(int min_cdclk)
>  		return 168000;
>  }
>  
> +static u8 cnl_calc_voltage(int cdclk)
> +{
> +	switch (cdclk) {
> +	default:
> +	case 168000:
> +		return 0;
> +	case 336000:
> +		return 1;
> +	case 528000:
> +		return 2;
> +	}
> +}
> +
>  static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
>  				 struct intel_cdclk_state *cdclk_state)
>  {
> @@ -1538,7 +1551,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>  	cdclk_state->cdclk = cdclk_state->ref;
>  
>  	if (cdclk_state->vco == 0)
> -		return;
> +		goto out;
>  
>  	divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
>  
> @@ -1555,6 +1568,13 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
>  	}
>  
>  	cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
> +
> + out:
> +	/*
> +	 * Can't read this out :( Let's assume it's
> +	 * at least what the CDCLK frequency requires.
> +	 */
> +	cdclk_state->voltage = cnl_calc_voltage(cdclk_state->cdclk);
>  }
>  
>  static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
> @@ -1595,7 +1615,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  {
>  	int cdclk = cdclk_state->cdclk;
>  	int vco = cdclk_state->vco;
> -	u32 val, divider, pcu_ack;
> +	u32 val, divider;
>  	int ret;
>  
>  	mutex_lock(&dev_priv->pcu_lock);
> @@ -1624,19 +1644,6 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  		break;
>  	}
>  
> -	switch (cdclk) {
> -	case 528000:
> -		pcu_ack = 2;
> -		break;
> -	case 336000:
> -		pcu_ack = 1;
> -		break;
> -	case 168000:
> -	default:
> -		pcu_ack = 0;
> -		break;
> -	}
> -
>  	if (dev_priv->cdclk.hw.vco != 0 &&
>  	    dev_priv->cdclk.hw.vco != vco)
>  		cnl_cdclk_pll_disable(dev_priv);
> @@ -1654,7 +1661,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  
>  	/* inform PCU of the change */
>  	mutex_lock(&dev_priv->pcu_lock);
> -	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
> +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> +				cdclk_state->voltage);
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	intel_update_cdclk(dev_priv);
> @@ -1747,6 +1755,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv)
>  
>  	cdclk_state.cdclk = cnl_calc_cdclk(0);
>  	cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk);
> +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
>  
>  	cnl_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -1764,6 +1773,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
>  
>  	cdclk_state.cdclk = cdclk_state.ref;
>  	cdclk_state.vco = 0;
> +	cdclk_state.voltage = cnl_calc_voltage(cdclk_state.cdclk);
>  
>  	cnl_set_cdclk(dev_priv, &cdclk_state);
>  }
> @@ -2081,6 +2091,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> +	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = cnl_calc_cdclk(0);
> @@ -2088,6 +2099,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  		intel_state->cdclk.actual.vco = vco;
>  		intel_state->cdclk.actual.cdclk = cdclk;
> +		intel_state->cdclk.actual.voltage = cnl_calc_voltage(cdclk);
>  	} else {
>  		intel_state->cdclk.actual =
>  			intel_state->cdclk.logical;
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports
  2017-10-20 17:05   ` [PATCH v3 " Ville Syrjala
@ 2017-10-23 18:39     ` Rodrigo Vivi
  0 siblings, 0 replies; 58+ messages in thread
From: Rodrigo Vivi @ 2017-10-23 18:39 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Fri, Oct 20, 2017 at 05:05:40PM +0000, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> On CNL we may need to bump up the system agent voltage not only due
> to CDCLK but also when driving DDI port with a sufficiently high clock.
> To that end start tracking the minimum acceptable voltage for each crtc.
> We do the tracking via crtcs because we don't have any kind of encoder
> state. Also there's no downside to doing it this way, and it matches how
> we track cdclk requirements on account of pixel rate.
> 
> v2: Allow disabled crtcs to use the min voltage
>     Add IS_CNL check to intel_ddi_compute_min_voltage() since
>     we're using CNL specific values there
>     s/intel_compute_min_voltage/cnl_compute_min_voltage/ since
>     the function makes hw specific assumptions about the voltage
>     values
> v3: Drop the test hack leftovers from skl_modeset_calc_cdclk()
> 
> Cc: Mika Kahola <mika.kahola@intel.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  2 ++
>  drivers/gpu/drm/i915/intel_cdclk.c   | 46 +++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_ddi.c     | 11 +++++++++
>  drivers/gpu/drm/i915/intel_display.c |  9 +++++++
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  5 ++++
>  drivers/gpu/drm/i915/intel_drv.h     |  6 +++++
>  6 files changed, 78 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d3ac58dc275f..185711a852b0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2415,6 +2415,8 @@ struct drm_i915_private {
>  	unsigned int active_crtcs;
>  	/* minimum acceptable cdclk for each pipe */
>  	int min_cdclk[I915_MAX_PIPES];
> +	/* minimum acceptable voltage for each pipe */
> +	u8 min_voltage[I915_MAX_PIPES];
>  
>  	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
>  
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 2a0cc9aafa5a..0f5f2ce4bd3e 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1661,6 +1661,12 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
>  	intel_update_cdclk(dev_priv);
> +
> +	/*
> +	 * Can't read out the voltage :( So let's
> +	 * just assume everything is as expected.
> +	 */
> +	dev_priv->cdclk.hw.voltage = cdclk_state->voltage;
>  }
>  
>  static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
> @@ -1930,6 +1936,42 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
>  	return min_cdclk;
>  }
>  
> +/*
> + * Note that this functions assumes that 0 is
> + * the lowest voltage value, and higher values
> + * correspond to increasingly higher voltages.
> + *
> + * Should that relationship no longer hold on
> + * future platforms this code will need to be
> + * adjusted.
> + */
> +static u8 cnl_compute_min_voltage(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc *crtc;
> +	struct intel_crtc_state *crtc_state;
> +	u8 min_voltage;
> +	int i;
> +	enum pipe pipe;
> +
> +	memcpy(state->min_voltage, dev_priv->min_voltage,
> +	       sizeof(state->min_voltage));
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> +		if (crtc_state->base.enable)
> +			state->min_voltage[i] = crtc_state->min_voltage;
> +		else
> +			state->min_voltage[i] = 0;
> +	}
> +
> +	min_voltage = 0;
> +	for_each_pipe(dev_priv, pipe)
> +		min_voltage = max(state->min_voltage[pipe],
> +				  min_voltage);
> +
> +	return min_voltage;
> +}
> +
>  static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> @@ -2086,7 +2128,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  
>  	intel_state->cdclk.logical.vco = vco;
>  	intel_state->cdclk.logical.cdclk = cdclk;
> -	intel_state->cdclk.logical.voltage = cnl_calc_voltage(cdclk);
> +	intel_state->cdclk.logical.voltage =
> +		max(cnl_calc_voltage(cdclk),
> +		    cnl_compute_min_voltage(intel_state));
>  
>  	if (!intel_state->active_crtcs) {
>  		cdclk = cnl_calc_cdclk(0);
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index adf51b328844..f707134b4f65 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2525,6 +2525,13 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
>  	return false;
>  }
>  
> +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> +				   struct intel_crtc_state *crtc_state)
> +{
> +	if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000)
> +		crtc_state->min_voltage = 2;
> +}

Now we have this properly handled, should we remove on the same patch
all 4 "FIXME: (DVFS)" on dpll code? Maybe removing the entire comment
blocks with a smaller explanation that we handle that dvfs in a different
and atomic way.

one way or another, feel free to use:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> +
>  void intel_ddi_get_config(struct intel_encoder *encoder,
>  			  struct intel_crtc_state *pipe_config)
>  {
> @@ -2624,6 +2631,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	if (IS_GEN9_LP(dev_priv))
>  		pipe_config->lane_lat_optim_mask =
>  			bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
> +
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
>  }
>  
>  static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> @@ -2650,6 +2659,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
>  			bxt_ddi_phy_calc_lane_lat_optim_mask(encoder,
>  							     pipe_config->lane_count);
>  
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> +
>  	return ret;
>  
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 32e7cca52da2..83024956a74d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5938,6 +5938,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
>  
>  	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
>  	dev_priv->min_cdclk[intel_crtc->pipe] = 0;
> +	dev_priv->min_voltage[intel_crtc->pipe] = 0;
>  }
>  
>  /*
> @@ -11304,6 +11305,8 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
>  	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
>  	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
>  
> +	PIPE_CONF_CHECK_I(min_voltage);
> +
>  #undef PIPE_CONF_CHECK_X
>  #undef PIPE_CONF_CHECK_I
>  #undef PIPE_CONF_CHECK_P
> @@ -11964,6 +11967,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  		DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n",
>  			      intel_state->cdclk.logical.cdclk,
>  			      intel_state->cdclk.actual.cdclk);
> +		DRM_DEBUG_KMS("New voltage calculated to be logical %u, actual %u\n",
> +			      intel_state->cdclk.logical.voltage,
> +			      intel_state->cdclk.actual.voltage);
>  	} else {
>  		to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical;
>  	}
> @@ -12532,6 +12538,8 @@ static int intel_atomic_commit(struct drm_device *dev,
>  	if (intel_state->modeset) {
>  		memcpy(dev_priv->min_cdclk, intel_state->min_cdclk,
>  		       sizeof(intel_state->min_cdclk));
> +		memcpy(dev_priv->min_voltage, intel_state->min_voltage,
> +		       sizeof(intel_state->min_voltage));
>  		dev_priv->active_crtcs = intel_state->active_crtcs;
>  		dev_priv->cdclk.logical = intel_state->cdclk.logical;
>  		dev_priv->cdclk.actual = intel_state->cdclk.actual;
> @@ -15042,6 +15050,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		}
>  
>  		dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
> +		dev_priv->min_voltage[crtc->pipe] = crtc_state->min_voltage;
>  
>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 772521440a9f..6c1da88b5fef 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  					struct intel_crtc_state *pipe_config,
>  					struct drm_connector_state *conn_state)
>  {
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
>  	struct intel_digital_port *intel_dig_port = intel_mst->primary;
>  	struct intel_dp *intel_dp = &intel_dig_port->dp;
> @@ -87,6 +88,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  
>  	pipe_config->dp_m_n.tu = slots;
>  
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
> +
>  	return true;
>  }
>  
> @@ -307,6 +310,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
>  	intel_dp_get_m_n(crtc, pipe_config);
>  
>  	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
> +
> +	intel_ddi_compute_min_voltage(dev_priv, pipe_config);
>  }
>  
>  static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 765a737700c5..002894b13d69 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -386,6 +386,8 @@ struct intel_atomic_state {
>  	unsigned int active_crtcs;
>  	/* minimum acceptable cdclk for each pipe */
>  	int min_cdclk[I915_MAX_PIPES];
> +	/* minimum acceptable voltage for each pipe */
> +	u8 min_voltage[I915_MAX_PIPES];
>  
>  	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
>  
> @@ -739,6 +741,8 @@ struct intel_crtc_state {
>  	 */
>  	uint8_t lane_lat_optim_mask;
>  
> +	u8 min_voltage;
> +
>  	/* Panel fitter controls for gen2-gen4 + VLV */
>  	struct {
>  		u32 control;
> @@ -1294,6 +1298,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
>  			 struct intel_crtc_state *pipe_config);
>  void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
>  				    bool state);
> +void intel_ddi_compute_min_voltage(struct drm_i915_private *dev_priv,
> +				   struct intel_crtc_state *crtc_state);
>  u32 bxt_signal_levels(struct intel_dp *intel_dp);
>  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
>  u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
> -- 
> 2.13.6
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2017-10-23 18:39 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-18 20:48 [PATCH 0/8] drm/i915: CNL DVFS thing Ville Syrjala
2017-10-18 20:48 ` [PATCH 1/8] drm/i915: Clean up some cdclk switch statements Ville Syrjala
2017-10-19  7:20   ` Mika Kahola
2017-10-18 20:48 ` [PATCH 2/8] drm/i915: Start tracking voltage level in the cdclk state Ville Syrjala
2017-10-19 23:32   ` Rodrigo Vivi
2017-10-20 14:01   ` Ville Syrjälä
2017-10-20 20:43     ` Rodrigo Vivi
2017-10-23 12:13       ` Ville Syrjälä
2017-10-23 17:14         ` Rodrigo Vivi
2017-10-18 20:48 ` [PATCH 3/8] drm/i915: USe cdclk_state->voltage on VLV/CHV Ville Syrjala
2017-10-19 17:43   ` [PATCH v2 3/8] drm/i915: Use " Ville Syrjala
2017-10-19 23:42     ` Rodrigo Vivi
2017-10-20 16:20       ` Ville Syrjälä
2017-10-20 17:03   ` [PATCH v3 " Ville Syrjala
2017-10-18 20:48 ` [PATCH 4/8] drm/i915: Use cdclk_state->voltage on BDW Ville Syrjala
2017-10-19 23:44   ` Rodrigo Vivi
2017-10-20 16:14     ` Ville Syrjälä
2017-10-20 17:03   ` [PATCH v2 " Ville Syrjala
2017-10-20 20:47     ` Rodrigo Vivi
2017-10-18 20:48 ` [PATCH 5/8] drm/i915: Use cdclk_state->voltage on SKL/KBL/CFL Ville Syrjala
2017-10-19 23:47   ` Rodrigo Vivi
2017-10-20 11:18     ` Ville Syrjälä
2017-10-20 20:45       ` Rodrigo Vivi
2017-10-18 20:48 ` [PATCH 6/8] drm/i915: Use cdclk_state->voltage on BXT/GLK Ville Syrjala
2017-10-20 20:51   ` Rodrigo Vivi
2017-10-18 20:48 ` [PATCH 7/8] drm/i915: Use cdclk_state->voltage on CNL Ville Syrjala
2017-10-18 21:50   ` Rodrigo Vivi
2017-10-18 22:43     ` Rodrigo Vivi
2017-10-19 10:48     ` Ville Syrjälä
2017-10-19 10:56       ` Mika Kahola
2017-10-19 12:19         ` Ville Syrjälä
2017-10-19 23:52       ` Rodrigo Vivi
2017-10-23 18:29   ` Rodrigo Vivi
2017-10-18 20:48 ` [PATCH 8/8] drm/i915: Adjust system agent voltage on CNL if required by DDI ports Ville Syrjala
2017-10-19 23:54   ` Rodrigo Vivi
2017-10-20 11:11     ` Ville Syrjälä
2017-10-20 17:48       ` Runyan, Arthur J
2017-10-20 20:07         ` Ville Syrjälä
2017-10-20 20:36           ` Rodrigo Vivi
2017-10-20 21:44             ` Runyan, Arthur J
2017-10-23 12:03               ` Ville Syrjälä
2017-10-23 11:48             ` Ville Syrjälä
2017-10-20 14:18     ` Ville Syrjälä
2017-10-20 16:11       ` Ville Syrjälä
2017-10-20 16:09   ` [PATCH v2 " Ville Syrjala
2017-10-20 16:52     ` Ville Syrjälä
2017-10-20 17:05   ` [PATCH v3 " Ville Syrjala
2017-10-23 18:39     ` Rodrigo Vivi
2017-10-18 21:07 ` ✗ Fi.CI.BAT: warning for drm/i915: CNL DVFS thing Patchwork
2017-10-19 17:31   ` Ville Syrjälä
2017-10-19 18:17 ` ✗ Fi.CI.BAT: failure for drm/i915: CNL DVFS thing (rev2) Patchwork
2017-10-19 18:52 ` Patchwork
2017-10-19 20:07 ` ✗ Fi.CI.BAT: warning " Patchwork
2017-10-19 23:27 ` ✓ Fi.CI.BAT: success " Patchwork
2017-10-20  0:22 ` ✓ Fi.CI.IGT: " Patchwork
2017-10-20 16:28 ` ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev3) Patchwork
2017-10-20 17:48 ` ✓ Fi.CI.BAT: success for drm/i915: CNL DVFS thing (rev6) Patchwork
2017-10-20 19:19 ` ✓ Fi.CI.IGT: " Patchwork

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.