diff mbox series

[08/12] drm/i915: Split skl+ and ilk+ read_wm_latency()

Message ID 20181010130454.28557-9-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: Clean up the wm mem latency stuff | expand

Commit Message

Ville Syrjala Oct. 10, 2018, 1:04 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

There's no point it having the skl+ and ilk+ codepaths for reading
the wm latency values in the same function. Split them apart.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 197 +++++++++++++++++---------------
 1 file changed, 104 insertions(+), 93 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 067dc1ac4521..8289c6378db3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2825,95 +2825,10 @@  hsw_compute_linetime_wm(const struct intel_crtc_state *cstate)
 	       PIPE_WM_LINETIME_TIME(linetime);
 }
 
-static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
-				  uint16_t wm[8])
+static void ilk_read_wm_latency(struct drm_i915_private *dev_priv,
+				u16 wm[5])
 {
-	if (INTEL_GEN(dev_priv) >= 9) {
-		uint32_t val;
-		int ret, i;
-		int level, num_levels = dev_priv->wm.num_levels;
-
-		/* read the first set of memory latencies[0:3] */
-		val = 0; /* data0 to be programmed to 0 for first set */
-		mutex_lock(&dev_priv->pcu_lock);
-		ret = sandybridge_pcode_read(dev_priv,
-					     GEN9_PCODE_READ_MEM_LATENCY,
-					     &val);
-		mutex_unlock(&dev_priv->pcu_lock);
-
-		if (ret) {
-			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
-			return;
-		}
-
-		wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
-		wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
-				GEN9_MEM_LATENCY_LEVEL_MASK;
-		wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
-				GEN9_MEM_LATENCY_LEVEL_MASK;
-		wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
-				GEN9_MEM_LATENCY_LEVEL_MASK;
-
-		/* read the second set of memory latencies[4:7] */
-		val = 1; /* data0 to be programmed to 1 for second set */
-		mutex_lock(&dev_priv->pcu_lock);
-		ret = sandybridge_pcode_read(dev_priv,
-					     GEN9_PCODE_READ_MEM_LATENCY,
-					     &val);
-		mutex_unlock(&dev_priv->pcu_lock);
-		if (ret) {
-			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
-			return;
-		}
-
-		wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
-		wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
-				GEN9_MEM_LATENCY_LEVEL_MASK;
-		wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
-				GEN9_MEM_LATENCY_LEVEL_MASK;
-		wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
-				GEN9_MEM_LATENCY_LEVEL_MASK;
-
-		/*
-		 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
-		 * need to be disabled. We make sure to sanitize the values out
-		 * of the punit to satisfy this requirement.
-		 */
-		for (level = 1; level < num_levels; level++) {
-			if (wm[level] == 0) {
-				for (i = level + 1; i < num_levels; i++)
-					wm[i] = 0;
-				break;
-			}
-		}
-
-		/*
-		 * WaWmMemoryReadLatency:skl+,glk
-		 *
-		 * punit doesn't take into account the read latency so we need
-		 * to add 2us to the various latency levels we retrieve from the
-		 * punit when level 0 response data us 0us.
-		 */
-		if (wm[0] == 0) {
-			wm[0] += 2;
-			for (level = 1; level < num_levels; level++) {
-				if (wm[level] == 0)
-					break;
-				wm[level] += 2;
-			}
-		}
-
-		/*
-		 * WA Level-0 adjustment for 16GB DIMMs: SKL+
-		 * If we could not get dimm info enable this WA to prevent from
-		 * any underrun. If not able to get Dimm info assume 16GB dimm
-		 * to avoid any underrun.
-		 */
-		if (!dev_priv->dram_info.valid_dimm ||
-		    dev_priv->dram_info.is_16gb_dimm)
-			wm[0] += 1;
-
-	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
 
 		wm[0] = (sskpd >> 56) & 0xFF;
@@ -2930,7 +2845,7 @@  static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
 		wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK;
 		wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK;
 		wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK;
-	} else if (INTEL_GEN(dev_priv) >= 5) {
+	} else if (IS_GEN5(dev_priv)) {
 		uint32_t mltr = I915_READ(MLTR_ILK);
 
 		/* ILK primary LP0 latency is 700 ns */
@@ -3009,8 +2924,7 @@  static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 	else
 		dev_priv->wm.num_levels = 3;
 
-	intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
-
+	ilk_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
 	ilk_fixup_wm_latency_units(dev_priv, dev_priv->wm.pri_latency);
 
 	memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency,
@@ -3029,6 +2943,68 @@  static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 		snb_wm_latency_quirk(dev_priv);
 }
 
+static void skl_read_wm_latency(struct drm_i915_private *dev_priv,
+				u16 wm[8])
+{
+	int level, num_levels = dev_priv->wm.num_levels;
+	int ret, i;
+	u32 val;
+
+	/* read the first set of memory latencies[0:3] */
+	val = 0; /* data0 to be programmed to 0 for first set */
+	mutex_lock(&dev_priv->pcu_lock);
+	ret = sandybridge_pcode_read(dev_priv,
+				     GEN9_PCODE_READ_MEM_LATENCY,
+				     &val);
+	mutex_unlock(&dev_priv->pcu_lock);
+
+	if (ret) {
+		DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+		return;
+	}
+
+	wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+	wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+		GEN9_MEM_LATENCY_LEVEL_MASK;
+	wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+		GEN9_MEM_LATENCY_LEVEL_MASK;
+	wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+		GEN9_MEM_LATENCY_LEVEL_MASK;
+
+	/* read the second set of memory latencies[4:7] */
+	val = 1; /* data0 to be programmed to 1 for second set */
+	mutex_lock(&dev_priv->pcu_lock);
+	ret = sandybridge_pcode_read(dev_priv,
+				     GEN9_PCODE_READ_MEM_LATENCY,
+				     &val);
+	mutex_unlock(&dev_priv->pcu_lock);
+	if (ret) {
+		DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+		return;
+	}
+
+	wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+	wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+		GEN9_MEM_LATENCY_LEVEL_MASK;
+	wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+		GEN9_MEM_LATENCY_LEVEL_MASK;
+	wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+		GEN9_MEM_LATENCY_LEVEL_MASK;
+
+	/*
+	 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
+	 * need to be disabled. We make sure to sanitize the values out
+	 * of the punit to satisfy this requirement.
+	 */
+	for (level = 1; level < num_levels; level++) {
+		if (wm[level] == 0) {
+			for (i = level + 1; i < num_levels; i++)
+				wm[i] = 0;
+			break;
+		}
+	}
+}
+
 static void skl_fixup_wm_latency_units(struct drm_i915_private *dev_priv,
 				       u16 wm[8])
 {
@@ -3039,14 +3015,49 @@  static void skl_fixup_wm_latency_units(struct drm_i915_private *dev_priv,
 		wm[level] *= 10;
 }
 
+static void skl_wm_latency_wa(struct drm_i915_private *dev_priv,
+			      u16 wm[8])
+{
+	/*
+	 * WaWmMemoryReadLatency:skl,glk
+	 *
+	 * punit doesn't take into account the read latency so we need
+	 * to add 2us to the various latency levels we retrieve from the
+	 * punit when level 0 response data us 0us.
+	 */
+	if (wm[0] == 0) {
+		int level, num_levels = dev_priv->wm.num_levels;
+
+		wm[0] += 20;
+
+		for (level = 1; level < num_levels; level++) {
+			if (wm[level] == 0)
+				break;
+
+			wm[level] += 20;
+		}
+	}
+
+	/*
+	 * WA Level-0 adjustment for 16GB DIMMs: SKL+
+	 * If we could not get dimm info enable this WA to prevent from
+	 * any underrun. If not able to get Dimm info assume 16GB dimm
+	 * to avoid any underrun.
+	 */
+	if (!dev_priv->dram_info.valid_dimm ||
+	    dev_priv->dram_info.is_16gb_dimm)
+		wm[0] += 10;
+}
+
 static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
 	dev_priv->wm.num_levels = 8;
 
-	intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
-
+	skl_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
 	skl_fixup_wm_latency_units(dev_priv, dev_priv->wm.pri_latency);
 
+	skl_wm_latency_wa(dev_priv, dev_priv->wm.pri_latency);
+
 	memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency,
 	       sizeof(dev_priv->wm.pri_latency));
 	memcpy(dev_priv->wm.cur_latency, dev_priv->wm.pri_latency,