All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 01/12] drm/i915: Store all wm memory latency values in .1 usec units
Date: Wed, 10 Oct 2018 16:04:43 +0300	[thread overview]
Message-ID: <20181010130454.28557-2-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20181010130454.28557-1-ville.syrjala@linux.intel.com>

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

In order to simplify the code let's store all memory latency values in
0.1 usec units. This limits the platform specific units to the initial
setup code for the most part.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  12 ---
 drivers/gpu/drm/i915/i915_drv.h     |  14 +--
 drivers/gpu/drm/i915/intel_pm.c     | 149 ++++++++++++++++------------
 3 files changed, 87 insertions(+), 88 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 00c551d3e409..9e0cb995801f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3807,18 +3807,6 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
 	for (level = 0; level < num_levels; level++) {
 		unsigned int latency = wm[level];
 
-		/*
-		 * - WM1+ latency values in 0.5us units
-		 * - latencies are in us on gen9/vlv/chv
-		 */
-		if (INTEL_GEN(dev_priv) >= 9 ||
-		    IS_VALLEYVIEW(dev_priv) ||
-		    IS_CHERRYVIEW(dev_priv) ||
-		    IS_G4X(dev_priv))
-			latency *= 10;
-		else if (level > 0)
-			latency *= 5;
-
 		seq_printf(m, "WM%d %u (%u.%u usec)\n",
 			   level, wm[level], latency / 10, latency % 10);
 	}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 794a8a03c7e6..e57b8cb8fa4d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1906,22 +1906,10 @@ struct drm_i915_private {
 	} sagv_status;
 
 	struct {
-		/*
-		 * Raw watermark latency values:
-		 * in 0.1us units for WM0,
-		 * in 0.5us units for WM1+.
-		 */
-		/* primary */
+		/* Watermark memory latency values in 0.1 us units */
 		uint16_t pri_latency[5];
-		/* sprite */
 		uint16_t spr_latency[5];
-		/* cursor */
 		uint16_t cur_latency[5];
-		/*
-		 * Raw watermark memory latency values
-		 * for SKL for all 8 levels
-		 * in 1us units.
-		 */
 		uint16_t skl_latency[8];
 
 		/* current hardware state */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1392aa56a55a..f871a6f152c3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -801,6 +801,27 @@ static int intel_wm_num_levels(struct drm_i915_private *dev_priv)
 	return dev_priv->wm.max_level + 1;
 }
 
+static int intel_plane_wm_latency(struct intel_plane *plane,
+				  int level)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+
+	if (INTEL_GEN(dev_priv) >= 9)
+		return dev_priv->wm.skl_latency[level];
+
+	if (HAS_GMCH_DISPLAY(dev_priv))
+		return dev_priv->wm.pri_latency[level];
+
+	switch (plane->id) {
+	case PLANE_PRIMARY:
+		return dev_priv->wm.pri_latency[level];
+	case PLANE_CURSOR:
+		return dev_priv->wm.cur_latency[level];
+	default:
+		return dev_priv->wm.spr_latency[level];
+	}
+}
+
 static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
 				   const struct intel_plane_state *plane_state)
 {
@@ -1039,10 +1060,10 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
 
 static void g4x_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
-	/* all latencies in usec */
-	dev_priv->wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 5;
-	dev_priv->wm.pri_latency[G4X_WM_LEVEL_SR] = 12;
-	dev_priv->wm.pri_latency[G4X_WM_LEVEL_HPLL] = 35;
+	/* all latencies in .1 usec */
+	dev_priv->wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 50;
+	dev_priv->wm.pri_latency[G4X_WM_LEVEL_SR] = 120;
+	dev_priv->wm.pri_latency[G4X_WM_LEVEL_HPLL] = 350;
 
 	dev_priv->wm.max_level = G4X_WM_LEVEL_HPLL;
 }
@@ -1097,7 +1118,7 @@ static uint16_t g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->base.adjusted_mode;
-	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
+	int latency = intel_plane_wm_latency(plane, level);
 	unsigned int clock, htotal, cpp, width, wm;
 
 	if (latency == 0)
@@ -1586,14 +1607,14 @@ static unsigned int vlv_wm_method2(unsigned int pixel_rate,
 
 static void vlv_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
-	/* all latencies in usec */
-	dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3;
+	/* all latencies in .1 usec */
+	dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 30;
 
 	dev_priv->wm.max_level = VLV_WM_LEVEL_PM2;
 
 	if (IS_CHERRYVIEW(dev_priv)) {
-		dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12;
-		dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33;
+		dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 120;
+		dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 330;
 
 		dev_priv->wm.max_level = VLV_WM_LEVEL_DDR_DVFS;
 	}
@@ -1604,12 +1625,12 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 				     int level)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
-	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->base.adjusted_mode;
+	int latency = intel_plane_wm_latency(plane, level);
 	unsigned int clock, htotal, cpp, width, wm;
 
-	if (dev_priv->wm.pri_latency[level] == 0)
+	if (latency == 0)
 		return USHRT_MAX;
 
 	if (!intel_wm_plane_visible(crtc_state, plane_state))
@@ -1629,8 +1650,7 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 		 */
 		wm = 63;
 	} else {
-		wm = vlv_wm_method2(clock, htotal, width, cpp,
-				    dev_priv->wm.pri_latency[level] * 10);
+		wm = vlv_wm_method2(clock, htotal, width, cpp, latency);
 	}
 
 	return min_t(unsigned int, wm, USHRT_MAX);
@@ -2481,15 +2501,12 @@ struct ilk_wm_maximums {
 	uint16_t fbc;
 };
 
-/*
- * For both WM_PIPE and WM_LP.
- * mem_value must be in 0.1us units.
- */
 static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
-				   uint32_t mem_value,
-				   bool is_lp)
+				   int level)
 {
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	int latency = intel_plane_wm_latency(plane, level);
 	uint32_t method1, method2;
 	int cpp;
 
@@ -2498,27 +2515,25 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
 
 	cpp = pstate->base.fb->format->cpp[0];
 
-	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, mem_value);
+	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, latency);
 
-	if (!is_lp)
+	if (level == 0)
 		return method1;
 
 	method2 = ilk_wm_method2(cstate->pixel_rate,
 				 cstate->base.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&pstate->base.dst),
-				 cpp, mem_value);
+				 cpp, latency);
 
 	return min(method1, method2);
 }
 
-/*
- * For both WM_PIPE and WM_LP.
- * mem_value must be in 0.1us units.
- */
 static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
-				   uint32_t mem_value)
+				   int level)
 {
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	int latency = intel_plane_wm_latency(plane, level);
 	uint32_t method1, method2;
 	int cpp;
 
@@ -2527,22 +2542,20 @@ static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
 
 	cpp = pstate->base.fb->format->cpp[0];
 
-	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, mem_value);
+	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, latency);
 	method2 = ilk_wm_method2(cstate->pixel_rate,
 				 cstate->base.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&pstate->base.dst),
-				 cpp, mem_value);
+				 cpp, latency);
 	return min(method1, method2);
 }
 
-/*
- * For both WM_PIPE and WM_LP.
- * mem_value must be in 0.1us units.
- */
 static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
-				   uint32_t mem_value)
+				   int level)
 {
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	int latency = intel_plane_wm_latency(plane, level);
 	int cpp;
 
 	if (!intel_wm_plane_visible(cstate, pstate))
@@ -2552,7 +2565,7 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
 
 	return ilk_wm_method2(cstate->pixel_rate,
 			      cstate->base.adjusted_mode.crtc_htotal,
-			      pstate->base.crtc_w, cpp, mem_value);
+			      pstate->base.crtc_w, cpp, latency);
 }
 
 /* Only for WM_LP. */
@@ -2743,28 +2756,16 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 				 const struct intel_plane_state *curstate,
 				 struct intel_wm_level *result)
 {
-	uint16_t pri_latency = dev_priv->wm.pri_latency[level];
-	uint16_t spr_latency = dev_priv->wm.spr_latency[level];
-	uint16_t cur_latency = dev_priv->wm.cur_latency[level];
-
-	/* WM1+ latency values stored in 0.5us units */
-	if (level > 0) {
-		pri_latency *= 5;
-		spr_latency *= 5;
-		cur_latency *= 5;
-	}
-
 	if (pristate) {
-		result->pri_val = ilk_compute_pri_wm(cstate, pristate,
-						     pri_latency, level);
+		result->pri_val = ilk_compute_pri_wm(cstate, pristate, level);
 		result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
 	}
 
 	if (sprstate)
-		result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
+		result->spr_val = ilk_compute_spr_wm(cstate, sprstate, level);
 
 	if (curstate)
-		result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
+		result->cur_val = ilk_compute_cur_wm(cstate, curstate, level);
 
 	result->enable = true;
 }
@@ -2930,6 +2931,16 @@ static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv,
 		wm[0] = 13;
 }
 
+static void ilk_fixup_wm_latency_units(struct drm_i915_private *dev_priv,
+				       u16 wm[5])
+{
+	int level, num_levels = ilk_wm_max_level(dev_priv) + 1;
+
+	/* convert .5 usec to .1 usec units */
+	for (level = 1; level < num_levels; level++)
+		wm[level] *= 5;
+}
+
 int ilk_wm_max_level(const struct drm_i915_private *dev_priv)
 {
 	/* how many WM levels are we expecting */
@@ -2958,15 +2969,6 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv,
 			continue;
 		}
 
-		/*
-		 * - latencies are in us on gen9.
-		 * - before then, WM1+ latency values are in 0.5us units
-		 */
-		if (INTEL_GEN(dev_priv) >= 9)
-			latency *= 10;
-		else if (level > 0)
-			latency *= 5;
-
 		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
 			      name, level, wm[level],
 			      latency / 10, latency % 10);
@@ -2982,8 +2984,12 @@ static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv,
 		return false;
 
 	wm[0] = max(wm[0], min);
+
+	/* WM1+ latencies must be multiples of .5 usec */
+	min = roundup(min, 5);
+
 	for (level = 1; level <= max_level; level++)
-		wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5));
+		wm[level] = max(wm[level], min);
 
 	return true;
 }
@@ -3013,6 +3019,8 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
 	intel_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,
 	       sizeof(dev_priv->wm.pri_latency));
 	memcpy(dev_priv->wm.cur_latency, dev_priv->wm.pri_latency,
@@ -3029,9 +3037,22 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 		snb_wm_latency_quirk(dev_priv);
 }
 
+static void skl_fixup_wm_latency_units(struct drm_i915_private *dev_priv,
+				       u16 wm[8])
+{
+	int level, num_levels = ilk_wm_max_level(dev_priv) + 1;
+
+	/* convert usec to .1 usec units */
+	for (level = 0; level < num_levels; level++)
+		wm[level] *= 10;
+}
+
 static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
 	intel_read_wm_latency(dev_priv, dev_priv->wm.skl_latency);
+
+	skl_fixup_wm_latency_units(dev_priv, dev_priv->wm.skl_latency);
+
 	intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency);
 }
 
@@ -3303,7 +3324,8 @@ static unsigned int ilk_wm_lp_latency(struct drm_device *dev, int level)
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 		return 2 * level;
 	else
-		return dev_priv->wm.pri_latency[level];
+		/* specified in .5 usec units */
+		return dev_priv->wm.pri_latency[level] / 5;
 }
 
 static void ilk_compute_wm_results(struct drm_device *dev,
@@ -3763,7 +3785,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
 		     !wm->wm[level].plane_en; --level)
 		     { }
 
-		latency = dev_priv->wm.skl_latency[level];
+		latency = intel_plane_wm_latency(plane, level);
 
 		if (skl_needs_memory_bw_wa(intel_state) &&
 		    plane->base.state->fb->modifier ==
@@ -4636,7 +4658,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 				struct skl_wm_level *result /* out */)
 {
 	const struct drm_plane_state *pstate = &intel_pstate->base;
-	uint32_t latency = dev_priv->wm.skl_latency[level];
+	uint32_t latency = intel_plane_wm_latency(to_intel_plane(pstate->plane),
+						  level);
 	uint_fixed_16_16_t method1, method2;
 	uint_fixed_16_16_t selected_result;
 	uint32_t res_blocks, res_lines;
-- 
2.18.1

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

  reply	other threads:[~2018-10-10 13:07 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-10 13:04 [PATCH 00/12] drm/i915: Clean up the wm mem latency stuff Ville Syrjala
2018-10-10 13:04 ` Ville Syrjala [this message]
2018-10-10 13:12   ` [PATCH 01/12] drm/i915: Store all wm memory latency values in .1 usec units Chris Wilson
2018-10-10 15:35     ` Ville Syrjälä
2018-10-26 18:14   ` [PATCH v2 " Ville Syrjala
2018-10-10 13:04 ` [PATCH 02/12] drm/i915: Use the spr/cur latencies on vlv/chv/g4x Ville Syrjala
2018-10-10 13:04 ` [PATCH 03/12] drm/i915: Eliminate skl_latency[] Ville Syrjala
2018-10-10 13:04 ` [PATCH 04/12] drm/i915: Add dev_priv->wm.num_levels and use it everywhere Ville Syrjala
2018-10-26 18:27   ` [PATCH v2 " Ville Syrjala
2018-10-10 13:04 ` [PATCH 05/12] drm/i915: Add DEFINE_SNPRINTF_ARRAY() Ville Syrjala
2018-10-11 12:14   ` Jani Nikula
2018-10-11 12:47     ` Ville Syrjälä
2018-10-11 16:07       ` Jani Nikula
2018-10-10 13:04 ` [PATCH 06/12] drm/i915: Make the WM memory latency print more compact Ville Syrjala
2018-10-10 13:04 ` [PATCH 07/12] drm/i915: Eliminate redundant ilk sprite/cursor wm fixup code Ville Syrjala
2018-10-10 13:04 ` [PATCH 08/12] drm/i915: Split skl+ and ilk+ read_wm_latency() Ville Syrjala
2018-10-26 18:45   ` [PATCH v2 " Ville Syrjala
2018-10-10 13:04 ` [PATCH 09/12] drm/i915: Sanitize wm latency values for ilk+ Ville Syrjala
2018-10-26 19:11   ` [PATCH v2 " Ville Syrjala
2018-10-10 13:04 ` [PATCH 10/12] drm/i915: Drop the funky ilk wm setup Ville Syrjala
2018-10-10 13:04 ` [PATCH 11/12] drm/i915: Allow LP3 watermarks on ILK Ville Syrjala
2018-10-10 13:04 ` [PATCH 12/12] drm/i915: Remove the remnants of the ilk+ LP0 wm hack Ville Syrjala
2018-10-10 14:34 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Clean up the wm mem latency stuff Patchwork
2018-10-10 14:38 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-10-10 14:50 ` ✗ Fi.CI.BAT: failure " Patchwork
2018-10-26 18:17 ` ✗ Fi.CI.BAT: failure for drm/i915: Clean up the wm mem latency stuff (rev2) Patchwork
2018-10-26 18:37 ` ✗ Fi.CI.BAT: failure for drm/i915: Clean up the wm mem latency stuff (rev3) Patchwork
2018-10-26 19:01 ` ✗ Fi.CI.BAT: failure for drm/i915: Clean up the wm mem latency stuff (rev4) Patchwork
2018-10-26 19:29 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Clean up the wm mem latency stuff (rev5) Patchwork
2018-10-26 19:34 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-10-26 19:47 ` ✓ Fi.CI.BAT: success " Patchwork
2018-10-27  5:17 ` ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20181010130454.28557-2-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

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

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