All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] Atomic watermark updates (v3)
@ 2015-08-21  1:11 Matt Roper
  2015-08-21  1:11 ` [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code Matt Roper
                   ` (13 more replies)
  0 siblings, 14 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Previous atomic watermark patches were posted here:
  http://lists.freedesktop.org/archives/intel-gfx/2015-July/070465.html

Key changes since the last series:
 * Quite a bit of rebasing; I got pulled away from working on this for a while,
   so parts of the upstream code evolved a bit before I was able to get back
   to working on this.
 * Completely drop the async aspect of writing the final watermarks on
   platforms that need two-step programming.  Although this is the direction we
   want to go eventually, Maarten has indicated that what I was doing in
   previous patch sets was going to lead to conflicts with some of his
   in-progress work and asked that I just write the final watermarks at the
   very end of the atomic transaction, after waiting for vblanks.  We can
   revisit the async final step again after Maarten's work lands and leverage
   the new interfaces he adds.  In the meantime, this simplifies things a
   bit since we don't need to worry about async final watermark writing
   racing with our next transaction and clobbering the intermediate values
   for that next transaction that we've already written.
 * Early SKL-style atomic watermarks (completely untested at the moment!).  Even
   though gen9 doesn't need the two-step programming process, we now
   pre-compute gen9 watermark values during the check phase and write+flush
   them during commit.  However I think there's still more refactoring that
   should be eventually done here.  We trigger watermark updates on a per-crtc
   basis, but the end results are global, not per-crtc.  In an atomic
   transaction this could currently lead to us re-calculating the same values
   multiple times if multiple CRTC's all trigger a WM update.   Note that I
   haven't had a chance to run any of this on real gen9 hardware yet, so all of
   the SKL patches here should be considered RFC at best; they may be
   completely broken.
 * Various review feedback from Daniel, Ville, and Maarten from previous
   iterations.


Matt Roper (12):
  drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM
    code
  drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  drm/i915/skl: Simplify wm structures slightly
  drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM
  drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check
  drm/i915: Drop intel_update_sprite_watermarks
  drm/i915: Move active watermarks into CRTC state (v2)
  drm/i915: Calculate ILK-style watermarks during atomic check (v2)
  drm/i915: Calculate watermark configuration during atomic check
  drm/i915: Add two-stage ILK-style watermark programming (v3)
  drm/i915/skl: Switch to atomic watermark programming
  drm/i915/skl: Clarify pending vs hw watermark values

Ville Syrjälä (1):
  drm/i915: Refactor ilk_update_wm (v3)

 drivers/gpu/drm/i915/i915_debugfs.c  |   4 +-
 drivers/gpu/drm/i915/i915_drv.h      |  68 ++-
 drivers/gpu/drm/i915/intel_atomic.c  |   1 +
 drivers/gpu/drm/i915/intel_display.c | 184 +++++++-
 drivers/gpu/drm/i915/intel_drv.h     |  81 +++-
 drivers/gpu/drm/i915/intel_pm.c      | 860 ++++++++++++++++-------------------
 drivers/gpu/drm/i915/intel_sprite.c  |  15 -
 7 files changed, 659 insertions(+), 554 deletions(-)

-- 
2.1.4

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

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

* [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-26 12:45   ` Conselvan De Oliveira, Ander
  2015-08-21  1:11 ` [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM Matt Roper
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Just pull the info out of the plane state structure rather than staging
it in an additional structure.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 133 +++++++++++++++++++++-------------------
 1 file changed, 70 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index fff0c22..c9cf7cf 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1791,9 +1791,6 @@ struct ilk_pipe_wm_parameters {
 	bool active;
 	uint32_t pipe_htotal;
 	uint32_t pixel_rate;
-	struct intel_plane_wm_parameters pri;
-	struct intel_plane_wm_parameters spr;
-	struct intel_plane_wm_parameters cur;
 };
 
 struct ilk_wm_maximums {
@@ -1815,25 +1812,25 @@ struct intel_wm_config {
  * mem_value must be in 0.1us units.
  */
 static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
+				   const struct intel_plane_state *pstate,
 				   uint32_t mem_value,
 				   bool is_lp)
 {
+	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
 	uint32_t method1, method2;
 
-	if (!params->active || !params->pri.enabled)
+	if (!params->active || !pstate->visible)
 		return 0;
 
-	method1 = ilk_wm_method1(params->pixel_rate,
-				 params->pri.bytes_per_pixel,
-				 mem_value);
+	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
 
 	if (!is_lp)
 		return method1;
 
 	method2 = ilk_wm_method2(params->pixel_rate,
 				 params->pipe_htotal,
-				 params->pri.horiz_pixels,
-				 params->pri.bytes_per_pixel,
+				 drm_rect_width(&pstate->dst),
+				 bpp,
 				 mem_value);
 
 	return min(method1, method2);
@@ -1844,20 +1841,20 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
  * mem_value must be in 0.1us units.
  */
 static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
+				   const struct intel_plane_state *pstate,
 				   uint32_t mem_value)
 {
+	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
 	uint32_t method1, method2;
 
-	if (!params->active || !params->spr.enabled)
+	if (!params->active || !pstate->visible)
 		return 0;
 
-	method1 = ilk_wm_method1(params->pixel_rate,
-				 params->spr.bytes_per_pixel,
-				 mem_value);
+	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
 	method2 = ilk_wm_method2(params->pixel_rate,
 				 params->pipe_htotal,
-				 params->spr.horiz_pixels,
-				 params->spr.bytes_per_pixel,
+				 drm_rect_width(&pstate->dst),
+				 bpp,
 				 mem_value);
 	return min(method1, method2);
 }
@@ -1867,28 +1864,32 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
  * mem_value must be in 0.1us units.
  */
 static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
+				   const struct intel_plane_state *pstate,
 				   uint32_t mem_value)
 {
-	if (!params->active || !params->cur.enabled)
+	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
+
+	if (!params->active || !pstate->visible)
 		return 0;
 
 	return ilk_wm_method2(params->pixel_rate,
 			      params->pipe_htotal,
-			      params->cur.horiz_pixels,
-			      params->cur.bytes_per_pixel,
+			      drm_rect_width(&pstate->dst),
+			      bpp,
 			      mem_value);
 }
 
 /* Only for WM_LP. */
 static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
+				   const struct intel_plane_state *pstate,
 				   uint32_t pri_val)
 {
-	if (!params->active || !params->pri.enabled)
+	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
+
+	if (!params->active || !pstate->visible)
 		return 0;
 
-	return ilk_wm_fbc(pri_val,
-			  params->pri.horiz_pixels,
-			  params->pri.bytes_per_pixel);
+	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
 }
 
 static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
@@ -2053,10 +2054,12 @@ static bool ilk_validate_wm_level(int level,
 }
 
 static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
+				 const struct intel_crtc *intel_crtc,
 				 int level,
 				 const struct ilk_pipe_wm_parameters *p,
 				 struct intel_wm_level *result)
 {
+	struct intel_plane *intel_plane;
 	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];
@@ -2068,10 +2071,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 		cur_latency *= 5;
 	}
 
-	result->pri_val = ilk_compute_pri_wm(p, pri_latency, level);
-	result->spr_val = ilk_compute_spr_wm(p, spr_latency);
-	result->cur_val = ilk_compute_cur_wm(p, cur_latency);
-	result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val);
+	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
+		struct intel_plane_state *pstate =
+			to_intel_plane_state(intel_plane->base.state);
+
+		switch (intel_plane->base.type) {
+		case DRM_PLANE_TYPE_PRIMARY:
+			result->pri_val = ilk_compute_pri_wm(p, pstate,
+							     pri_latency,
+							     level);
+			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
+							     result->pri_val);
+			break;
+		case DRM_PLANE_TYPE_OVERLAY:
+			result->spr_val = ilk_compute_spr_wm(p, pstate,
+							     spr_latency);
+			break;
+		case DRM_PLANE_TYPE_CURSOR:
+			result->cur_val = ilk_compute_cur_wm(p, pstate,
+							     cur_latency);
+			break;
+		}
+	}
+
 	result->enable = true;
 }
 
@@ -2333,10 +2355,7 @@ static void skl_setup_wm_latency(struct drm_device *dev)
 static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
 				      struct ilk_pipe_wm_parameters *p)
 {
-	struct drm_device *dev = crtc->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum pipe pipe = intel_crtc->pipe;
-	struct drm_plane *plane;
 
 	if (!intel_crtc->active)
 		return;
@@ -2344,32 +2363,6 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
 	p->active = true;
 	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
 	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
-
-	if (crtc->primary->state->fb)
-		p->pri.bytes_per_pixel =
-			crtc->primary->state->fb->bits_per_pixel / 8;
-	else
-		p->pri.bytes_per_pixel = 4;
-
-	p->cur.bytes_per_pixel = 4;
-	/*
-	 * TODO: for now, assume primary and cursor planes are always enabled.
-	 * Setting them to false makes the screen flicker.
-	 */
-	p->pri.enabled = true;
-	p->cur.enabled = true;
-
-	p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
-	p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
-
-	drm_for_each_legacy_plane(plane, dev) {
-		struct intel_plane *intel_plane = to_intel_plane(plane);
-
-		if (intel_plane->pipe == pipe) {
-			p->spr = intel_plane->wm;
-			break;
-		}
-	}
 }
 
 static void ilk_compute_wm_config(struct drm_device *dev,
@@ -2397,28 +2390,42 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	const struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *sprstate = NULL;
 	int level, max_level = ilk_wm_max_level(dev);
 	/* LP0 watermark maximums depend on this pipe alone */
 	struct intel_wm_config config = {
 		.num_pipes_active = 1,
-		.sprites_enabled = params->spr.enabled,
-		.sprites_scaled = params->spr.scaled,
 	};
 	struct ilk_wm_maximums max;
 
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
+			sprstate = to_intel_plane_state(intel_plane->base.state);
+			break;
+		}
+	}
+
+	config.sprites_enabled = sprstate->visible;
+	config.sprites_scaled =
+		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
+		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
+
+
 	pipe_wm->pipe_enabled = params->active;
-	pipe_wm->sprites_enabled = params->spr.enabled;
-	pipe_wm->sprites_scaled = params->spr.scaled;
+	pipe_wm->sprites_enabled = sprstate->visible;
+	pipe_wm->sprites_scaled = config.sprites_scaled;
 
 	/* ILK/SNB: LP2+ watermarks only w/o sprites */
-	if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled)
+	if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
 		max_level = 1;
 
 	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
-	if (params->spr.scaled)
+	if (config.sprites_scaled)
 		max_level = 0;
 
-	ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]);
+	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
 
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
@@ -2435,7 +2442,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
 	for (level = 1; level <= max_level; level++) {
 		struct intel_wm_level wm = {};
 
-		ilk_compute_wm_level(dev_priv, level, params, &wm);
+		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
 
 		/*
 		 * Disable any watermark level that exceeds the
-- 
2.1.4

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

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

* [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
  2015-08-21  1:11 ` [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-26 12:45   ` Ander Conselvan De Oliveira
  2015-08-26 13:39   ` Ville Syrjälä
  2015-08-21  1:11 ` [PATCH 03/13] drm/i915/skl: Simplify wm structures slightly Matt Roper
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Just pull the info out of the CRTC state structure rather than staging
it in an additional structure.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 84 ++++++++++++++---------------------------
 1 file changed, 28 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c9cf7cf..d82ea82 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1787,12 +1787,6 @@ struct skl_pipe_wm_parameters {
 	struct intel_plane_wm_parameters cursor;
 };
 
-struct ilk_pipe_wm_parameters {
-	bool active;
-	uint32_t pipe_htotal;
-	uint32_t pixel_rate;
-};
-
 struct ilk_wm_maximums {
 	uint16_t pri;
 	uint16_t spr;
@@ -1811,7 +1805,7 @@ struct intel_wm_config {
  * For both WM_PIPE and WM_LP.
  * mem_value must be in 0.1us units.
  */
-static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
+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)
@@ -1819,16 +1813,16 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
 	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
 	uint32_t method1, method2;
 
-	if (!params->active || !pstate->visible)
+	if (!cstate->base.active || !pstate->visible)
 		return 0;
 
-	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
+	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
 
 	if (!is_lp)
 		return method1;
 
-	method2 = ilk_wm_method2(params->pixel_rate,
-				 params->pipe_htotal,
+	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
+				 cstate->base.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&pstate->dst),
 				 bpp,
 				 mem_value);
@@ -1840,19 +1834,19 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
  * For both WM_PIPE and WM_LP.
  * mem_value must be in 0.1us units.
  */
-static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
+static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
 				   uint32_t mem_value)
 {
 	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
 	uint32_t method1, method2;
 
-	if (!params->active || !pstate->visible)
+	if (!cstate->base.active || !pstate->visible)
 		return 0;
 
-	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
-	method2 = ilk_wm_method2(params->pixel_rate,
-				 params->pipe_htotal,
+	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
+	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
+				 cstate->base.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&pstate->dst),
 				 bpp,
 				 mem_value);
@@ -1863,30 +1857,30 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
  * For both WM_PIPE and WM_LP.
  * mem_value must be in 0.1us units.
  */
-static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
+static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
 				   uint32_t mem_value)
 {
 	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
 
-	if (!params->active || !pstate->visible)
+	if (!cstate->base.active || !pstate->visible)
 		return 0;
 
-	return ilk_wm_method2(params->pixel_rate,
-			      params->pipe_htotal,
+	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
+			      cstate->base.adjusted_mode.crtc_htotal,
 			      drm_rect_width(&pstate->dst),
 			      bpp,
 			      mem_value);
 }
 
 /* Only for WM_LP. */
-static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
+static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
 				   uint32_t pri_val)
 {
 	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
 
-	if (!params->active || !pstate->visible)
+	if (!cstate->base.active || !pstate->visible)
 		return 0;
 
 	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
@@ -2056,7 +2050,7 @@ static bool ilk_validate_wm_level(int level,
 static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 				 const struct intel_crtc *intel_crtc,
 				 int level,
-				 const struct ilk_pipe_wm_parameters *p,
+				 struct intel_crtc_state *cstate,
 				 struct intel_wm_level *result)
 {
 	struct intel_plane *intel_plane;
@@ -2077,18 +2071,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 
 		switch (intel_plane->base.type) {
 		case DRM_PLANE_TYPE_PRIMARY:
-			result->pri_val = ilk_compute_pri_wm(p, pstate,
+			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
 							     pri_latency,
 							     level);
-			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
+			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
 							     result->pri_val);
 			break;
 		case DRM_PLANE_TYPE_OVERLAY:
-			result->spr_val = ilk_compute_spr_wm(p, pstate,
+			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
 							     spr_latency);
 			break;
 		case DRM_PLANE_TYPE_CURSOR:
-			result->cur_val = ilk_compute_cur_wm(p, pstate,
+			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
 							     cur_latency);
 			break;
 		}
@@ -2352,19 +2346,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
 	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
 }
 
-static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
-				      struct ilk_pipe_wm_parameters *p)
-{
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	if (!intel_crtc->active)
-		return;
-
-	p->active = true;
-	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
-	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
-}
-
 static void ilk_compute_wm_config(struct drm_device *dev,
 				  struct intel_wm_config *config)
 {
@@ -2384,10 +2365,10 @@ static void ilk_compute_wm_config(struct drm_device *dev,
 }
 
 /* Compute new watermarks for the pipe */
-static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
-				  const struct ilk_pipe_wm_parameters *params,
+static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 				  struct intel_pipe_wm *pipe_wm)
 {
+	struct drm_crtc *crtc = cstate->base.crtc;
 	struct drm_device *dev = crtc->dev;
 	const struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -2412,8 +2393,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
 		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
 		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
 
-
-	pipe_wm->pipe_enabled = params->active;
+	pipe_wm->pipe_enabled = cstate->base.active;
 	pipe_wm->sprites_enabled = sprstate->visible;
 	pipe_wm->sprites_scaled = config.sprites_scaled;
 
@@ -2425,7 +2405,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
 	if (config.sprites_scaled)
 		max_level = 0;
 
-	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
+	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
 
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
@@ -2442,7 +2422,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
 	for (level = 1; level <= max_level; level++) {
 		struct intel_wm_level wm = {};
 
-		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
+		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
 
 		/*
 		 * Disable any watermark level that exceeds the
@@ -3748,19 +3728,17 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
 static void ilk_update_wm(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct ilk_wm_maximums max;
-	struct ilk_pipe_wm_parameters params = {};
 	struct ilk_wm_values results = {};
 	enum intel_ddb_partitioning partitioning;
 	struct intel_pipe_wm pipe_wm = {};
 	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
 	struct intel_wm_config config = {};
 
-	ilk_compute_wm_parameters(crtc, &params);
-
-	intel_compute_pipe_wm(crtc, &params, &pipe_wm);
+	intel_compute_pipe_wm(cstate, &pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
 		return;
@@ -3800,12 +3778,6 @@ ilk_update_sprite_wm(struct drm_plane *plane,
 	struct drm_device *dev = plane->dev;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 
-	intel_plane->wm.enabled = enabled;
-	intel_plane->wm.scaled = scaled;
-	intel_plane->wm.horiz_pixels = sprite_width;
-	intel_plane->wm.vert_pixels = sprite_width;
-	intel_plane->wm.bytes_per_pixel = pixel_size;
-
 	/*
 	 * IVB workaround: must disable low power watermarks for at least
 	 * one frame before enabling scaling.  LP watermarks can be re-enabled
-- 
2.1.4

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

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

* [PATCH 03/13] drm/i915/skl: Simplify wm structures slightly
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
  2015-08-21  1:11 ` [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code Matt Roper
  2015-08-21  1:11 ` [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-26 13:23   ` Ander Conselvan De Oliveira
  2015-08-21  1:11 ` [PATCH 04/13] drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM Matt Roper
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

A bunch of SKL watermark-related structures have the cursor plane as a
separate entry from the rest of the planes.  If we just extend the
relevant plane arrays by one entry and use the top-most array element as
the cursor, it will simplify future patches.

There shouldn't be any functional change here; this is just shuffling
around how the data is stored in some of the data structures.  The whole
patch is generated with Coccinelle via the following semantic patch:

        @@ struct skl_pipe_wm_parameters WMP; @@
        - WMP.cursor
        + WMP.plane[I915_MAX_PLANES]

        @@ struct skl_pipe_wm_parameters *WMP; @@
        - WMP->cursor
        + WMP->plane[I915_MAX_PLANES]

        @@ @@
        struct skl_pipe_wm_parameters {
        ...
        - struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
        + struct intel_plane_wm_parameters plane[I915_MAX_PLANES+1];
        - struct intel_plane_wm_parameters cursor;
        ...
        };

        @@
        struct skl_ddb_allocation DDB;
        expression E;
        @@
        - DDB.cursor[E]
        + DDB.plane[E][I915_MAX_PLANES]

        @@
        struct skl_ddb_allocation *DDB;
        expression E;
        @@
        - DDB->cursor[E]
        + DDB->plane[E][I915_MAX_PLANES]

        @@ @@
        struct skl_ddb_allocation {
        ...
        - struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
        + struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES+1];
        ...
        - struct skl_ddb_entry cursor[I915_MAX_PIPES];
        ...
        };

        @@
        struct skl_wm_values WMV;
        expression E1, E2;
        @@
        (
        - WMV.cursor[E1][E2]
        + WMV.plane[E1][I915_MAX_PLANES][E2]
        |
        - WMV.cursor_trans[E1]
        + WMV.plane_trans[E1][I915_MAX_PLANES]
        )

        @@
        struct skl_wm_values *WMV;
        expression E1, E2;
        @@
        (
        - WMV->cursor[E1][E2]
        + WMV->plane[E1][I915_MAX_PLANES][E2]
        |
        - WMV->cursor_trans[E1]
        + WMV->plane_trans[E1][I915_MAX_PLANES]
        )

        @@ @@
        struct skl_wm_values {
        ...
        - uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
        + uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES+1][8];
        ...
        - uint32_t cursor[I915_MAX_PIPES][8];
        ...
        - uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
        + uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES+1];
        ...
        - uint32_t cursor_trans[I915_MAX_PIPES];
        ...
        };

        @@ struct skl_wm_level WML; @@
        (
        - WML.cursor_en
        + WML.plane_en[I915_MAX_PLANES]
        |
        - WML.cursor_res_b
        + WML.plane_res_b[I915_MAX_PLANES]
        |
        - WML.cursor_res_l
        + WML.plane_res_l[I915_MAX_PLANES]
        )

        @@ struct skl_wm_level *WML; @@
        (
        - WML->cursor_en
        + WML->plane_en[I915_MAX_PLANES]
        |
        - WML->cursor_res_b
        + WML->plane_res_b[I915_MAX_PLANES]
        |
        - WML->cursor_res_l
        + WML->plane_res_l[I915_MAX_PLANES]
        )

        @@ @@
        struct skl_wm_level {
        ...
        - bool plane_en[I915_MAX_PLANES];
        + bool plane_en[I915_MAX_PLANES+1];
        ...
        - bool cursor_en;
        ...
        - uint16_t plane_res_b[I915_MAX_PLANES];
        + uint16_t plane_res_b[I915_MAX_PLANES+1];
        ...
        - uint8_t plane_res_l[I915_MAX_PLANES];
        + uint8_t plane_res_l[I915_MAX_PLANES+1];
        ...
        - uint16_t cursor_res_b;
        - uint8_t cursor_res_l;
        ...
        };

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  2 +-
 drivers/gpu/drm/i915/i915_drv.h      | 20 +++-----
 drivers/gpu/drm/i915/intel_display.c |  4 +-
 drivers/gpu/drm/i915/intel_pm.c      | 89 +++++++++++++++++++-----------------
 4 files changed, 56 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 7a28de5..54508f1 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3148,7 +3148,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
 				   skl_ddb_entry_size(entry));
 		}
 
-		entry = &ddb->cursor[pipe];
+		entry = &ddb->plane[pipe][I915_MAX_PLANES];
 		seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
 			   entry->end, skl_ddb_entry_size(entry));
 	}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e0f3f05..f04b67e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1571,28 +1571,22 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
 
 struct skl_ddb_allocation {
 	struct skl_ddb_entry pipe[I915_MAX_PIPES];
-	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */
-	struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* y-plane */
-	struct skl_ddb_entry cursor[I915_MAX_PIPES];
+	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES + 1]; /* packed/uv */
+	struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
 };
 
 struct skl_wm_values {
 	bool dirty[I915_MAX_PIPES];
 	struct skl_ddb_allocation ddb;
 	uint32_t wm_linetime[I915_MAX_PIPES];
-	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
-	uint32_t cursor[I915_MAX_PIPES][8];
-	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
-	uint32_t cursor_trans[I915_MAX_PIPES];
+	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES + 1][8];
+	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES + 1];
 };
 
 struct skl_wm_level {
-	bool plane_en[I915_MAX_PLANES];
-	bool cursor_en;
-	uint16_t plane_res_b[I915_MAX_PLANES];
-	uint8_t plane_res_l[I915_MAX_PLANES];
-	uint16_t cursor_res_b;
-	uint8_t cursor_res_l;
+	bool plane_en[I915_MAX_PLANES + 1];
+	uint16_t plane_res_b[I915_MAX_PLANES + 1];
+	uint8_t plane_res_l[I915_MAX_PLANES + 1];
 };
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f604ce1..455b1bd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12552,8 +12552,8 @@ static void check_wm_state(struct drm_device *dev)
 		}
 
 		/* cursor */
-		hw_entry = &hw_ddb.cursor[pipe];
-		sw_entry = &sw_ddb->cursor[pipe];
+		hw_entry = &hw_ddb.plane[pipe][I915_MAX_PLANES];
+		sw_entry = &sw_ddb->plane[pipe][I915_MAX_PLANES];
 
 		if (skl_ddb_entry_equal(hw_entry, sw_entry))
 			continue;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d82ea82..b9bcb85 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1783,8 +1783,7 @@ struct skl_pipe_wm_parameters {
 	bool active;
 	uint32_t pipe_htotal;
 	uint32_t pixel_rate; /* in KHz */
-	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
-	struct intel_plane_wm_parameters cursor;
+	struct intel_plane_wm_parameters plane[I915_MAX_PLANES + 1];
 };
 
 struct ilk_wm_maximums {
@@ -2898,7 +2897,8 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
 		}
 
 		val = I915_READ(CUR_BUF_CFG(pipe));
-		skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val);
+		skl_ddb_entry_init_from_hw(&ddb->plane[pipe][I915_MAX_PLANES],
+					   val);
 	}
 }
 
@@ -2967,13 +2967,14 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 	alloc_size = skl_ddb_entry_size(alloc);
 	if (alloc_size == 0) {
 		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
-		memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
+		memset(&ddb->plane[pipe][I915_MAX_PLANES], 0,
+		       sizeof(ddb->plane[pipe][I915_MAX_PLANES]));
 		return;
 	}
 
 	cursor_blocks = skl_cursor_allocation(config);
-	ddb->cursor[pipe].start = alloc->end - cursor_blocks;
-	ddb->cursor[pipe].end = alloc->end;
+	ddb->plane[pipe][I915_MAX_PLANES].start = alloc->end - cursor_blocks;
+	ddb->plane[pipe][I915_MAX_PLANES].end = alloc->end;
 
 	alloc_size -= cursor_blocks;
 	alloc->end -= cursor_blocks;
@@ -3112,8 +3113,8 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
 		   sizeof(new_ddb->plane[pipe])))
 		return true;
 
-	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
-		    sizeof(new_ddb->cursor[pipe])))
+	if (memcmp(&new_ddb->plane[pipe][I915_MAX_PLANES], &cur_ddb->plane[pipe][I915_MAX_PLANES],
+		    sizeof(new_ddb->plane[pipe][I915_MAX_PLANES])))
 		return true;
 
 	return false;
@@ -3172,17 +3173,17 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
 		p->plane[0].rotation = crtc->primary->state->rotation;
 
 		fb = crtc->cursor->state->fb;
-		p->cursor.y_bytes_per_pixel = 0;
+		p->plane[I915_MAX_PLANES].y_bytes_per_pixel = 0;
 		if (fb) {
-			p->cursor.enabled = true;
-			p->cursor.bytes_per_pixel = fb->bits_per_pixel / 8;
-			p->cursor.horiz_pixels = crtc->cursor->state->crtc_w;
-			p->cursor.vert_pixels = crtc->cursor->state->crtc_h;
+			p->plane[I915_MAX_PLANES].enabled = true;
+			p->plane[I915_MAX_PLANES].bytes_per_pixel = fb->bits_per_pixel / 8;
+			p->plane[I915_MAX_PLANES].horiz_pixels = crtc->cursor->state->crtc_w;
+			p->plane[I915_MAX_PLANES].vert_pixels = crtc->cursor->state->crtc_h;
 		} else {
-			p->cursor.enabled = false;
-			p->cursor.bytes_per_pixel = 0;
-			p->cursor.horiz_pixels = 64;
-			p->cursor.vert_pixels = 64;
+			p->plane[I915_MAX_PLANES].enabled = false;
+			p->plane[I915_MAX_PLANES].bytes_per_pixel = 0;
+			p->plane[I915_MAX_PLANES].horiz_pixels = 64;
+			p->plane[I915_MAX_PLANES].vert_pixels = 64;
 		}
 	}
 
@@ -3296,11 +3297,12 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 						&result->plane_res_l[i]);
 	}
 
-	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
-	result->cursor_en = skl_compute_plane_wm(dev_priv, p, &p->cursor,
+	ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][I915_MAX_PLANES]);
+	result->plane_en[I915_MAX_PLANES] = skl_compute_plane_wm(dev_priv, p,
+						 &p->plane[I915_MAX_PLANES],
 						 ddb_blocks, level,
-						 &result->cursor_res_b,
-						 &result->cursor_res_l);
+						 &result->plane_res_b[I915_MAX_PLANES],
+						 &result->plane_res_l[I915_MAX_PLANES]);
 }
 
 static uint32_t
@@ -3328,7 +3330,7 @@ static void skl_compute_transition_wm(struct drm_crtc *crtc,
 	/* Until we know more, just disable transition WMs */
 	for (i = 0; i < intel_num_planes(intel_crtc); i++)
 		trans_wm->plane_en[i] = false;
-	trans_wm->cursor_en = false;
+	trans_wm->plane_en[I915_MAX_PLANES] = false;
 }
 
 static void skl_compute_pipe_wm(struct drm_crtc *crtc,
@@ -3377,13 +3379,13 @@ static void skl_compute_wm_results(struct drm_device *dev,
 
 		temp = 0;
 
-		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
-		temp |= p_wm->wm[level].cursor_res_b;
+		temp |= p_wm->wm[level].plane_res_l[I915_MAX_PLANES] << PLANE_WM_LINES_SHIFT;
+		temp |= p_wm->wm[level].plane_res_b[I915_MAX_PLANES];
 
-		if (p_wm->wm[level].cursor_en)
+		if (p_wm->wm[level].plane_en[I915_MAX_PLANES])
 			temp |= PLANE_WM_EN;
 
-		r->cursor[pipe][level] = temp;
+		r->plane[pipe][I915_MAX_PLANES][level] = temp;
 
 	}
 
@@ -3399,12 +3401,12 @@ static void skl_compute_wm_results(struct drm_device *dev,
 	}
 
 	temp = 0;
-	temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT;
-	temp |= p_wm->trans_wm.cursor_res_b;
-	if (p_wm->trans_wm.cursor_en)
+	temp |= p_wm->trans_wm.plane_res_l[I915_MAX_PLANES] << PLANE_WM_LINES_SHIFT;
+	temp |= p_wm->trans_wm.plane_res_b[I915_MAX_PLANES];
+	if (p_wm->trans_wm.plane_en[I915_MAX_PLANES])
 		temp |= PLANE_WM_EN;
 
-	r->cursor_trans[pipe] = temp;
+	r->plane_trans[pipe][I915_MAX_PLANES] = temp;
 
 	r->wm_linetime[pipe] = p_wm->linetime;
 }
@@ -3438,12 +3440,13 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
 				I915_WRITE(PLANE_WM(pipe, i, level),
 					   new->plane[pipe][i][level]);
 			I915_WRITE(CUR_WM(pipe, level),
-				   new->cursor[pipe][level]);
+				   new->plane[pipe][I915_MAX_PLANES][level]);
 		}
 		for (i = 0; i < intel_num_planes(crtc); i++)
 			I915_WRITE(PLANE_WM_TRANS(pipe, i),
 				   new->plane_trans[pipe][i]);
-		I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+		I915_WRITE(CUR_WM_TRANS(pipe),
+			   new->plane_trans[pipe][I915_MAX_PLANES]);
 
 		for (i = 0; i < intel_num_planes(crtc); i++) {
 			skl_ddb_entry_write(dev_priv,
@@ -3455,7 +3458,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
 		}
 
 		skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
-				    &new->ddb.cursor[pipe]);
+				    &new->ddb.plane[pipe][I915_MAX_PLANES]);
 	}
 }
 
@@ -3809,10 +3812,10 @@ static void skl_pipe_wm_active_state(uint32_t val,
 					(val >> PLANE_WM_LINES_SHIFT) &
 						PLANE_WM_LINES_MASK;
 		} else {
-			active->wm[level].cursor_en = is_enabled;
-			active->wm[level].cursor_res_b =
+			active->wm[level].plane_en[I915_MAX_PLANES] = is_enabled;
+			active->wm[level].plane_res_b[I915_MAX_PLANES] =
 					val & PLANE_WM_BLOCKS_MASK;
-			active->wm[level].cursor_res_l =
+			active->wm[level].plane_res_l[I915_MAX_PLANES] =
 					(val >> PLANE_WM_LINES_SHIFT) &
 						PLANE_WM_LINES_MASK;
 		}
@@ -3825,10 +3828,10 @@ static void skl_pipe_wm_active_state(uint32_t val,
 					(val >> PLANE_WM_LINES_SHIFT) &
 						PLANE_WM_LINES_MASK;
 		} else {
-			active->trans_wm.cursor_en = is_enabled;
-			active->trans_wm.cursor_res_b =
+			active->trans_wm.plane_en[I915_MAX_PLANES] = is_enabled;
+			active->trans_wm.plane_res_b[I915_MAX_PLANES] =
 					val & PLANE_WM_BLOCKS_MASK;
-			active->trans_wm.cursor_res_l =
+			active->trans_wm.plane_res_l[I915_MAX_PLANES] =
 					(val >> PLANE_WM_LINES_SHIFT) &
 						PLANE_WM_LINES_MASK;
 		}
@@ -3854,12 +3857,12 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 		for (i = 0; i < intel_num_planes(intel_crtc); i++)
 			hw->plane[pipe][i][level] =
 					I915_READ(PLANE_WM(pipe, i, level));
-		hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
+		hw->plane[pipe][I915_MAX_PLANES][level] = I915_READ(CUR_WM(pipe, level));
 	}
 
 	for (i = 0; i < intel_num_planes(intel_crtc); i++)
 		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
-	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
+	hw->plane_trans[pipe][I915_MAX_PLANES] = I915_READ(CUR_WM_TRANS(pipe));
 
 	if (!intel_crtc->active)
 		return;
@@ -3874,7 +3877,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 			skl_pipe_wm_active_state(temp, active, false,
 						false, i, level);
 		}
-		temp = hw->cursor[pipe][level];
+		temp = hw->plane[pipe][I915_MAX_PLANES][level];
 		skl_pipe_wm_active_state(temp, active, false, true, i, level);
 	}
 
@@ -3883,7 +3886,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 		skl_pipe_wm_active_state(temp, active, true, false, i, 0);
 	}
 
-	temp = hw->cursor_trans[pipe];
+	temp = hw->plane_trans[pipe][I915_MAX_PLANES];
 	skl_pipe_wm_active_state(temp, active, true, true, i, 0);
 }
 
-- 
2.1.4

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

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

* [PATCH 04/13] drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (2 preceding siblings ...)
  2015-08-21  1:11 ` [PATCH 03/13] drm/i915/skl: Simplify wm structures slightly Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-27 12:55   ` Ander Conselvan De Oliveira
  2015-08-21  1:11 ` [PATCH 05/13] drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check Matt Roper
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Just pull the info out of the state structures rather than staging
it in an additional set of structures.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 304 ++++++++++++++++++----------------------
 1 file changed, 135 insertions(+), 169 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b9bcb85..0cfba0a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1779,13 +1779,6 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
 	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
 }
 
-struct skl_pipe_wm_parameters {
-	bool active;
-	uint32_t pipe_htotal;
-	uint32_t pixel_rate; /* in KHz */
-	struct intel_plane_wm_parameters plane[I915_MAX_PLANES + 1];
-};
-
 struct ilk_wm_maximums {
 	uint16_t pri;
 	uint16_t spr;
@@ -2826,18 +2819,40 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
 #define SKL_DDB_SIZE		896	/* in blocks */
 #define BXT_DDB_SIZE		512
 
+/*
+ * Return the index of a plane in the SKL DDB and wm result arrays.  Primary
+ * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES, and
+ * other universal planes are in indices 1..n.  Note that this may leave
+ * unused indices between the top "sprite" plane and the cursor.
+ */
+static int
+skl_wm_plane_id(const struct intel_plane *plane)
+{
+	switch (plane->base.type) {
+	case DRM_PLANE_TYPE_PRIMARY:
+		return 0;
+	case DRM_PLANE_TYPE_CURSOR:
+		return I915_MAX_PLANES;
+	case DRM_PLANE_TYPE_OVERLAY:
+		return plane->plane;
+	default:
+		MISSING_CASE(plane->base.type);
+		return plane->plane;
+	}
+}
+
 static void
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 				   struct drm_crtc *for_crtc,
 				   const struct intel_wm_config *config,
-				   const struct skl_pipe_wm_parameters *params,
+				   const struct intel_crtc_state *cstate,
 				   struct skl_ddb_entry *alloc /* out */)
 {
 	struct drm_crtc *crtc;
 	unsigned int pipe_size, ddb_size;
 	int nth_active_pipe;
 
-	if (!params->active) {
+	if (!cstate->base.active) {
 		alloc->start = 0;
 		alloc->end = 0;
 		return;
@@ -2903,19 +2918,27 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
 }
 
 static unsigned int
-skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
+skl_plane_relative_data_rate(const struct drm_plane_state *state, int y)
 {
+	struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
+	struct drm_framebuffer *fb = state->fb;
 
 	/* for planar format */
-	if (p->y_bytes_per_pixel) {
+	if (fb->pixel_format == DRM_FORMAT_NV12) {
 		if (y)  /* y-plane data rate */
-			return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel;
+			return intel_crtc->config->pipe_src_w *
+				intel_crtc->config->pipe_src_h *
+				drm_format_plane_cpp(fb->pixel_format, 0);
 		else    /* uv-plane data rate */
-			return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel;
+			return (intel_crtc->config->pipe_src_w/2) *
+				(intel_crtc->config->pipe_src_h/2) *
+				drm_format_plane_cpp(fb->pixel_format, 1);
 	}
 
 	/* for packed formats */
-	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
+	return intel_crtc->config->pipe_src_w *
+		intel_crtc->config->pipe_src_h *
+		fb->bits_per_pixel / 8;
 }
 
 /*
@@ -2924,23 +2947,24 @@ skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
  *   3 * 4096 * 8192  * 4 < 2^32
  */
 static unsigned int
-skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
-				 const struct skl_pipe_wm_parameters *params)
+skl_get_total_relative_data_rate(const struct intel_crtc *intel_crtc)
 {
+	struct drm_device *dev = intel_crtc->base.dev;
+	const struct intel_plane *intel_plane;
 	unsigned int total_data_rate = 0;
-	int plane;
 
-	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
-		const struct intel_plane_wm_parameters *p;
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		const struct drm_plane_state *state = intel_plane->base.state;
 
-		p = &params->plane[plane];
-		if (!p->enabled)
+		if (WARN_ON(state->fb == NULL))
 			continue;
 
-		total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */
-		if (p->y_bytes_per_pixel) {
-			total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */
-		}
+		/* packed/uv */
+		total_data_rate += skl_plane_relative_data_rate(state, 0);
+
+		if (state->fb->pixel_format == DRM_FORMAT_NV12)
+			/* y-plane */
+			total_data_rate += skl_plane_relative_data_rate(state, 1);
 	}
 
 	return total_data_rate;
@@ -2949,21 +2973,20 @@ skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
 static void
 skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 		      const struct intel_wm_config *config,
-		      const struct skl_pipe_wm_parameters *params,
+		      const struct intel_crtc_state *cstate,
 		      struct skl_ddb_allocation *ddb /* out */)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_plane *intel_plane;
 	enum pipe pipe = intel_crtc->pipe;
 	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
 	uint16_t alloc_size, start, cursor_blocks;
 	uint16_t minimum[I915_MAX_PLANES];
 	uint16_t y_minimum[I915_MAX_PLANES];
 	unsigned int total_data_rate;
-	int plane;
 
-	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc);
+	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, cstate, alloc);
 	alloc_size = skl_ddb_entry_size(alloc);
 	if (alloc_size == 0) {
 		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
@@ -2980,17 +3003,20 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 	alloc->end -= cursor_blocks;
 
 	/* 1. Allocate the mininum required blocks for each active plane */
-	for_each_plane(dev_priv, pipe, plane) {
-		const struct intel_plane_wm_parameters *p;
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		struct drm_plane *plane = &intel_plane->base;
+		struct drm_framebuffer *fb = plane->fb;
+		int id = skl_wm_plane_id(intel_plane);
 
-		p = &params->plane[plane];
-		if (!p->enabled)
+		if (fb == NULL)
+			continue;
+		if (plane->type == DRM_PLANE_TYPE_CURSOR)
 			continue;
 
-		minimum[plane] = 8;
-		alloc_size -= minimum[plane];
-		y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0;
-		alloc_size -= y_minimum[plane];
+		minimum[id] = 8;
+		alloc_size -= minimum[id];
+		y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
+		alloc_size -= y_minimum[id];
 	}
 
 	/*
@@ -2999,45 +3025,45 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 	 *
 	 * FIXME: we may not allocate every single block here.
 	 */
-	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
+	total_data_rate = skl_get_total_relative_data_rate(intel_crtc);
 
 	start = alloc->start;
-	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
-		const struct intel_plane_wm_parameters *p;
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		struct drm_plane_state *state = intel_plane->base.state;
 		unsigned int data_rate, y_data_rate;
 		uint16_t plane_blocks, y_plane_blocks = 0;
+		int id = skl_wm_plane_id(intel_plane);
 
-		p = &params->plane[plane];
-		if (!p->enabled)
+		if (state->fb == NULL)
 			continue;
 
-		data_rate = skl_plane_relative_data_rate(p, 0);
+		data_rate = skl_plane_relative_data_rate(state, 0);
 
 		/*
 		 * allocation for (packed formats) or (uv-plane part of planar format):
 		 * promote the expression to 64 bits to avoid overflowing, the
 		 * result is < available as data_rate / total_data_rate < 1
 		 */
-		plane_blocks = minimum[plane];
+		plane_blocks = minimum[id];
 		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
 					total_data_rate);
 
-		ddb->plane[pipe][plane].start = start;
-		ddb->plane[pipe][plane].end = start + plane_blocks;
+		ddb->plane[pipe][id].start = start;
+		ddb->plane[pipe][id].end = start + plane_blocks;
 
 		start += plane_blocks;
 
 		/*
 		 * allocation for y_plane part of planar format:
 		 */
-		if (p->y_bytes_per_pixel) {
-			y_data_rate = skl_plane_relative_data_rate(p, 1);
-			y_plane_blocks = y_minimum[plane];
+		if (state->fb->pixel_format == DRM_FORMAT_NV12) {
+			y_data_rate = skl_plane_relative_data_rate(state, 1);
+			y_plane_blocks = y_minimum[id];
 			y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
 						total_data_rate);
 
-			ddb->y_plane[pipe][plane].start = start;
-			ddb->y_plane[pipe][plane].end = start + y_plane_blocks;
+			ddb->y_plane[pipe][id].start = start;
+			ddb->y_plane[pipe][id].end = start + y_plane_blocks;
 
 			start += y_plane_blocks;
 		}
@@ -3138,72 +3164,16 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
 	}
 }
 
-static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
-					   struct skl_pipe_wm_parameters *p)
-{
-	struct drm_device *dev = crtc->dev;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum pipe pipe = intel_crtc->pipe;
-	struct drm_plane *plane;
-	struct drm_framebuffer *fb;
-	int i = 1; /* Index for sprite planes start */
-
-	p->active = intel_crtc->active;
-	if (p->active) {
-		p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
-		p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
-
-		fb = crtc->primary->state->fb;
-		/* For planar: Bpp is for uv plane, y_Bpp is for y plane */
-		if (fb) {
-			p->plane[0].enabled = true;
-			p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
-				drm_format_plane_cpp(fb->pixel_format, 1) : fb->bits_per_pixel / 8;
-			p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
-				drm_format_plane_cpp(fb->pixel_format, 0) : 0;
-			p->plane[0].tiling = fb->modifier[0];
-		} else {
-			p->plane[0].enabled = false;
-			p->plane[0].bytes_per_pixel = 0;
-			p->plane[0].y_bytes_per_pixel = 0;
-			p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
-		}
-		p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
-		p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
-		p->plane[0].rotation = crtc->primary->state->rotation;
-
-		fb = crtc->cursor->state->fb;
-		p->plane[I915_MAX_PLANES].y_bytes_per_pixel = 0;
-		if (fb) {
-			p->plane[I915_MAX_PLANES].enabled = true;
-			p->plane[I915_MAX_PLANES].bytes_per_pixel = fb->bits_per_pixel / 8;
-			p->plane[I915_MAX_PLANES].horiz_pixels = crtc->cursor->state->crtc_w;
-			p->plane[I915_MAX_PLANES].vert_pixels = crtc->cursor->state->crtc_h;
-		} else {
-			p->plane[I915_MAX_PLANES].enabled = false;
-			p->plane[I915_MAX_PLANES].bytes_per_pixel = 0;
-			p->plane[I915_MAX_PLANES].horiz_pixels = 64;
-			p->plane[I915_MAX_PLANES].vert_pixels = 64;
-		}
-	}
-
-	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
-		struct intel_plane *intel_plane = to_intel_plane(plane);
-
-		if (intel_plane->pipe == pipe &&
-			plane->type == DRM_PLANE_TYPE_OVERLAY)
-			p->plane[i++] = intel_plane->wm;
-	}
-}
-
 static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
-				 struct skl_pipe_wm_parameters *p,
-				 struct intel_plane_wm_parameters *p_params,
+				 struct intel_crtc *intel_crtc,
+				 struct intel_plane *intel_plane,
 				 uint16_t ddb_allocation,
 				 int level,
 				 uint16_t *out_blocks, /* out */
 				 uint8_t *out_lines /* out */)
 {
+	struct drm_plane *plane = &intel_plane->base;
+	struct drm_framebuffer *fb = plane->state->fb;
 	uint32_t latency = dev_priv->wm.skl_latency[level];
 	uint32_t method1, method2;
 	uint32_t plane_bytes_per_line, plane_blocks_per_line;
@@ -3211,31 +3181,35 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	uint32_t selected_result;
 	uint8_t bytes_per_pixel;
 
-	if (latency == 0 || !p->active || !p_params->enabled)
+	if (latency == 0 || !intel_crtc->active || !fb)
 		return false;
 
-	bytes_per_pixel = p_params->y_bytes_per_pixel ?
-		p_params->y_bytes_per_pixel :
-		p_params->bytes_per_pixel;
-	method1 = skl_wm_method1(p->pixel_rate,
+	bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
+		drm_format_plane_cpp(DRM_FORMAT_NV12, 0) :
+		fb->bits_per_pixel / 8;
+	method1 = skl_wm_method1(skl_pipe_pixel_rate(intel_crtc->config),
 				 bytes_per_pixel,
 				 latency);
-	method2 = skl_wm_method2(p->pixel_rate,
-				 p->pipe_htotal,
-				 p_params->horiz_pixels,
+	method2 = skl_wm_method2(skl_pipe_pixel_rate(intel_crtc->config),
+				 intel_crtc->config->base.adjusted_mode.crtc_htotal,
+				 intel_crtc->config->pipe_src_w,
 				 bytes_per_pixel,
-				 p_params->tiling,
+				 fb->modifier[0],
 				 latency);
 
-	plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel;
+	plane_bytes_per_line = intel_crtc->config->pipe_src_w * bytes_per_pixel;
 	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
 
-	if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
-	    p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
+	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
 		uint32_t min_scanlines = 4;
 		uint32_t y_tile_minimum;
-		if (intel_rotation_90_or_270(p_params->rotation)) {
-			switch (p_params->bytes_per_pixel) {
+		if (intel_rotation_90_or_270(plane->state->rotation)) {
+			int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
+				drm_format_plane_cpp(fb->pixel_format, 1) :
+				fb->bits_per_pixel / 8;
+
+			switch (bpp) {
 			case 1:
 				min_scanlines = 16;
 				break;
@@ -3259,8 +3233,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
 
 	if (level >= 1 && level <= 7) {
-		if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
-		    p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
+		if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
 			res_lines += 4;
 		else
 			res_blocks++;
@@ -3277,65 +3251,64 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 
 static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 				 struct skl_ddb_allocation *ddb,
-				 struct skl_pipe_wm_parameters *p,
-				 enum pipe pipe,
+				 struct intel_crtc *intel_crtc,
 				 int level,
-				 int num_planes,
 				 struct skl_wm_level *result)
 {
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct intel_plane *intel_plane;
 	uint16_t ddb_blocks;
-	int i;
+	enum pipe pipe = intel_crtc->pipe;
+
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		int i = skl_wm_plane_id(intel_plane);
 
-	for (i = 0; i < num_planes; i++) {
 		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
 
 		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
-						p, &p->plane[i],
+						intel_crtc,
+						intel_plane,
 						ddb_blocks,
 						level,
 						&result->plane_res_b[i],
 						&result->plane_res_l[i]);
 	}
-
-	ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][I915_MAX_PLANES]);
-	result->plane_en[I915_MAX_PLANES] = skl_compute_plane_wm(dev_priv, p,
-						 &p->plane[I915_MAX_PLANES],
-						 ddb_blocks, level,
-						 &result->plane_res_b[I915_MAX_PLANES],
-						 &result->plane_res_l[I915_MAX_PLANES]);
 }
 
 static uint32_t
-skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
+skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 {
-	if (!to_intel_crtc(crtc)->active)
+	if (!cstate->base.active)
 		return 0;
 
-	if (WARN_ON(p->pixel_rate == 0))
+	if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
 		return 0;
 
-	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
+	return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
+			    skl_pipe_pixel_rate(cstate));
 }
 
-static void skl_compute_transition_wm(struct drm_crtc *crtc,
-				      struct skl_pipe_wm_parameters *params,
+static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
 				      struct skl_wm_level *trans_wm /* out */)
 {
+	struct drm_crtc *crtc = cstate->base.crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	int i;
+	struct intel_plane *intel_plane;
 
-	if (!params->active)
+	if (!cstate->base.active)
 		return;
 
 	/* Until we know more, just disable transition WMs */
-	for (i = 0; i < intel_num_planes(intel_crtc); i++)
+	for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
+		int i = skl_wm_plane_id(intel_plane);
+
 		trans_wm->plane_en[i] = false;
-	trans_wm->plane_en[I915_MAX_PLANES] = false;
+	}
 }
 
 static void skl_compute_pipe_wm(struct drm_crtc *crtc,
 				struct skl_ddb_allocation *ddb,
-				struct skl_pipe_wm_parameters *params,
+				struct intel_crtc_state *cstate,
 				struct skl_pipe_wm *pipe_wm)
 {
 	struct drm_device *dev = crtc->dev;
@@ -3344,17 +3317,15 @@ static void skl_compute_pipe_wm(struct drm_crtc *crtc,
 	int level, max_level = ilk_wm_max_level(dev);
 
 	for (level = 0; level <= max_level; level++) {
-		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
-				     level, intel_num_planes(intel_crtc),
-				     &pipe_wm->wm[level]);
+		skl_compute_wm_level(dev_priv, ddb, intel_crtc,
+				     level, &pipe_wm->wm[level]);
 	}
-	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
+	pipe_wm->linetime = skl_compute_linetime_wm(cstate);
 
-	skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm);
+	skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
 }
 
 static void skl_compute_wm_results(struct drm_device *dev,
-				   struct skl_pipe_wm_parameters *p,
 				   struct skl_pipe_wm *p_wm,
 				   struct skl_wm_values *r,
 				   struct intel_crtc *intel_crtc)
@@ -3598,16 +3569,15 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 }
 
 static bool skl_update_pipe_wm(struct drm_crtc *crtc,
-			       struct skl_pipe_wm_parameters *params,
 			       struct intel_wm_config *config,
 			       struct skl_ddb_allocation *ddb, /* out */
 			       struct skl_pipe_wm *pipe_wm /* out */)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
-	skl_compute_wm_pipe_parameters(crtc, params);
-	skl_allocate_pipe_ddb(crtc, config, params, ddb);
-	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
+	skl_allocate_pipe_ddb(crtc, config, cstate, ddb);
+	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
 		return false;
@@ -3640,7 +3610,6 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 	 */
 	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
 				base.head) {
-		struct skl_pipe_wm_parameters params = {};
 		struct skl_pipe_wm pipe_wm = {};
 		bool wm_changed;
 
@@ -3650,8 +3619,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		if (!intel_crtc->active)
 			continue;
 
-		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
-						&params, config,
+		wm_changed = skl_update_pipe_wm(&intel_crtc->base, config,
 						&r->ddb, &pipe_wm);
 
 		/*
@@ -3661,7 +3629,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		 */
 		WARN_ON(!wm_changed);
 
-		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
+		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
 		r->dirty[intel_crtc->pipe] = true;
 	}
 }
@@ -3671,7 +3639,6 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct skl_pipe_wm_parameters params = {};
 	struct skl_wm_values *results = &dev_priv->wm.skl_results;
 	struct skl_pipe_wm pipe_wm = {};
 	struct intel_wm_config config = {};
@@ -3680,11 +3647,10 @@ static void skl_update_wm(struct drm_crtc *crtc)
 
 	skl_compute_wm_global_parameters(dev, &config);
 
-	if (!skl_update_pipe_wm(crtc, &params, &config,
-				&results->ddb, &pipe_wm))
+	if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
 		return;
 
-	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
+	skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
 	results->dirty[intel_crtc->pipe] = true;
 
 	skl_update_other_pipe_wm(dev, crtc, &config, results);
-- 
2.1.4

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

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

* [PATCH 05/13] drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (3 preceding siblings ...)
  2015-08-21  1:11 ` [PATCH 04/13] drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-21  1:11 ` [PATCH 06/13] drm/i915: Drop intel_update_sprite_watermarks Matt Roper
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Determine whether we need to apply this workaround at atomic check time
and just set a flag that will be used by the main watermark update
routine.

Moving this workaround into the atomic framework reduces
ilk_update_sprite_wm() to just a standard watermark update, so drop it
completely and just ensure that ilk_update_wm() is called whenever a
sprite plane is updated in a way that would affect watermarks.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  |  1 +
 drivers/gpu/drm/i915/intel_display.c | 40 +++++++++++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_drv.h     |  3 +++
 drivers/gpu/drm/i915/intel_pm.c      | 35 +++++++++++--------------------
 4 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 9336e80..244d6bb 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -100,6 +100,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
 
 	crtc_state->base.crtc = crtc;
+	crtc_state->disable_lp_wm = false;
 
 	return &crtc_state->base;
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 455b1bd..16e5cb6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11536,23 +11536,38 @@ retry:
 static bool intel_wm_need_update(struct drm_plane *plane,
 				 struct drm_plane_state *state)
 {
-	/* Update watermarks on tiling changes. */
+	struct intel_plane_state *new = to_intel_plane_state(state);
+	struct intel_plane_state *cur = to_intel_plane_state(plane->state);
+
+	/* Update watermarks on tiling or size changes. */
 	if (!plane->state->fb || !state->fb ||
 	    plane->state->fb->modifier[0] != state->fb->modifier[0] ||
-	    plane->state->rotation != state->rotation)
-		return true;
-
-	if (plane->state->crtc_w != state->crtc_w)
+	    plane->state->rotation != state->rotation ||
+	    drm_rect_width(&new->src) != drm_rect_width(&cur->src) ||
+	    drm_rect_height(&new->src) != drm_rect_height(&cur->src) ||
+	    drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) ||
+	    drm_rect_height(&new->dst) != drm_rect_height(&cur->dst))
 		return true;
 
 	return false;
 }
 
+static bool needs_scaling(struct intel_plane_state *state)
+{
+	int src_w = drm_rect_width(&state->src) >> 16;
+	int src_h = drm_rect_height(&state->src) >> 16;
+	int dst_w = drm_rect_width(&state->dst);
+	int dst_h = drm_rect_height(&state->dst);
+
+	return (src_w != dst_w || src_h != dst_h);
+}
+
 int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 				    struct drm_plane_state *plane_state)
 {
 	struct drm_crtc *crtc = crtc_state->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc_state);
 	struct drm_plane *plane = plane_state->plane;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -11563,7 +11578,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 	bool mode_changed = needs_modeset(crtc_state);
 	bool was_crtc_enabled = crtc->state->active;
 	bool is_crtc_enabled = crtc_state->active;
-
 	bool turn_off, turn_on, visible, was_visible;
 	struct drm_framebuffer *fb = plane_state->fb;
 
@@ -11681,11 +11695,23 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 	case DRM_PLANE_TYPE_CURSOR:
 		break;
 	case DRM_PLANE_TYPE_OVERLAY:
-		if (turn_off && !mode_changed) {
+		/*
+		 * WaCxSRDisabledForSpriteScaling:ivb
+		 *
+		 * atomic.update_wm was already set above, so this flag will
+		 * take effect when we commit and program watermarks.
+		 */
+		if (IS_IVYBRIDGE(dev) &&
+		    needs_scaling(to_intel_plane_state(plane_state)) &&
+		    !needs_scaling(old_plane_state)) {
+			cstate->disable_lp_wm = true;
+		} else if (turn_off && !mode_changed) {
 			intel_crtc->atomic.wait_vblank = true;
 			intel_crtc->atomic.update_sprite_watermarks |=
 				1 << i;
 		}
+
+		break;
 	}
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 81b7d77..da145b0 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -455,6 +455,9 @@ struct intel_crtc_state {
 
 	/* w/a for waiting 2 vblanks during crtc enable */
 	enum pipe hsw_workaround_pipe;
+
+	/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
+	bool disable_lp_wm;
 };
 
 struct vlv_wm_state {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0cfba0a..d6792d8 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3707,6 +3707,18 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
 	struct intel_wm_config config = {};
 
+	/*
+	 * IVB workaround: must disable low power watermarks for at least
+	 * one frame before enabling scaling.  LP watermarks can be re-enabled
+	 * when scaling is disabled.
+	 *
+	 * WaCxSRDisabledForSpriteScaling:ivb
+	 */
+	if (cstate->disable_lp_wm) {
+		ilk_disable_lp_wm(dev);
+		intel_wait_for_vblank(dev, intel_crtc->pipe);
+	}
+
 	intel_compute_pipe_wm(cstate, &pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
@@ -3738,28 +3750,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 	ilk_write_wm_values(dev_priv, &results);
 }
 
-static void
-ilk_update_sprite_wm(struct drm_plane *plane,
-		     struct drm_crtc *crtc,
-		     uint32_t sprite_width, uint32_t sprite_height,
-		     int pixel_size, bool enabled, bool scaled)
-{
-	struct drm_device *dev = plane->dev;
-	struct intel_plane *intel_plane = to_intel_plane(plane);
-
-	/*
-	 * IVB workaround: must disable low power watermarks for at least
-	 * one frame before enabling scaling.  LP watermarks can be re-enabled
-	 * when scaling is disabled.
-	 *
-	 * WaCxSRDisabledForSpriteScaling:ivb
-	 */
-	if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev))
-		intel_wait_for_vblank(dev, intel_plane->pipe);
-
-	ilk_update_wm(crtc);
-}
-
 static void skl_pipe_wm_active_state(uint32_t val,
 				     struct skl_pipe_wm *active,
 				     bool is_transwm,
@@ -7050,7 +7040,6 @@ void intel_init_pm(struct drm_device *dev)
 		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
 		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
 			dev_priv->display.update_wm = ilk_update_wm;
-			dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;
 		} else {
 			DRM_DEBUG_KMS("Failed to read display plane latency. "
 				      "Disable CxSR\n");
-- 
2.1.4

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

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

* [PATCH 06/13] drm/i915: Drop intel_update_sprite_watermarks
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (4 preceding siblings ...)
  2015-08-21  1:11 ` [PATCH 05/13] drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-21  1:11 ` [PATCH 07/13] drm/i915: Refactor ilk_update_wm (v3) Matt Roper
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

The only platform that still has an update_sprite_wm entrypoint is SKL;
on SKL, intel_update_sprite_watermarks just updates intel_plane->wm and
then performs a regular watermark update.  However intel_plane->wm is
only used to update a couple fields in intel_wm_config, and those fields
are never used by the SKL code, so on SKL an update_sprite_wm is
effectively identical to an update_wm call.  Since we're already
ensuring that the regular intel_update_wm is called any time we'd try to
call intel_update_sprite_watermarks, the whole call is redundant and can
be dropped.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  4 ---
 drivers/gpu/drm/i915/intel_display.c |  5 ----
 drivers/gpu/drm/i915/intel_drv.h     |  6 ----
 drivers/gpu/drm/i915/intel_pm.c      | 58 ------------------------------------
 drivers/gpu/drm/i915/intel_sprite.c  | 15 ----------
 5 files changed, 88 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f04b67e..7c58f38 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -621,10 +621,6 @@ struct drm_i915_display_funcs {
 			  struct dpll *match_clock,
 			  struct dpll *best_clock);
 	void (*update_wm)(struct drm_crtc *crtc);
-	void (*update_sprite_wm)(struct drm_plane *plane,
-				 struct drm_crtc *crtc,
-				 uint32_t sprite_width, uint32_t sprite_height,
-				 int pixel_size, bool enable, bool scaled);
 	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
 	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
 	/* Returns the active state of the crtc, and if the crtc is active,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 16e5cb6..6bcc3da 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4752,7 +4752,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
 	struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_plane *plane;
 
 	if (atomic->wait_vblank)
 		intel_wait_for_vblank(dev, crtc->pipe);
@@ -4771,10 +4770,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
 	if (atomic->post_enable_primary)
 		intel_post_enable_primary(&crtc->base);
 
-	drm_for_each_plane_mask(plane, dev, atomic->update_sprite_watermarks)
-		intel_update_sprite_watermarks(plane, &crtc->base,
-					       0, 0, 0, false, false);
-
 	memset(atomic, 0, sizeof(*atomic));
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index da145b0..65f0171 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1352,12 +1352,6 @@ void intel_init_clock_gating(struct drm_device *dev);
 void intel_suspend_hw(struct drm_device *dev);
 int ilk_wm_max_level(const struct drm_device *dev);
 void intel_update_watermarks(struct drm_crtc *crtc);
-void intel_update_sprite_watermarks(struct drm_plane *plane,
-				    struct drm_crtc *crtc,
-				    uint32_t sprite_width,
-				    uint32_t sprite_height,
-				    int pixel_size,
-				    bool enabled, bool scaled);
 void intel_init_pm(struct drm_device *dev);
 void intel_pm_setup(struct drm_device *dev);
 void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d6792d8..399e3b5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3150,18 +3150,9 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
 					     struct intel_wm_config *config)
 {
 	struct drm_crtc *crtc;
-	struct drm_plane *plane;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 		config->num_pipes_active += to_intel_crtc(crtc)->active;
-
-	/* FIXME: I don't think we need those two global parameters on SKL */
-	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
-		struct intel_plane *intel_plane = to_intel_plane(plane);
-
-		config->sprites_enabled |= intel_plane->wm.enabled;
-		config->sprites_scaled |= intel_plane->wm.scaled;
-	}
 }
 
 static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
@@ -3661,39 +3652,6 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	dev_priv->wm.skl_hw = *results;
 }
 
-static void
-skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
-		     uint32_t sprite_width, uint32_t sprite_height,
-		     int pixel_size, bool enabled, bool scaled)
-{
-	struct intel_plane *intel_plane = to_intel_plane(plane);
-	struct drm_framebuffer *fb = plane->state->fb;
-
-	intel_plane->wm.enabled = enabled;
-	intel_plane->wm.scaled = scaled;
-	intel_plane->wm.horiz_pixels = sprite_width;
-	intel_plane->wm.vert_pixels = sprite_height;
-	intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE;
-
-	/* For planar: Bpp is for UV plane, y_Bpp is for Y plane */
-	intel_plane->wm.bytes_per_pixel =
-		(fb && fb->pixel_format == DRM_FORMAT_NV12) ?
-		drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size;
-	intel_plane->wm.y_bytes_per_pixel =
-		(fb && fb->pixel_format == DRM_FORMAT_NV12) ?
-		drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0;
-
-	/*
-	 * Framebuffer can be NULL on plane disable, but it does not
-	 * matter for watermarks if we assume no tiling in that case.
-	 */
-	if (fb)
-		intel_plane->wm.tiling = fb->modifier[0];
-	intel_plane->wm.rotation = plane->state->rotation;
-
-	skl_update_wm(crtc);
-}
-
 static void ilk_update_wm(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -4107,21 +4065,6 @@ void intel_update_watermarks(struct drm_crtc *crtc)
 		dev_priv->display.update_wm(crtc);
 }
 
-void intel_update_sprite_watermarks(struct drm_plane *plane,
-				    struct drm_crtc *crtc,
-				    uint32_t sprite_width,
-				    uint32_t sprite_height,
-				    int pixel_size,
-				    bool enabled, bool scaled)
-{
-	struct drm_i915_private *dev_priv = plane->dev->dev_private;
-
-	if (dev_priv->display.update_sprite_wm)
-		dev_priv->display.update_sprite_wm(plane, crtc,
-						   sprite_width, sprite_height,
-						   pixel_size, enabled, scaled);
-}
-
 /**
  * Lock protecting IPS related data structures
  */
@@ -7031,7 +6974,6 @@ void intel_init_pm(struct drm_device *dev)
 			dev_priv->display.init_clock_gating =
 				skl_init_clock_gating;
 		dev_priv->display.update_wm = skl_update_wm;
-		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 9d8af2f..3363334 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -178,7 +178,6 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	const int pipe = intel_plane->pipe;
 	const int plane = intel_plane->plane + 1;
 	u32 plane_ctl, stride_div, stride;
-	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 	const struct drm_intel_sprite_colorkey *key =
 		&to_intel_plane_state(drm_plane->state)->ckey;
 	unsigned long surf_addr;
@@ -197,10 +196,6 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	rotation = drm_plane->state->rotation;
 	plane_ctl |= skl_plane_ctl_rotation(rotation);
 
-	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
-				       pixel_size, true,
-				       src_w != crtc_w || src_h != crtc_h);
-
 	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
 					       fb->pixel_format);
 
@@ -282,8 +277,6 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
 
 	I915_WRITE(PLANE_SURF(pipe, plane), 0);
 	POSTING_READ(PLANE_SURF(pipe, plane));
-
-	intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
 }
 
 static void
@@ -526,10 +519,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		sprctl |= SPRITE_PIPE_CSC_ENABLE;
 
-	intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
-				       true,
-				       src_w != crtc_w || src_h != crtc_h);
-
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
@@ -663,10 +652,6 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	if (IS_GEN6(dev))
 		dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
 
-	intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
-				       pixel_size, true,
-				       src_w != crtc_w || src_h != crtc_h);
-
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
-- 
2.1.4

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

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

* [PATCH 07/13] drm/i915: Refactor ilk_update_wm (v3)
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (5 preceding siblings ...)
  2015-08-21  1:11 ` [PATCH 06/13] drm/i915: Drop intel_update_sprite_watermarks Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-21  1:11 ` [PATCH 08/13] drm/i915: Move active watermarks into CRTC state (v2) Matt Roper
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

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

Split ilk_update_wm() into two parts; one doing the programming
and the other the calculations.

v2: Fix typo in commit message

v3 (by Matt): Heavily rebased for current codebase.

Reviewed-by(v2): Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 60 ++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 399e3b5..5b79c2f 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3652,37 +3652,14 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	dev_priv->wm.skl_hw = *results;
 }
 
-static void ilk_update_wm(struct drm_crtc *crtc)
+static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
 	struct ilk_wm_maximums max;
+	struct intel_wm_config config = {};
 	struct ilk_wm_values results = {};
 	enum intel_ddb_partitioning partitioning;
-	struct intel_pipe_wm pipe_wm = {};
-	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
-	struct intel_wm_config config = {};
-
-	/*
-	 * IVB workaround: must disable low power watermarks for at least
-	 * one frame before enabling scaling.  LP watermarks can be re-enabled
-	 * when scaling is disabled.
-	 *
-	 * WaCxSRDisabledForSpriteScaling:ivb
-	 */
-	if (cstate->disable_lp_wm) {
-		ilk_disable_lp_wm(dev);
-		intel_wait_for_vblank(dev, intel_crtc->pipe);
-	}
-
-	intel_compute_pipe_wm(cstate, &pipe_wm);
-
-	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
-		return;
-
-	intel_crtc->wm.active = pipe_wm;
 
 	ilk_compute_wm_config(dev, &config);
 
@@ -3708,6 +3685,35 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 	ilk_write_wm_values(dev_priv, &results);
 }
 
+static void ilk_update_wm(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct intel_pipe_wm pipe_wm = {};
+
+	/*
+	 * IVB workaround: must disable low power watermarks for at least
+	 * one frame before enabling scaling.  LP watermarks can be re-enabled
+	 * when scaling is disabled.
+	 *
+	 * WaCxSRDisabledForSpriteScaling:ivb
+	 */
+	if (cstate->disable_lp_wm) {
+		ilk_disable_lp_wm(crtc->dev);
+		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
+	}
+
+	intel_compute_pipe_wm(cstate, &pipe_wm);
+
+	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
+		return;
+
+	intel_crtc->wm.active = pipe_wm;
+
+	ilk_program_watermarks(dev_priv);
+}
+
 static void skl_pipe_wm_active_state(uint32_t val,
 				     struct skl_pipe_wm *active,
 				     bool is_transwm,
-- 
2.1.4

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

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

* [PATCH 08/13] drm/i915: Move active watermarks into CRTC state (v2)
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (6 preceding siblings ...)
  2015-08-21  1:11 ` [PATCH 07/13] drm/i915: Refactor ilk_update_wm (v3) Matt Roper
@ 2015-08-21  1:11 ` Matt Roper
  2015-08-26 13:10   ` Ville Syrjälä
  2015-08-21  1:12 ` [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2) Matt Roper
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Since we allocate a few CRTC states on the stack, also switch the 'wm'
struct here to be a union so that we're not wasting stack space with
other platforms' watermark values.

v2: Don't move cxsr_allowed to state (Maarten)

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h | 45 +++++++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_pm.c  | 30 ++++++++++++++++-----------
 2 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 65f0171..dfbfba9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -323,6 +323,21 @@ struct intel_crtc_scaler_state {
 /* drm_mode->private_flags */
 #define I915_MODE_FLAG_INHERITED 1
 
+struct intel_pipe_wm {
+	struct intel_wm_level wm[5];
+	uint32_t linetime;
+	bool fbc_wm_enabled;
+	bool pipe_enabled;
+	bool sprites_enabled;
+	bool sprites_scaled;
+};
+
+struct skl_pipe_wm {
+	struct skl_wm_level wm[8];
+	struct skl_wm_level trans_wm;
+	uint32_t linetime;
+};
+
 struct intel_crtc_state {
 	struct drm_crtc_state base;
 
@@ -458,6 +473,17 @@ struct intel_crtc_state {
 
 	/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
 	bool disable_lp_wm;
+
+	struct {
+		/*
+		 * final watermarks, programmed post-vblank when this state
+		 * is committed
+		 */
+		union {
+			struct intel_pipe_wm ilk;
+			struct skl_pipe_wm skl;
+		} active;
+	} wm;
 };
 
 struct vlv_wm_state {
@@ -469,15 +495,6 @@ struct vlv_wm_state {
 	bool cxsr;
 };
 
-struct intel_pipe_wm {
-	struct intel_wm_level wm[5];
-	uint32_t linetime;
-	bool fbc_wm_enabled;
-	bool pipe_enabled;
-	bool sprites_enabled;
-	bool sprites_scaled;
-};
-
 struct intel_mmio_flip {
 	struct work_struct work;
 	struct drm_i915_private *i915;
@@ -485,12 +502,6 @@ struct intel_mmio_flip {
 	struct intel_crtc *crtc;
 };
 
-struct skl_pipe_wm {
-	struct skl_wm_level wm[8];
-	struct skl_wm_level trans_wm;
-	uint32_t linetime;
-};
-
 /*
  * Tracking of operations that need to be performed at the beginning/end of an
  * atomic commit, outside the atomic section where interrupts are disabled.
@@ -555,10 +566,6 @@ struct intel_crtc {
 
 	/* per-pipe watermark state */
 	struct {
-		/* watermarks currently being used  */
-		struct intel_pipe_wm active;
-		/* SKL wm values currently in use */
-		struct skl_pipe_wm skl_active;
 		/* allow CxSR on this pipe */
 		bool cxsr_allowed;
 	} wm;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5b79c2f..04fc092 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2345,7 +2345,9 @@ static void ilk_compute_wm_config(struct drm_device *dev,
 
 	/* Compute the currently _active_ config */
 	for_each_intel_crtc(dev, intel_crtc) {
-		const struct intel_pipe_wm *wm = &intel_crtc->wm.active;
+		const struct intel_crtc_state *cstate =
+			to_intel_crtc_state(intel_crtc->base.state);
+		const struct intel_pipe_wm *wm = &cstate->wm.active.ilk;
 
 		if (!wm->pipe_enabled)
 			continue;
@@ -2442,7 +2444,9 @@ static void ilk_merge_wm_level(struct drm_device *dev,
 	ret_wm->enable = true;
 
 	for_each_intel_crtc(dev, intel_crtc) {
-		const struct intel_pipe_wm *active = &intel_crtc->wm.active;
+		const struct intel_crtc_state *cstate =
+			to_intel_crtc_state(intel_crtc->base.state);
+		const struct intel_pipe_wm *active = &cstate->wm.active.ilk;
 		const struct intel_wm_level *wm = &active->wm[level];
 
 		if (!active->pipe_enabled)
@@ -2590,14 +2594,15 @@ static void ilk_compute_wm_results(struct drm_device *dev,
 
 	/* LP0 register values */
 	for_each_intel_crtc(dev, intel_crtc) {
+		const struct intel_crtc_state *cstate =
+			to_intel_crtc_state(intel_crtc->base.state);
 		enum pipe pipe = intel_crtc->pipe;
-		const struct intel_wm_level *r =
-			&intel_crtc->wm.active.wm[0];
+		const struct intel_wm_level *r = &cstate->wm.active.ilk.wm[0];
 
 		if (WARN_ON(!r->enable))
 			continue;
 
-		results->wm_linetime[pipe] = intel_crtc->wm.active.linetime;
+		results->wm_linetime[pipe] = cstate->wm.active.ilk.linetime;
 
 		results->wm_pipe[pipe] =
 			(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
@@ -3564,16 +3569,15 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 			       struct skl_ddb_allocation *ddb, /* out */
 			       struct skl_pipe_wm *pipe_wm /* out */)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
 	skl_allocate_pipe_ddb(crtc, config, cstate, ddb);
 	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
 
-	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
+	if (!memcmp(&cstate->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
 		return false;
 
-	intel_crtc->wm.skl_active = *pipe_wm;
+	cstate->wm.active.skl = *pipe_wm;
 
 	return true;
 }
@@ -3706,10 +3710,10 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 
 	intel_compute_pipe_wm(cstate, &pipe_wm);
 
-	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
+	if (!memcmp(&cstate->wm.active.ilk, &pipe_wm, sizeof(pipe_wm)))
 		return;
 
-	intel_crtc->wm.active = pipe_wm;
+	cstate->wm.active.ilk = pipe_wm;
 
 	ilk_program_watermarks(dev_priv);
 }
@@ -3764,7 +3768,8 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct skl_pipe_wm *active = &cstate->wm.active.skl;
 	enum pipe pipe = intel_crtc->pipe;
 	int level, i, max_level;
 	uint32_t temp;
@@ -3827,7 +3832,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct ilk_wm_values *hw = &dev_priv->wm.hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_pipe_wm *active = &intel_crtc->wm.active;
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct intel_pipe_wm *active = &cstate->wm.active.ilk;
 	enum pipe pipe = intel_crtc->pipe;
 	static const unsigned int wm0_pipe_reg[] = {
 		[PIPE_A] = WM0_PIPEA_ILK,
-- 
2.1.4

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

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

* [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2)
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (7 preceding siblings ...)
  2015-08-21  1:11 ` [PATCH 08/13] drm/i915: Move active watermarks into CRTC state (v2) Matt Roper
@ 2015-08-21  1:12 ` Matt Roper
  2015-08-28 12:53   ` Ander Conselvan De Oliveira
  2015-08-28 12:56   ` Ander Conselvan De Oliveira
  2015-08-21  1:12 ` [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check Matt Roper
                   ` (4 subsequent siblings)
  13 siblings, 2 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Calculate pipe watermarks during atomic calculation phase, based on the
contents of the atomic transaction's state structure.  We still program
the watermarks at the same time we did before, but the computation now
happens much earlier.

While this patch isn't too exciting by itself, it paves the way for
future patches.  The eventual goal (which will be realized in future
patches in this series) is to calculate multiple sets up watermark
values up front, and then program them at different times (pre- vs
post-vblank) on the platforms that need a two-step watermark update.

While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since
this function only applies to ILK-style watermarks and we have a
completely different function for SKL-style watermarks.

Note that the original code had a memcmp() in ilk_update_wm() to avoid
calling ilk_program_watermarks() if the watermarks hadn't changed.  This
memcmp vanishes here, which means we may do some unnecessary result
generation and merging in cases where watermarks didn't change, but the
lower-level function ilk_write_wm_values already makes sure that we
don't actually try to program the watermark registers again.

v2: Squash a few commits from the original series together; no longer
    leave pre-calculated wm's in a separate temporary structure since
    it's easier to follow the logic if we just cut over to using the
    pre-calculated values directly.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  2 +
 drivers/gpu/drm/i915/intel_display.c |  6 +++
 drivers/gpu/drm/i915/intel_drv.h     |  2 +
 drivers/gpu/drm/i915/intel_pm.c      | 87 ++++++++++++++++++------------------
 4 files changed, 53 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7c58f38..c91bab9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -620,6 +620,8 @@ struct drm_i915_display_funcs {
 			  int target, int refclk,
 			  struct dpll *match_clock,
 			  struct dpll *best_clock);
+	int (*compute_pipe_wm)(struct drm_crtc *crtc,
+			       struct drm_atomic_state *state);
 	void (*update_wm)(struct drm_crtc *crtc);
 	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
 	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6bcc3da..c40f025 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11791,6 +11791,12 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	ret = 0;
+	if (dev_priv->display.compute_pipe_wm) {
+		ret = dev_priv->display.compute_pipe_wm(crtc, state);
+		if (ret)
+			return ret;
+	}
+
 	if (INTEL_INFO(dev)->gen >= 9) {
 		if (mode_changed)
 			ret = skl_update_scaler_crtc(pipe_config);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index dfbfba9..f9cac4b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1427,6 +1427,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 int intel_atomic_setup_scalers(struct drm_device *dev,
 	struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state);
+int intel_check_crtc(struct drm_crtc *crtc,
+		     struct drm_crtc_state *state);
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 04fc092..bc29260 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2043,9 +2043,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 				 const struct intel_crtc *intel_crtc,
 				 int level,
 				 struct intel_crtc_state *cstate,
+				 struct intel_plane_state *pristate,
+				 struct intel_plane_state *sprstate,
+				 struct intel_plane_state *curstate,
 				 struct intel_wm_level *result)
 {
-	struct intel_plane *intel_plane;
 	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];
@@ -2057,29 +2059,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 		cur_latency *= 5;
 	}
 
-	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
-		struct intel_plane_state *pstate =
-			to_intel_plane_state(intel_plane->base.state);
-
-		switch (intel_plane->base.type) {
-		case DRM_PLANE_TYPE_PRIMARY:
-			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
-							     pri_latency,
-							     level);
-			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
-							     result->pri_val);
-			break;
-		case DRM_PLANE_TYPE_OVERLAY:
-			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
-							     spr_latency);
-			break;
-		case DRM_PLANE_TYPE_CURSOR:
-			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
-							     cur_latency);
-			break;
-		}
-	}
-
+	result->pri_val = ilk_compute_pri_wm(cstate, pristate,
+					     pri_latency, level);
+	result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
+	result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
+	result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
 	result->enable = true;
 }
 
@@ -2359,15 +2343,20 @@ static void ilk_compute_wm_config(struct drm_device *dev,
 }
 
 /* Compute new watermarks for the pipe */
-static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
-				  struct intel_pipe_wm *pipe_wm)
+static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
+			       struct drm_atomic_state *state)
 {
-	struct drm_crtc *crtc = cstate->base.crtc;
+	struct intel_pipe_wm *pipe_wm;
 	struct drm_device *dev = crtc->dev;
 	const struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_crtc_state *cs;
+	struct intel_crtc_state *cstate = NULL;
 	struct intel_plane *intel_plane;
+	struct drm_plane_state *ps;
+	struct intel_plane_state *pristate = NULL;
 	struct intel_plane_state *sprstate = NULL;
+	struct intel_plane_state *curstate = NULL;
 	int level, max_level = ilk_wm_max_level(dev);
 	/* LP0 watermark maximums depend on this pipe alone */
 	struct intel_wm_config config = {
@@ -2375,11 +2364,26 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 	};
 	struct ilk_wm_maximums max;
 
+	cs = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+	else
+		cstate = to_intel_crtc_state(cs);
+
+	pipe_wm = &cstate->wm.active.ilk;
+
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
-		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
-			sprstate = to_intel_plane_state(intel_plane->base.state);
-			break;
-		}
+		ps = drm_atomic_get_plane_state(state,
+						&intel_plane->base);
+		if (IS_ERR(ps))
+			return PTR_ERR(ps);
+
+		if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+			pristate = to_intel_plane_state(ps);
+		else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
+			sprstate = to_intel_plane_state(ps);
+		else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
+			curstate = to_intel_plane_state(ps);
 	}
 
 	config.sprites_enabled = sprstate->visible;
@@ -2388,7 +2392,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
 
 	pipe_wm->pipe_enabled = cstate->base.active;
-	pipe_wm->sprites_enabled = sprstate->visible;
+	pipe_wm->sprites_enabled = config.sprites_enabled;
 	pipe_wm->sprites_scaled = config.sprites_scaled;
 
 	/* ILK/SNB: LP2+ watermarks only w/o sprites */
@@ -2399,7 +2403,8 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 	if (config.sprites_scaled)
 		max_level = 0;
 
-	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
+	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
+			     pristate, sprstate, curstate, &pipe_wm->wm[0]);
 
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
@@ -2409,14 +2414,15 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 
 	/* At least LP0 must be valid */
 	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
-		return false;
+		return -EINVAL;
 
 	ilk_compute_wm_reg_maximums(dev, 1, &max);
 
 	for (level = 1; level <= max_level; level++) {
 		struct intel_wm_level wm = {};
 
-		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
+		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
+				     pristate, sprstate, curstate, &wm);
 
 		/*
 		 * Disable any watermark level that exceeds the
@@ -2429,7 +2435,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 		pipe_wm->wm[level] = wm;
 	}
 
-	return true;
+	return 0;
 }
 
 /*
@@ -3694,7 +3700,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct intel_pipe_wm pipe_wm = {};
 
 	/*
 	 * IVB workaround: must disable low power watermarks for at least
@@ -3708,13 +3713,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
 	}
 
-	intel_compute_pipe_wm(cstate, &pipe_wm);
-
-	if (!memcmp(&cstate->wm.active.ilk, &pipe_wm, sizeof(pipe_wm)))
-		return;
-
-	cstate->wm.active.ilk = pipe_wm;
-
 	ilk_program_watermarks(dev_priv);
 }
 
@@ -6994,6 +6992,7 @@ void intel_init_pm(struct drm_device *dev)
 		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
 		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
 			dev_priv->display.update_wm = ilk_update_wm;
+			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
 		} else {
 			DRM_DEBUG_KMS("Failed to read display plane latency. "
 				      "Disable CxSR\n");
-- 
2.1.4

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

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

* [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (8 preceding siblings ...)
  2015-08-21  1:12 ` [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2) Matt Roper
@ 2015-08-21  1:12 ` Matt Roper
  2015-08-28 13:42   ` Ander Conselvan De Oliveira
  2015-08-21  1:12 ` [PATCH 11/13] drm/i915: Add two-stage ILK-style watermark programming (v3) Matt Roper
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      | 10 ++++++
 drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_drv.h     |  1 +
 drivers/gpu/drm/i915/intel_pm.c      | 66 +++++++-----------------------------
 4 files changed, 71 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c91bab9..ac13cd7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1686,6 +1686,13 @@ struct i915_execbuffer_params {
 	struct drm_i915_gem_request     *request;
 };
 
+/* used in computing the new watermarks state */
+struct intel_wm_config {
+	unsigned int num_pipes_active;
+	bool sprites_enabled;
+	bool sprites_scaled;
+};
+
 struct drm_i915_private {
 	struct drm_device *dev;
 	struct kmem_cache *objects;
@@ -1903,6 +1910,9 @@ struct drm_i915_private {
 		 */
 		uint16_t skl_latency[8];
 
+		/* Committed wm config */
+		struct intel_wm_config config;
+
 		/*
 		 * The skl_wm_values structure is a bit too big for stack
 		 * allocation, so we keep the staging struct where we store
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c40f025..8e9d87a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13005,6 +13005,44 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 	return 0;
 }
 
+/*
+ * Handle calculation of various watermark data at the end of the atomic check
+ * phase.  The code here should be run after the per-crtc and per-plane 'check'
+ * handlers to ensure that all derived state has been updated.
+ */
+static void calc_watermark_data(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *cstate;
+	struct drm_plane *plane;
+	struct drm_plane_state *pstate;
+
+	/*
+	 * Calculate watermark configuration details now that derived
+	 * plane/crtc state is all properly updated.
+	 */
+	drm_for_each_crtc(crtc, dev) {
+		cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
+			crtc->state;
+
+		intel_state->wm_config.num_pipes_active++;
+	}
+	drm_for_each_legacy_plane(plane, dev) {
+		pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
+			plane->state;
+
+		if (!to_intel_plane_state(pstate)->visible)
+			continue;
+
+		intel_state->wm_config.sprites_enabled = true;
+		if (pstate->crtc_w != pstate->src_w >> 16 ||
+		    pstate->crtc_h != pstate->src_h >> 16)
+			intel_state->wm_config.sprites_scaled = true;
+	}
+}
+
 /**
  * intel_atomic_check - validate state object
  * @dev: drm device
@@ -13013,6 +13051,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 static int intel_atomic_check(struct drm_device *dev,
 			      struct drm_atomic_state *state)
 {
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	int ret, i;
@@ -13076,10 +13115,15 @@ static int intel_atomic_check(struct drm_device *dev,
 		if (ret)
 			return ret;
 	} else
-		to_intel_atomic_state(state)->cdclk =
-			to_i915(state->dev)->cdclk_freq;
+		intel_state->cdclk = to_i915(state->dev)->cdclk_freq;
 
-	return drm_atomic_helper_check_planes(state->dev, state);
+	ret = drm_atomic_helper_check_planes(state->dev, state);
+	if (ret)
+		return ret;
+
+	calc_watermark_data(state);
+
+	return 0;
 }
 
 /**
@@ -13119,6 +13163,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 		return ret;
 
 	drm_atomic_helper_swap_state(dev, state);
+	dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f9cac4b..6ac1010c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -239,6 +239,7 @@ struct intel_atomic_state {
 	unsigned int cdclk;
 	bool dpll_set;
 	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+	struct intel_wm_config wm_config;
 };
 
 struct intel_plane_state {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index bc29260..b32d6b0 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1786,13 +1786,6 @@ struct ilk_wm_maximums {
 	uint16_t fbc;
 };
 
-/* used in computing the new watermarks state */
-struct intel_wm_config {
-	unsigned int num_pipes_active;
-	bool sprites_enabled;
-	bool sprites_scaled;
-};
-
 /*
  * For both WM_PIPE and WM_LP.
  * mem_value must be in 0.1us units.
@@ -2322,26 +2315,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
 	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
 }
 
-static void ilk_compute_wm_config(struct drm_device *dev,
-				  struct intel_wm_config *config)
-{
-	struct intel_crtc *intel_crtc;
-
-	/* Compute the currently _active_ config */
-	for_each_intel_crtc(dev, intel_crtc) {
-		const struct intel_crtc_state *cstate =
-			to_intel_crtc_state(intel_crtc->base.state);
-		const struct intel_pipe_wm *wm = &cstate->wm.active.ilk;
-
-		if (!wm->pipe_enabled)
-			continue;
-
-		config->sprites_enabled |= wm->sprites_enabled;
-		config->sprites_scaled |= wm->sprites_scaled;
-		config->num_pipes_active++;
-	}
-}
-
 /* Compute new watermarks for the pipe */
 static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 			       struct drm_atomic_state *state)
@@ -2983,11 +2956,12 @@ skl_get_total_relative_data_rate(const struct intel_crtc *intel_crtc)
 
 static void
 skl_allocate_pipe_ddb(struct drm_crtc *crtc,
-		      const struct intel_wm_config *config,
 		      const struct intel_crtc_state *cstate,
 		      struct skl_ddb_allocation *ddb /* out */)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_wm_config *config = &dev_priv->wm.config;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_plane *intel_plane;
 	enum pipe pipe = intel_crtc->pipe;
@@ -3157,15 +3131,6 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
 	return false;
 }
 
-static void skl_compute_wm_global_parameters(struct drm_device *dev,
-					     struct intel_wm_config *config)
-{
-	struct drm_crtc *crtc;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-		config->num_pipes_active += to_intel_crtc(crtc)->active;
-}
-
 static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 				 struct intel_crtc *intel_crtc,
 				 struct intel_plane *intel_plane,
@@ -3571,13 +3536,12 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 }
 
 static bool skl_update_pipe_wm(struct drm_crtc *crtc,
-			       struct intel_wm_config *config,
 			       struct skl_ddb_allocation *ddb, /* out */
 			       struct skl_pipe_wm *pipe_wm /* out */)
 {
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
-	skl_allocate_pipe_ddb(crtc, config, cstate, ddb);
+	skl_allocate_pipe_ddb(crtc, cstate, ddb);
 	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
 
 	if (!memcmp(&cstate->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
@@ -3590,7 +3554,6 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 
 static void skl_update_other_pipe_wm(struct drm_device *dev,
 				     struct drm_crtc *crtc,
-				     struct intel_wm_config *config,
 				     struct skl_wm_values *r)
 {
 	struct intel_crtc *intel_crtc;
@@ -3620,7 +3583,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		if (!intel_crtc->active)
 			continue;
 
-		wm_changed = skl_update_pipe_wm(&intel_crtc->base, config,
+		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
 						&r->ddb, &pipe_wm);
 
 		/*
@@ -3642,19 +3605,16 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct skl_wm_values *results = &dev_priv->wm.skl_results;
 	struct skl_pipe_wm pipe_wm = {};
-	struct intel_wm_config config = {};
 
 	memset(results, 0, sizeof(*results));
 
-	skl_compute_wm_global_parameters(dev, &config);
-
-	if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
+	if (!skl_update_pipe_wm(crtc, &results->ddb, &pipe_wm))
 		return;
 
 	skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
 	results->dirty[intel_crtc->pipe] = true;
 
-	skl_update_other_pipe_wm(dev, crtc, &config, results);
+	skl_update_other_pipe_wm(dev, crtc, results);
 	skl_write_wm_values(dev_priv, results);
 	skl_flush_wm_values(dev_priv, results);
 
@@ -3667,20 +3627,18 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
 	struct drm_device *dev = dev_priv->dev;
 	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
 	struct ilk_wm_maximums max;
-	struct intel_wm_config config = {};
+	struct intel_wm_config *config = &dev_priv->wm.config;
 	struct ilk_wm_values results = {};
 	enum intel_ddb_partitioning partitioning;
 
-	ilk_compute_wm_config(dev, &config);
-
-	ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max);
-	ilk_wm_merge(dev, &config, &max, &lp_wm_1_2);
+	ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_1_2, &max);
+	ilk_wm_merge(dev, config, &max, &lp_wm_1_2);
 
 	/* 5/6 split only in single pipe config on IVB+ */
 	if (INTEL_INFO(dev)->gen >= 7 &&
-	    config.num_pipes_active == 1 && config.sprites_enabled) {
-		ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max);
-		ilk_wm_merge(dev, &config, &max, &lp_wm_5_6);
+	    config->num_pipes_active == 1 && config->sprites_enabled) {
+		ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_5_6, &max);
+		ilk_wm_merge(dev, config, &max, &lp_wm_5_6);
 
 		best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6);
 	} else {
-- 
2.1.4

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

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

* [PATCH 11/13] drm/i915: Add two-stage ILK-style watermark programming (v3)
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (9 preceding siblings ...)
  2015-08-21  1:12 ` [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check Matt Roper
@ 2015-08-21  1:12 ` Matt Roper
  2015-08-31 14:36   ` Ander Conselvan De Oliveira
  2015-08-21  1:12 ` [PATCH 12/13] drm/i915/skl: Switch to atomic watermark programming Matt Roper
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time.  These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank).  Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.

v2: Significant rebasing/rewriting.

v3:
 - Move 'need_postvbl_update' flag to CRTC state (Daniel)
 - Don't forget to check intermediate watermark values for validity
   (Maarten)
 - Don't due async watermark optimization; just do it at the end of the
   atomic transaction, after waiting for vblanks.  We do want it to be
   async eventually, but adding that now will cause more trouble for
   Maarten's in-progress work.  (Maarten)
 - Don't allocate space in crtc_state for intermediate watermarks on
   platforms that don't need it (gen9+).
 - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
   now that ilk_update_wm is gone.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   5 ++
 drivers/gpu/drm/i915/intel_display.c |  77 ++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h     |  33 ++++++--
 drivers/gpu/drm/i915/intel_pm.c      | 144 ++++++++++++++++++++++++-----------
 4 files changed, 208 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ac13cd7..be42dd8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -622,6 +622,11 @@ struct drm_i915_display_funcs {
 			  struct dpll *best_clock);
 	int (*compute_pipe_wm)(struct drm_crtc *crtc,
 			       struct drm_atomic_state *state);
+	int (*compute_intermediate_wm)(struct drm_device *dev,
+				       struct intel_crtc_state *newstate,
+				       const struct intel_crtc_state *oldstate);
+	void (*program_watermarks)(struct drm_i915_private *dev_priv);
+	void (*optimize_watermarks)(struct intel_crtc_state *cstate);
 	void (*update_wm)(struct drm_crtc *crtc);
 	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
 	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8e9d87a..f929676 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11634,6 +11634,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 		}
 	} else if (intel_wm_need_update(plane, plane_state)) {
 		intel_crtc->atomic.update_wm_pre = true;
+
+		/* Pre-gen9 platforms need two-step watermark updates */
+		if (INTEL_INFO(dev)->gen < 9 &&
+		    dev_priv->display.program_watermarks)
+			cstate->wm.need_postvbl_update = true;
 	}
 
 	if (visible)
@@ -11769,6 +11774,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *pipe_config =
 		to_intel_crtc_state(crtc_state);
+	struct intel_crtc_state *old_pipe_config =
+		to_intel_crtc_state(crtc->state);
 	struct drm_atomic_state *state = crtc_state->state;
 	int ret;
 	bool mode_changed = needs_modeset(crtc_state);
@@ -11793,8 +11800,28 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 	ret = 0;
 	if (dev_priv->display.compute_pipe_wm) {
 		ret = dev_priv->display.compute_pipe_wm(crtc, state);
-		if (ret)
+		if (ret) {
+			DRM_DEBUG_KMS("Target pipe watermarks are invalid\n");
+			return ret;
+		}
+	}
+
+	if (dev_priv->display.compute_intermediate_wm) {
+		if (WARN_ON(!dev_priv->display.compute_pipe_wm))
+			return 0;
+
+		/*
+		 * Calculate 'intermediate' watermarks that satisfy both the
+		 * old state and the new state.  We can program these
+		 * immediately.
+		 */
+		ret = dev_priv->display.compute_intermediate_wm(crtc->dev,
+								pipe_config,
+								old_pipe_config);
+		if (ret) {
+			DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n");
 			return ret;
+		}
 	}
 
 	if (INTEL_INFO(dev)->gen >= 9) {
@@ -13149,6 +13176,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
+	struct intel_crtc_state *intel_cstate;
 	int ret = 0;
 	int i;
 	bool any_ms = false;
@@ -13213,6 +13241,21 @@ static int intel_atomic_commit(struct drm_device *dev,
 	/* FIXME: add subpixel order */
 
 	drm_atomic_helper_wait_for_vblanks(dev, state);
+
+	/*
+	 * Now that the vblank has passed, we can go ahead and program the
+	 * optimal watermarks on platforms that need two-step watermark
+	 * programming.
+	 *
+	 * TODO: Move this (and other cleanup) to an async worker eventually.
+	 */
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		intel_cstate = to_intel_crtc_state(crtc->state);
+
+		if (intel_cstate->wm.need_postvbl_update)
+			dev_priv->display.optimize_watermarks(intel_cstate);
+	}
+
 	drm_atomic_helper_cleanup_planes(dev, state);
 
 	if (any_ms)
@@ -13544,10 +13587,40 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
 				    struct drm_crtc_state *old_crtc_state)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-	if (intel_crtc->atomic.update_wm_pre)
+	/*
+	 * IVB workaround: must disable low power watermarks for at least
+	 * one frame before enabling scaling.  LP watermarks can be re-enabled
+	 * when scaling is disabled.
+	 *
+	 * WaCxSRDisabledForSpriteScaling:ivb
+	 */
+	if (to_intel_crtc_state(crtc->state)->disable_lp_wm) {
+		ilk_disable_lp_wm(crtc->dev);
+		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
+	}
+
+	/*
+	 * For platforms that support atomic watermarks, program the 'active'
+	 * watermarks immediately.  On pre-gen9 platforms, these will be the
+	 * intermediate values that are safe for both pre- and post- vblank;
+	 * when vblank happens, the 'active' values will be set to the final
+	 * 'target' values and we'll do this again to get the optimal
+	 * watermarks.  For gen9+ platforms, the values we program here will be
+	 * the final target values which will get automatically latched at
+	 * vblank time; no further programming will be necessary.
+	 *
+	 * If a platform hasn't been transitioned to atomic watermarks yet,
+	 * we'll continue to update watermarks the old way, if flags tell
+	 * us to.
+	 */
+	if (dev_priv->display.program_watermarks != NULL) {
+		dev_priv->display.program_watermarks(dev_priv);
+	} else if (intel_crtc->atomic.update_wm_pre) {
 		intel_update_watermarks(crtc);
+	}
 
 	/* Perform vblank evasion around commit operation */
 	if (crtc->state->active)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6ac1010c..6a73a53 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -476,14 +476,34 @@ struct intel_crtc_state {
 	bool disable_lp_wm;
 
 	struct {
-		/*
-		 * final watermarks, programmed post-vblank when this state
-		 * is committed
-		 */
 		union {
-			struct intel_pipe_wm ilk;
+			struct {
+				/*
+				 * Final, target watermarks for state; this
+				 * might not have been programmed yet if a
+				 * vblank hasn't happened since this state
+				 * was committed.
+				 */
+				struct intel_pipe_wm target;
+
+				/*
+				 * currently programmed watermark; this will be
+				 * the intermediate values before vblank then
+				 * switch to match 'target' after vblank fires
+				 */
+				struct intel_pipe_wm active;
+			} ilk;
+
 			struct skl_pipe_wm skl;
-		} active;
+		};
+
+		/*
+		 * Platforms with two-step watermark programming will need to
+		 * update watermark programming post-vblank to switch from the
+		 * safe intermediate watermarks to the optimal final
+		 * watermarks.
+		 */
+		bool need_postvbl_update;
 	} wm;
 };
 
@@ -1385,6 +1405,7 @@ void skl_wm_get_hw_state(struct drm_device *dev);
 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
 			  struct skl_ddb_allocation *ddb /* out */);
 uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
+bool ilk_disable_lp_wm(struct drm_device *dev);
 
 /* intel_sdvo.c */
 bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b32d6b0..e0a4c4d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2315,6 +2315,29 @@ static void skl_setup_wm_latency(struct drm_device *dev)
 	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
 }
 
+static bool ilk_validate_pipe_wm(struct drm_device *dev,
+				 struct intel_pipe_wm *pipe_wm)
+{
+	/* LP0 watermark maximums depend on this pipe alone */
+	const struct intel_wm_config config = {
+		.num_pipes_active = 1,
+		.sprites_enabled = pipe_wm->sprites_enabled,
+		.sprites_scaled = pipe_wm->sprites_scaled,
+	};
+	struct ilk_wm_maximums max;
+
+	/* LP0 watermarks always use 1/2 DDB partitioning */
+	ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
+
+	/* At least LP0 must be valid */
+	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) {
+		DRM_DEBUG_KMS("LP0 watermark invalid\n");
+		return false;
+	}
+
+	return true;
+}
+
 /* Compute new watermarks for the pipe */
 static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 			       struct drm_atomic_state *state)
@@ -2331,10 +2354,6 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 	struct intel_plane_state *sprstate = NULL;
 	struct intel_plane_state *curstate = NULL;
 	int level, max_level = ilk_wm_max_level(dev);
-	/* LP0 watermark maximums depend on this pipe alone */
-	struct intel_wm_config config = {
-		.num_pipes_active = 1,
-	};
 	struct ilk_wm_maximums max;
 
 	cs = drm_atomic_get_crtc_state(state, crtc);
@@ -2343,7 +2362,7 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 	else
 		cstate = to_intel_crtc_state(cs);
 
-	pipe_wm = &cstate->wm.active.ilk;
+	pipe_wm = &cstate->wm.ilk.target;
 
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		ps = drm_atomic_get_plane_state(state,
@@ -2359,21 +2378,18 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 			curstate = to_intel_plane_state(ps);
 	}
 
-	config.sprites_enabled = sprstate->visible;
-	config.sprites_scaled =
+	pipe_wm->pipe_enabled = cstate->base.active;
+	pipe_wm->sprites_enabled = sprstate->visible;
+	pipe_wm->sprites_scaled =
 		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
 		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
 
-	pipe_wm->pipe_enabled = cstate->base.active;
-	pipe_wm->sprites_enabled = config.sprites_enabled;
-	pipe_wm->sprites_scaled = config.sprites_scaled;
-
 	/* ILK/SNB: LP2+ watermarks only w/o sprites */
 	if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
 		max_level = 1;
 
 	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
-	if (config.sprites_scaled)
+	if (pipe_wm->sprites_scaled)
 		max_level = 0;
 
 	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
@@ -2382,12 +2398,8 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
 
-	/* LP0 watermarks always use 1/2 DDB partitioning */
-	ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
-
-	/* At least LP0 must be valid */
-	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
-		return -EINVAL;
+	if (!ilk_validate_pipe_wm(dev, pipe_wm))
+		return false;
 
 	ilk_compute_wm_reg_maximums(dev, 1, &max);
 
@@ -2412,6 +2424,60 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 }
 
 /*
+ * Build a set of 'intermediate' watermark values that satisfy both the old
+ * state and the new state.  These can be programmed to the hardware
+ * immediately.
+ */
+static int ilk_compute_intermediate_wm(struct drm_device *dev,
+				       struct intel_crtc_state *newstate,
+				       const struct intel_crtc_state *oldstate)
+{
+	struct intel_pipe_wm *a = &newstate->wm.ilk.active;
+	const struct intel_pipe_wm *b = &oldstate->wm.ilk.active;
+	int level, max_level = ilk_wm_max_level(dev);
+
+	/*
+	 * Start with the final, target watermarks, then combine with the
+	 * current state's watermarks to get values that are safe both
+	 * before and after the vblank.
+	 */
+	*a = newstate->wm.ilk.target;
+	a->pipe_enabled |= b->pipe_enabled;
+	a->sprites_enabled |= b->sprites_enabled;
+	a->sprites_scaled |= b->sprites_scaled;
+
+	for (level = 0; level <= max_level; level++) {
+		struct intel_wm_level *a_wm = &a->wm[level];
+		const struct intel_wm_level *b_wm = &b->wm[level];
+
+		a_wm->enable &= b_wm->enable;
+		a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val);
+		a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val);
+		a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val);
+		a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val);
+	}
+
+	/*
+	 * We need to make sure that these merged watermark values are
+	 * actually a valid configuration themselves.  If they're not,
+	 * there's no safe way to transition from the old state to
+	 * the new state, so we need to fail the atomic transaction.
+	 */
+	if (!ilk_validate_pipe_wm(dev, a))
+		return -EINVAL;
+
+	/*
+	 * If our intermediate WM are identical to the final WM, then we can
+	 * omit the post-vblank programming.
+	 */
+	if (!memcmp(&newstate->wm.ilk.active, &newstate->wm.ilk.target,
+		    sizeof *a))
+		newstate->wm.need_postvbl_update = false;
+
+	return 0;
+}
+
+/*
  * Merge the watermarks from all active pipes for a specific level.
  */
 static void ilk_merge_wm_level(struct drm_device *dev,
@@ -2425,7 +2491,7 @@ static void ilk_merge_wm_level(struct drm_device *dev,
 	for_each_intel_crtc(dev, intel_crtc) {
 		const struct intel_crtc_state *cstate =
 			to_intel_crtc_state(intel_crtc->base.state);
-		const struct intel_pipe_wm *active = &cstate->wm.active.ilk;
+		const struct intel_pipe_wm *active = &cstate->wm.ilk.active;
 		const struct intel_wm_level *wm = &active->wm[level];
 
 		if (!active->pipe_enabled)
@@ -2576,12 +2642,12 @@ static void ilk_compute_wm_results(struct drm_device *dev,
 		const struct intel_crtc_state *cstate =
 			to_intel_crtc_state(intel_crtc->base.state);
 		enum pipe pipe = intel_crtc->pipe;
-		const struct intel_wm_level *r = &cstate->wm.active.ilk.wm[0];
+		const struct intel_wm_level *r = &cstate->wm.ilk.active.wm[0];
 
 		if (WARN_ON(!r->enable))
 			continue;
 
-		results->wm_linetime[pipe] = cstate->wm.active.ilk.linetime;
+		results->wm_linetime[pipe] = cstate->wm.ilk.active.linetime;
 
 		results->wm_pipe[pipe] =
 			(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
@@ -2788,7 +2854,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
 	dev_priv->wm.hw = *results;
 }
 
-static bool ilk_disable_lp_wm(struct drm_device *dev)
+bool ilk_disable_lp_wm(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -3544,10 +3610,10 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	skl_allocate_pipe_ddb(crtc, cstate, ddb);
 	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
 
-	if (!memcmp(&cstate->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+	if (!memcmp(&cstate->wm.skl, pipe_wm, sizeof(*pipe_wm)))
 		return false;
 
-	cstate->wm.active.skl = *pipe_wm;
+	cstate->wm.skl = *pipe_wm;
 
 	return true;
 }
@@ -3653,24 +3719,11 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
 	ilk_write_wm_values(dev_priv, &results);
 }
 
-static void ilk_update_wm(struct drm_crtc *crtc)
+static void ilk_optimize_watermarks(struct intel_crtc_state *cstate)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-
-	/*
-	 * IVB workaround: must disable low power watermarks for at least
-	 * one frame before enabling scaling.  LP watermarks can be re-enabled
-	 * when scaling is disabled.
-	 *
-	 * WaCxSRDisabledForSpriteScaling:ivb
-	 */
-	if (cstate->disable_lp_wm) {
-		ilk_disable_lp_wm(crtc->dev);
-		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
-	}
+	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
 
+	cstate->wm.ilk.active = cstate->wm.ilk.target;
 	ilk_program_watermarks(dev_priv);
 }
 
@@ -3725,7 +3778,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct skl_pipe_wm *active = &cstate->wm.active.skl;
+	struct skl_pipe_wm *active = &cstate->wm.skl;
 	enum pipe pipe = intel_crtc->pipe;
 	int level, i, max_level;
 	uint32_t temp;
@@ -3789,7 +3842,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	struct ilk_wm_values *hw = &dev_priv->wm.hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct intel_pipe_wm *active = &cstate->wm.active.ilk;
+	struct intel_pipe_wm *active = &cstate->wm.ilk.active;
 	enum pipe pipe = intel_crtc->pipe;
 	static const unsigned int wm0_pipe_reg[] = {
 		[PIPE_A] = WM0_PIPEA_ILK,
@@ -3828,6 +3881,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 		for (level = 0; level <= max_level; level++)
 			active->wm[level].enable = true;
 	}
+
+	cstate->wm.ilk.target = *active;
 }
 
 #define _FW_WM(value, plane) \
@@ -6949,8 +7004,11 @@ void intel_init_pm(struct drm_device *dev)
 		     dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) ||
 		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
 		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
-			dev_priv->display.update_wm = ilk_update_wm;
 			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
+			dev_priv->display.compute_intermediate_wm =
+				ilk_compute_intermediate_wm;
+			dev_priv->display.program_watermarks = ilk_program_watermarks;
+			dev_priv->display.optimize_watermarks = ilk_optimize_watermarks;
 		} else {
 			DRM_DEBUG_KMS("Failed to read display plane latency. "
 				      "Disable CxSR\n");
-- 
2.1.4

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

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

* [PATCH 12/13] drm/i915/skl: Switch to atomic watermark programming
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (10 preceding siblings ...)
  2015-08-21  1:12 ` [PATCH 11/13] drm/i915: Add two-stage ILK-style watermark programming (v3) Matt Roper
@ 2015-08-21  1:12 ` Matt Roper
  2015-08-21  1:12 ` [PATCH 13/13] drm/i915/skl: Clarify pending vs hw watermark values Matt Roper
  2015-08-26  4:33 ` [PATCH 00/13] Atomic watermark updates (v3) Hindman, Gavin
  13 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Atomic watermark programming involves pre-computing the watermark
results during the 'check' phase of an atomic transaction.  Although
watermark updates are triggered by the change to a specific CRTC, the
results themselves are global, so they're stored in the
intel_atomic_state.  If/when the state moves to the commit phase, the
results will be copied from the state object to dev_priv->skl_results at
the same time plane/crtc state is swapped into the various display
objects.  dev_priv->wm.skl_results is a temporary staging area since actual
programming to the hardware can potentially take several vblanks
depending on the changes taking place (see skl_flush_wm_values).  Once
the watermark programming has been fully flushed to the hardware, the
values will be copied to dev_priv->wm.skl_hw.

The goal here is to transition to an atomic design with minimal change
to the existing SKL WM code (which is pretty complicated).  Going
forward, it probably doesn't make sense to keep triggering watermark
calculation on a CRTC-by-CRTC basis, since this can lead to us
recalculating the same results multiple times for a single transaction.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  1 +
 drivers/gpu/drm/i915/intel_drv.h     |  3 ++
 drivers/gpu/drm/i915/intel_pm.c      | 56 +++++++++++++++++++++++-------------
 3 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f929676..0a0e7f7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13192,6 +13192,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 
 	drm_atomic_helper_swap_state(dev, state);
 	dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
+	dev_priv->wm.skl_results = to_intel_atomic_state(state)->skl_wm;
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6a73a53..d4b2e66 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -240,6 +240,9 @@ struct intel_atomic_state {
 	bool dpll_set;
 	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
 	struct intel_wm_config wm_config;
+
+	/* gen9-only at the moment */
+	struct skl_wm_values skl_wm;
 };
 
 struct intel_plane_state {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e0a4c4d..a9e9e57 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3601,29 +3601,31 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	}
 }
 
-static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+static bool skl_update_pipe_wm(struct drm_crtc_state *cstate,
 			       struct skl_ddb_allocation *ddb, /* out */
 			       struct skl_pipe_wm *pipe_wm /* out */)
 {
-	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
+	struct drm_crtc *crtc = cstate->crtc;
 
-	skl_allocate_pipe_ddb(crtc, cstate, ddb);
-	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
+	skl_allocate_pipe_ddb(crtc, intel_cstate, ddb);
+	skl_compute_pipe_wm(crtc, ddb, intel_cstate, pipe_wm);
 
-	if (!memcmp(&cstate->wm.skl, pipe_wm, sizeof(*pipe_wm)))
+	if (!memcmp(&intel_cstate->wm.skl, pipe_wm, sizeof(*pipe_wm)))
 		return false;
 
-	cstate->wm.skl = *pipe_wm;
+	intel_cstate->wm.skl = *pipe_wm;
 
 	return true;
 }
 
-static void skl_update_other_pipe_wm(struct drm_device *dev,
+static void skl_update_other_pipe_wm(struct drm_atomic_state *state,
 				     struct drm_crtc *crtc,
 				     struct skl_wm_values *r)
 {
 	struct intel_crtc *intel_crtc;
 	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
+	struct drm_crtc_state *cstate;
 
 	/*
 	 * If the WM update hasn't changed the allocation for this_crtc (the
@@ -3638,7 +3640,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
 	 * other active pipes need new DDB allocation and WM values.
 	 */
-	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+	list_for_each_entry(intel_crtc, &state->dev->mode_config.crtc_list,
 				base.head) {
 		struct skl_pipe_wm pipe_wm = {};
 		bool wm_changed;
@@ -3646,11 +3648,13 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		if (this_crtc->pipe == intel_crtc->pipe)
 			continue;
 
-		if (!intel_crtc->active)
+		cstate = drm_atomic_get_existing_crtc_state(state, &intel_crtc->base) ?:
+			intel_crtc->base.state;
+
+		if (!cstate->active)
 			continue;
 
-		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
-						&r->ddb, &pipe_wm);
+		wm_changed = skl_update_pipe_wm(cstate, &r->ddb, &pipe_wm);
 
 		/*
 		 * If we end up re-computing the other pipe WM values, it's
@@ -3659,28 +3663,38 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		 */
 		WARN_ON(!wm_changed);
 
-		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
+		skl_compute_wm_results(state->dev, &pipe_wm, r, intel_crtc);
 		r->dirty[intel_crtc->pipe] = true;
 	}
 }
 
-static void skl_update_wm(struct drm_crtc *crtc)
+static int skl_compute_wm(struct drm_crtc *crtc,
+			  struct drm_atomic_state *state)
 {
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct skl_wm_values *results = &dev_priv->wm.skl_results;
+	struct drm_crtc_state *cstate ;
+	struct skl_wm_values *results = &intel_state->skl_wm;
 	struct skl_pipe_wm pipe_wm = {};
 
-	memset(results, 0, sizeof(*results));
+	cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?: crtc->state;
 
-	if (!skl_update_pipe_wm(crtc, &results->ddb, &pipe_wm))
-		return;
+	if (!skl_update_pipe_wm(cstate, &results->ddb, &pipe_wm))
+		return 0;
 
 	skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
 	results->dirty[intel_crtc->pipe] = true;
 
-	skl_update_other_pipe_wm(dev, crtc, results);
+	skl_update_other_pipe_wm(state, crtc, results);
+
+	return 0;
+}
+
+static void skl_program_watermarks(struct drm_i915_private *dev_priv)
+{
+	struct skl_wm_values *results = &dev_priv->wm.skl_results;
+
 	skl_write_wm_values(dev_priv, results);
 	skl_flush_wm_values(dev_priv, results);
 
@@ -3688,6 +3702,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	dev_priv->wm.skl_hw = *results;
 }
 
+
 static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = dev_priv->dev;
@@ -6996,7 +7011,8 @@ void intel_init_pm(struct drm_device *dev)
 		else if (IS_SKYLAKE(dev))
 			dev_priv->display.init_clock_gating =
 				skl_init_clock_gating;
-		dev_priv->display.update_wm = skl_update_wm;
+		dev_priv->display.compute_pipe_wm = skl_compute_wm;
+		dev_priv->display.program_watermarks = skl_program_watermarks;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
 
-- 
2.1.4

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

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

* [PATCH 13/13] drm/i915/skl: Clarify pending vs hw watermark values
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (11 preceding siblings ...)
  2015-08-21  1:12 ` [PATCH 12/13] drm/i915/skl: Switch to atomic watermark programming Matt Roper
@ 2015-08-21  1:12 ` Matt Roper
  2015-08-26  4:33 ` [PATCH 00/13] Atomic watermark updates (v3) Hindman, Gavin
  13 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-21  1:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira

Although we calculate watermark values in the atomic state, we still
have both 'pending' and 'hardware' values that ultimately wind up in
dev_priv due to the somewhat complicated watermark flushing process.
Re-arranging how these are stored/named in the dev_priv substructure may
add a little bit of clarity to what they're for.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  2 +-
 drivers/gpu/drm/i915/i915_drv.h      | 29 +++++++++++++++++++++--------
 drivers/gpu/drm/i915/intel_display.c |  4 ++--
 drivers/gpu/drm/i915/intel_pm.c      | 12 ++++++------
 4 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 54508f1..2a24141 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3134,7 +3134,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
 
 	drm_modeset_lock_all(dev);
 
-	ddb = &dev_priv->wm.skl_hw.ddb;
+	ddb = &dev_priv->wm.skl.hw.ddb;
 
 	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index be42dd8..c4ba9a2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1918,17 +1918,30 @@ struct drm_i915_private {
 		/* Committed wm config */
 		struct intel_wm_config config;
 
-		/*
-		 * The skl_wm_values structure is a bit too big for stack
-		 * allocation, so we keep the staging struct where we store
-		 * intermediate results here instead.
-		 */
-		struct skl_wm_values skl_results;
-
 		/* current hardware state */
 		union {
 			struct ilk_wm_values hw;
-			struct skl_wm_values skl_hw;
+			struct {
+				/*
+				 * The skl_wm_values structure is a bit too big
+				 * for stack allocation, so we keep the staging
+				 * struct where we store intermediate results
+				 * here instead.
+				 *
+				 * These watermark values correspond to the
+				 * state that has been swapped into the various
+				 * DRM objects, but may not have been
+				 * completely written to hardware yet due to
+				 * the multi-step flushing process.
+				 */
+				struct skl_wm_values pending;
+
+				/*
+				 * Watermark values that have been fully
+				 * written and flushed to the hardware.
+				 */
+				struct skl_wm_values hw;
+			} skl;
 			struct vlv_wm_values vlv;
 		};
 	} wm;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0a0e7f7..c58a83b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12581,7 +12581,7 @@ static void check_wm_state(struct drm_device *dev)
 		return;
 
 	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
-	sw_ddb = &dev_priv->wm.skl_hw.ddb;
+	sw_ddb = &dev_priv->wm.skl.hw.ddb;
 
 	for_each_intel_crtc(dev, intel_crtc) {
 		struct skl_ddb_entry *hw_entry, *sw_entry;
@@ -13192,7 +13192,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 
 	drm_atomic_helper_swap_state(dev, state);
 	dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
-	dev_priv->wm.skl_results = to_intel_atomic_state(state)->skl_wm;
+	dev_priv->wm.skl.pending = to_intel_atomic_state(state)->skl_wm;
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a9e9e57..f1c989c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3183,7 +3183,7 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl.hw.ddb;
 	enum pipe pipe = intel_crtc->pipe;
 
 	if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe],
@@ -3529,7 +3529,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	enum pipe pipe;
 
 	new_ddb = &new_values->ddb;
-	cur_ddb = &dev_priv->wm.skl_hw.ddb;
+	cur_ddb = &dev_priv->wm.skl.hw.ddb;
 
 	/*
 	 * First pass: flush the pipes with the new allocation contained into
@@ -3693,13 +3693,13 @@ static int skl_compute_wm(struct drm_crtc *crtc,
 
 static void skl_program_watermarks(struct drm_i915_private *dev_priv)
 {
-	struct skl_wm_values *results = &dev_priv->wm.skl_results;
+	struct skl_wm_values *results = &dev_priv->wm.skl.pending;
 
 	skl_write_wm_values(dev_priv, results);
 	skl_flush_wm_values(dev_priv, results);
 
 	/* store the new configuration */
-	dev_priv->wm.skl_hw = *results;
+	dev_priv->wm.skl.hw = *results;
 }
 
 
@@ -3790,7 +3790,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
+	struct skl_wm_values *hw = &dev_priv->wm.skl.hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 	struct skl_pipe_wm *active = &cstate->wm.skl;
@@ -3842,7 +3842,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 void skl_wm_get_hw_state(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
+	struct skl_ddb_allocation *ddb = &dev_priv->wm.skl.hw.ddb;
 	struct drm_crtc *crtc;
 
 	skl_ddb_get_hw_state(dev_priv, ddb);
-- 
2.1.4

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

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

* Re: [PATCH 00/13] Atomic watermark updates (v3)
  2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
                   ` (12 preceding siblings ...)
  2015-08-21  1:12 ` [PATCH 13/13] drm/i915/skl: Clarify pending vs hw watermark values Matt Roper
@ 2015-08-26  4:33 ` Hindman, Gavin
  2015-08-26 18:07   ` Matt Roper
  13 siblings, 1 reply; 42+ messages in thread
From: Hindman, Gavin @ 2015-08-26  4:33 UTC (permalink / raw)
  To: Roper, Matthew D, intel-gfx; +Cc: Conselvan De Oliveira, Ander

Does this series comprehend all of the ddr-dvfs/PM-5 watermark reworks that Ville did towards the end of CHV, or is this series additive to that?

Gavin Hindman
Senior Program Manager
SSG/OTC – Open Source Technology Center


-----Original Message-----
From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Matt Roper
Sent: Thursday, August 20, 2015 6:12 PM
To: intel-gfx@lists.freedesktop.org
Cc: Conselvan De Oliveira, Ander
Subject: [Intel-gfx] [PATCH 00/13] Atomic watermark updates (v3)

Previous atomic watermark patches were posted here:
  http://lists.freedesktop.org/archives/intel-gfx/2015-July/070465.html

Key changes since the last series:
 * Quite a bit of rebasing; I got pulled away from working on this for a while,
   so parts of the upstream code evolved a bit before I was able to get back
   to working on this.
 * Completely drop the async aspect of writing the final watermarks on
   platforms that need two-step programming.  Although this is the direction we
   want to go eventually, Maarten has indicated that what I was doing in
   previous patch sets was going to lead to conflicts with some of his
   in-progress work and asked that I just write the final watermarks at the
   very end of the atomic transaction, after waiting for vblanks.  We can
   revisit the async final step again after Maarten's work lands and leverage
   the new interfaces he adds.  In the meantime, this simplifies things a
   bit since we don't need to worry about async final watermark writing
   racing with our next transaction and clobbering the intermediate values
   for that next transaction that we've already written.
 * Early SKL-style atomic watermarks (completely untested at the moment!).  Even
   though gen9 doesn't need the two-step programming process, we now
   pre-compute gen9 watermark values during the check phase and write+flush
   them during commit.  However I think there's still more refactoring that
   should be eventually done here.  We trigger watermark updates on a per-crtc
   basis, but the end results are global, not per-crtc.  In an atomic
   transaction this could currently lead to us re-calculating the same values
   multiple times if multiple CRTC's all trigger a WM update.   Note that I
   haven't had a chance to run any of this on real gen9 hardware yet, so all of
   the SKL patches here should be considered RFC at best; they may be
   completely broken.
 * Various review feedback from Daniel, Ville, and Maarten from previous
   iterations.


Matt Roper (12):
  drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM
    code
  drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  drm/i915/skl: Simplify wm structures slightly
  drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM
  drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check
  drm/i915: Drop intel_update_sprite_watermarks
  drm/i915: Move active watermarks into CRTC state (v2)
  drm/i915: Calculate ILK-style watermarks during atomic check (v2)
  drm/i915: Calculate watermark configuration during atomic check
  drm/i915: Add two-stage ILK-style watermark programming (v3)
  drm/i915/skl: Switch to atomic watermark programming
  drm/i915/skl: Clarify pending vs hw watermark values

Ville Syrjälä (1):
  drm/i915: Refactor ilk_update_wm (v3)

 drivers/gpu/drm/i915/i915_debugfs.c  |   4 +-
 drivers/gpu/drm/i915/i915_drv.h      |  68 ++-
 drivers/gpu/drm/i915/intel_atomic.c  |   1 +
 drivers/gpu/drm/i915/intel_display.c | 184 +++++++-
 drivers/gpu/drm/i915/intel_drv.h     |  81 +++-
 drivers/gpu/drm/i915/intel_pm.c      | 860 ++++++++++++++++-------------------
 drivers/gpu/drm/i915/intel_sprite.c  |  15 -
 7 files changed, 659 insertions(+), 554 deletions(-)

-- 
2.1.4

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

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

* Re: [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code
  2015-08-21  1:11 ` [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code Matt Roper
@ 2015-08-26 12:45   ` Conselvan De Oliveira, Ander
  2015-08-26 13:23     ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Conselvan De Oliveira, Ander @ 2015-08-26 12:45 UTC (permalink / raw)
  To: Roper, Matthew D, intel-gfx

On Thu, 2015-08-20 at 18:11 -0700, Matt Roper wrote:
> Just pull the info out of the plane state structure rather than staging
> it in an additional structure.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>

Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 133 +++++++++++++++++++++-------------------
>  1 file changed, 70 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index fff0c22..c9cf7cf 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1791,9 +1791,6 @@ struct ilk_pipe_wm_parameters {
>  	bool active;
>  	uint32_t pipe_htotal;
>  	uint32_t pixel_rate;
> -	struct intel_plane_wm_parameters pri;
> -	struct intel_plane_wm_parameters spr;
> -	struct intel_plane_wm_parameters cur;
>  };
>  
>  struct ilk_wm_maximums {
> @@ -1815,25 +1812,25 @@ struct intel_wm_config {
>   * mem_value must be in 0.1us units.
>   */
>  static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> +				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value,
>  				   bool is_lp)
>  {
> +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  	uint32_t method1, method2;
>  
> -	if (!params->active || !params->pri.enabled)
> +	if (!params->active || !pstate->visible)
>  		return 0;
>  
> -	method1 = ilk_wm_method1(params->pixel_rate,
> -				 params->pri.bytes_per_pixel,
> -				 mem_value);
> +	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
>  
>  	if (!is_lp)
>  		return method1;
>  
>  	method2 = ilk_wm_method2(params->pixel_rate,
>  				 params->pipe_htotal,
> -				 params->pri.horiz_pixels,
> -				 params->pri.bytes_per_pixel,
> +				 drm_rect_width(&pstate->dst),
> +				 bpp,
>  				 mem_value);
>  
>  	return min(method1, method2);
> @@ -1844,20 +1841,20 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters 
> *params,
>   * mem_value must be in 0.1us units.
>   */
>  static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> +				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value)
>  {
> +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  	uint32_t method1, method2;
>  
> -	if (!params->active || !params->spr.enabled)
> +	if (!params->active || !pstate->visible)
>  		return 0;
>  
> -	method1 = ilk_wm_method1(params->pixel_rate,
> -				 params->spr.bytes_per_pixel,
> -				 mem_value);
> +	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
>  	method2 = ilk_wm_method2(params->pixel_rate,
>  				 params->pipe_htotal,
> -				 params->spr.horiz_pixels,
> -				 params->spr.bytes_per_pixel,
> +				 drm_rect_width(&pstate->dst),
> +				 bpp,
>  				 mem_value);
>  	return min(method1, method2);
>  }
> @@ -1867,28 +1864,32 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters 
> *params,
>   * mem_value must be in 0.1us units.
>   */
>  static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
> +				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value)
>  {
> -	if (!params->active || !params->cur.enabled)
> +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> +
> +	if (!params->active || !pstate->visible)
>  		return 0;
>  
>  	return ilk_wm_method2(params->pixel_rate,
>  			      params->pipe_htotal,
> -			      params->cur.horiz_pixels,
> -			      params->cur.bytes_per_pixel,
> +			      drm_rect_width(&pstate->dst),
> +			      bpp,
>  			      mem_value);
>  }
>  
>  /* Only for WM_LP. */
>  static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
> +				   const struct intel_plane_state *pstate,
>  				   uint32_t pri_val)
>  {
> -	if (!params->active || !params->pri.enabled)
> +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> +
> +	if (!params->active || !pstate->visible)
>  		return 0;
>  
> -	return ilk_wm_fbc(pri_val,
> -			  params->pri.horiz_pixels,
> -			  params->pri.bytes_per_pixel);
> +	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
>  }
>  
>  static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
> @@ -2053,10 +2054,12 @@ static bool ilk_validate_wm_level(int level,
>  }
>  
>  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> +				 const struct intel_crtc *intel_crtc,
>  				 int level,
>  				 const struct ilk_pipe_wm_parameters *p,
>  				 struct intel_wm_level *result)
>  {
> +	struct intel_plane *intel_plane;
>  	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];
> @@ -2068,10 +2071,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  		cur_latency *= 5;
>  	}
>  
> -	result->pri_val = ilk_compute_pri_wm(p, pri_latency, level);
> -	result->spr_val = ilk_compute_spr_wm(p, spr_latency);
> -	result->cur_val = ilk_compute_cur_wm(p, cur_latency);
> -	result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val);
> +	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
> +		struct intel_plane_state *pstate =
> +			to_intel_plane_state(intel_plane->base.state);
> +
> +		switch (intel_plane->base.type) {
> +		case DRM_PLANE_TYPE_PRIMARY:
> +			result->pri_val = ilk_compute_pri_wm(p, pstate,
> +							     pri_latency,
> +							     level);
> +			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
> +							     result->pri_val);
> +			break;
> +		case DRM_PLANE_TYPE_OVERLAY:
> +			result->spr_val = ilk_compute_spr_wm(p, pstate,
> +							     spr_latency);
> +			break;
> +		case DRM_PLANE_TYPE_CURSOR:
> +			result->cur_val = ilk_compute_cur_wm(p, pstate,
> +							     cur_latency);
> +			break;
> +		}
> +	}
> +
>  	result->enable = true;
>  }
>  
> @@ -2333,10 +2355,7 @@ static void skl_setup_wm_latency(struct drm_device *dev)
>  static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
>  				      struct ilk_pipe_wm_parameters *p)
>  {
> -	struct drm_device *dev = crtc->dev;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum pipe pipe = intel_crtc->pipe;
> -	struct drm_plane *plane;
>  
>  	if (!intel_crtc->active)
>  		return;
> @@ -2344,32 +2363,6 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
>  	p->active = true;
>  	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
>  	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
> -
> -	if (crtc->primary->state->fb)
> -		p->pri.bytes_per_pixel =
> -			crtc->primary->state->fb->bits_per_pixel / 8;
> -	else
> -		p->pri.bytes_per_pixel = 4;
> -
> -	p->cur.bytes_per_pixel = 4;
> -	/*
> -	 * TODO: for now, assume primary and cursor planes are always enabled.
> -	 * Setting them to false makes the screen flicker.
> -	 */
> -	p->pri.enabled = true;
> -	p->cur.enabled = true;
> -
> -	p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
> -	p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
> -
> -	drm_for_each_legacy_plane(plane, dev) {
> -		struct intel_plane *intel_plane = to_intel_plane(plane);
> -
> -		if (intel_plane->pipe == pipe) {
> -			p->spr = intel_plane->wm;
> -			break;
> -		}
> -	}
>  }
>  
>  static void ilk_compute_wm_config(struct drm_device *dev,
> @@ -2397,28 +2390,42 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  {
>  	struct drm_device *dev = crtc->dev;
>  	const struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_plane *intel_plane;
> +	struct intel_plane_state *sprstate = NULL;
>  	int level, max_level = ilk_wm_max_level(dev);
>  	/* LP0 watermark maximums depend on this pipe alone */
>  	struct intel_wm_config config = {
>  		.num_pipes_active = 1,
> -		.sprites_enabled = params->spr.enabled,
> -		.sprites_scaled = params->spr.scaled,
>  	};
>  	struct ilk_wm_maximums max;
>  
> +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
> +			sprstate = to_intel_plane_state(intel_plane->base.state);
> +			break;
> +		}
> +	}
> +
> +	config.sprites_enabled = sprstate->visible;
> +	config.sprites_scaled =
> +		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
> +		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
> +
> +
>  	pipe_wm->pipe_enabled = params->active;
> -	pipe_wm->sprites_enabled = params->spr.enabled;
> -	pipe_wm->sprites_scaled = params->spr.scaled;
> +	pipe_wm->sprites_enabled = sprstate->visible;
> +	pipe_wm->sprites_scaled = config.sprites_scaled;
>  
>  	/* ILK/SNB: LP2+ watermarks only w/o sprites */
> -	if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled)
> +	if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
>  		max_level = 1;
>  
>  	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
> -	if (params->spr.scaled)
> +	if (config.sprites_scaled)
>  		max_level = 0;
>  
> -	ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]);
> +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
>  
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> @@ -2435,7 +2442,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  	for (level = 1; level <= max_level; level++) {
>  		struct intel_wm_level wm = {};
>  
> -		ilk_compute_wm_level(dev_priv, level, params, &wm);
> +		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
>  
>  		/*
>  		 * Disable any watermark level that exceeds the
---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  2015-08-21  1:11 ` [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM Matt Roper
@ 2015-08-26 12:45   ` Ander Conselvan De Oliveira
  2015-08-26 13:39   ` Ville Syrjälä
  1 sibling, 0 replies; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-26 12:45 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:11 -0700, Matt Roper wrote:
> Just pull the info out of the CRTC state structure rather than staging
> it in an additional structure.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>

Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 84 ++++++++++++++---------------------------
>  1 file changed, 28 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c9cf7cf..d82ea82 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1787,12 +1787,6 @@ struct skl_pipe_wm_parameters {
>  	struct intel_plane_wm_parameters cursor;
>  };
>  
> -struct ilk_pipe_wm_parameters {
> -	bool active;
> -	uint32_t pipe_htotal;
> -	uint32_t pixel_rate;
> -};
> -
>  struct ilk_wm_maximums {
>  	uint16_t pri;
>  	uint16_t spr;
> @@ -1811,7 +1805,7 @@ struct intel_wm_config {
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
>   */
> -static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> +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)
> @@ -1819,16 +1813,16 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters 
> *params,
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  	uint32_t method1, method2;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
> -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
>  
>  	if (!is_lp)
>  		return method1;
>  
> -	method2 = ilk_wm_method2(params->pixel_rate,
> -				 params->pipe_htotal,
> +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> +				 cstate->base.adjusted_mode.crtc_htotal,
>  				 drm_rect_width(&pstate->dst),
>  				 bpp,
>  				 mem_value);
> @@ -1840,19 +1834,19 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters 
> *params,
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
>   */
> -static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> +static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
>  				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value)
>  {
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  	uint32_t method1, method2;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
> -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> -	method2 = ilk_wm_method2(params->pixel_rate,
> -				 params->pipe_htotal,
> +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
> +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> +				 cstate->base.adjusted_mode.crtc_htotal,
>  				 drm_rect_width(&pstate->dst),
>  				 bpp,
>  				 mem_value);
> @@ -1863,30 +1857,30 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters 
> *params,
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
>   */
> -static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
> +static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
>  				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value)
>  {
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
> -	return ilk_wm_method2(params->pixel_rate,
> -			      params->pipe_htotal,
> +	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> +			      cstate->base.adjusted_mode.crtc_htotal,
>  			      drm_rect_width(&pstate->dst),
>  			      bpp,
>  			      mem_value);
>  }
>  
>  /* Only for WM_LP. */
> -static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
> +static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
>  				   const struct intel_plane_state *pstate,
>  				   uint32_t pri_val)
>  {
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
>  	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
> @@ -2056,7 +2050,7 @@ static bool ilk_validate_wm_level(int level,
>  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  				 const struct intel_crtc *intel_crtc,
>  				 int level,
> -				 const struct ilk_pipe_wm_parameters *p,
> +				 struct intel_crtc_state *cstate,
>  				 struct intel_wm_level *result)
>  {
>  	struct intel_plane *intel_plane;
> @@ -2077,18 +2071,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  
>  		switch (intel_plane->base.type) {
>  		case DRM_PLANE_TYPE_PRIMARY:
> -			result->pri_val = ilk_compute_pri_wm(p, pstate,
> +			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
>  							     pri_latency,
>  							     level);
> -			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
> +			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
>  							     result->pri_val);
>  			break;
>  		case DRM_PLANE_TYPE_OVERLAY:
> -			result->spr_val = ilk_compute_spr_wm(p, pstate,
> +			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
>  							     spr_latency);
>  			break;
>  		case DRM_PLANE_TYPE_CURSOR:
> -			result->cur_val = ilk_compute_cur_wm(p, pstate,
> +			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
>  							     cur_latency);
>  			break;
>  		}
> @@ -2352,19 +2346,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
>  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
>  }
>  
> -static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> -				      struct ilk_pipe_wm_parameters *p)
> -{
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	if (!intel_crtc->active)
> -		return;
> -
> -	p->active = true;
> -	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> -	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
> -}
> -
>  static void ilk_compute_wm_config(struct drm_device *dev,
>  				  struct intel_wm_config *config)
>  {
> @@ -2384,10 +2365,10 @@ static void ilk_compute_wm_config(struct drm_device *dev,
>  }
>  
>  /* Compute new watermarks for the pipe */
> -static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> -				  const struct ilk_pipe_wm_parameters *params,
> +static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  				  struct intel_pipe_wm *pipe_wm)
>  {
> +	struct drm_crtc *crtc = cstate->base.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	const struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -2412,8 +2393,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
>  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
>  
> -
> -	pipe_wm->pipe_enabled = params->active;
> +	pipe_wm->pipe_enabled = cstate->base.active;
>  	pipe_wm->sprites_enabled = sprstate->visible;
>  	pipe_wm->sprites_scaled = config.sprites_scaled;
>  
> @@ -2425,7 +2405,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  	if (config.sprites_scaled)
>  		max_level = 0;
>  
> -	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
> +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
>  
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> @@ -2442,7 +2422,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  	for (level = 1; level <= max_level; level++) {
>  		struct intel_wm_level wm = {};
>  
> -		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
> +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
>  
>  		/*
>  		 * Disable any watermark level that exceeds the
> @@ -3748,19 +3728,17 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
>  static void ilk_update_wm(struct drm_crtc *crtc)
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct ilk_wm_maximums max;
> -	struct ilk_pipe_wm_parameters params = {};
>  	struct ilk_wm_values results = {};
>  	enum intel_ddb_partitioning partitioning;
>  	struct intel_pipe_wm pipe_wm = {};
>  	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
>  	struct intel_wm_config config = {};
>  
> -	ilk_compute_wm_parameters(crtc, &params);
> -
> -	intel_compute_pipe_wm(crtc, &params, &pipe_wm);
> +	intel_compute_pipe_wm(cstate, &pipe_wm);
>  
>  	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
>  		return;
> @@ -3800,12 +3778,6 @@ ilk_update_sprite_wm(struct drm_plane *plane,
>  	struct drm_device *dev = plane->dev;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  
> -	intel_plane->wm.enabled = enabled;
> -	intel_plane->wm.scaled = scaled;
> -	intel_plane->wm.horiz_pixels = sprite_width;
> -	intel_plane->wm.vert_pixels = sprite_width;
> -	intel_plane->wm.bytes_per_pixel = pixel_size;
> -
>  	/*
>  	 * IVB workaround: must disable low power watermarks for at least
>  	 * one frame before enabling scaling.  LP watermarks can be re-enabled
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/13] drm/i915: Move active watermarks into CRTC state (v2)
  2015-08-21  1:11 ` [PATCH 08/13] drm/i915: Move active watermarks into CRTC state (v2) Matt Roper
@ 2015-08-26 13:10   ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2015-08-26 13:10 UTC (permalink / raw)
  To: Matt Roper; +Cc: ander.conselvan.de.oliveira, intel-gfx

On Thu, Aug 20, 2015 at 06:11:59PM -0700, Matt Roper wrote:
> Since we allocate a few CRTC states on the stack, also switch the 'wm'
> struct here to be a union so that we're not wasting stack space with
> other platforms' watermark values.
> 

I don't like this patch. The locking rules (once we have the vblank
update machinery and wm.mutex) will be totally different for the active
wms vs. the crtc state. So this would need to reverted when we add the
vblank wm machinery.

That's at least for ILK+. Not sure about SKL since I've not really
thought about it so far.

> v2: Don't move cxsr_allowed to state (Maarten)
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h | 45 +++++++++++++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_pm.c  | 30 ++++++++++++++++-----------
>  2 files changed, 44 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 65f0171..dfbfba9 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -323,6 +323,21 @@ struct intel_crtc_scaler_state {
>  /* drm_mode->private_flags */
>  #define I915_MODE_FLAG_INHERITED 1
>  
> +struct intel_pipe_wm {
> +	struct intel_wm_level wm[5];
> +	uint32_t linetime;
> +	bool fbc_wm_enabled;
> +	bool pipe_enabled;
> +	bool sprites_enabled;
> +	bool sprites_scaled;
> +};
> +
> +struct skl_pipe_wm {
> +	struct skl_wm_level wm[8];
> +	struct skl_wm_level trans_wm;
> +	uint32_t linetime;
> +};
> +
>  struct intel_crtc_state {
>  	struct drm_crtc_state base;
>  
> @@ -458,6 +473,17 @@ struct intel_crtc_state {
>  
>  	/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
>  	bool disable_lp_wm;
> +
> +	struct {
> +		/*
> +		 * final watermarks, programmed post-vblank when this state
> +		 * is committed
> +		 */
> +		union {
> +			struct intel_pipe_wm ilk;
> +			struct skl_pipe_wm skl;
> +		} active;
> +	} wm;
>  };
>  
>  struct vlv_wm_state {
> @@ -469,15 +495,6 @@ struct vlv_wm_state {
>  	bool cxsr;
>  };
>  
> -struct intel_pipe_wm {
> -	struct intel_wm_level wm[5];
> -	uint32_t linetime;
> -	bool fbc_wm_enabled;
> -	bool pipe_enabled;
> -	bool sprites_enabled;
> -	bool sprites_scaled;
> -};
> -
>  struct intel_mmio_flip {
>  	struct work_struct work;
>  	struct drm_i915_private *i915;
> @@ -485,12 +502,6 @@ struct intel_mmio_flip {
>  	struct intel_crtc *crtc;
>  };
>  
> -struct skl_pipe_wm {
> -	struct skl_wm_level wm[8];
> -	struct skl_wm_level trans_wm;
> -	uint32_t linetime;
> -};
> -
>  /*
>   * Tracking of operations that need to be performed at the beginning/end of an
>   * atomic commit, outside the atomic section where interrupts are disabled.
> @@ -555,10 +566,6 @@ struct intel_crtc {
>  
>  	/* per-pipe watermark state */
>  	struct {
> -		/* watermarks currently being used  */
> -		struct intel_pipe_wm active;
> -		/* SKL wm values currently in use */
> -		struct skl_pipe_wm skl_active;
>  		/* allow CxSR on this pipe */
>  		bool cxsr_allowed;
>  	} wm;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 5b79c2f..04fc092 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2345,7 +2345,9 @@ static void ilk_compute_wm_config(struct drm_device *dev,
>  
>  	/* Compute the currently _active_ config */
>  	for_each_intel_crtc(dev, intel_crtc) {
> -		const struct intel_pipe_wm *wm = &intel_crtc->wm.active;
> +		const struct intel_crtc_state *cstate =
> +			to_intel_crtc_state(intel_crtc->base.state);
> +		const struct intel_pipe_wm *wm = &cstate->wm.active.ilk;
>  
>  		if (!wm->pipe_enabled)
>  			continue;
> @@ -2442,7 +2444,9 @@ static void ilk_merge_wm_level(struct drm_device *dev,
>  	ret_wm->enable = true;
>  
>  	for_each_intel_crtc(dev, intel_crtc) {
> -		const struct intel_pipe_wm *active = &intel_crtc->wm.active;
> +		const struct intel_crtc_state *cstate =
> +			to_intel_crtc_state(intel_crtc->base.state);
> +		const struct intel_pipe_wm *active = &cstate->wm.active.ilk;
>  		const struct intel_wm_level *wm = &active->wm[level];
>  
>  		if (!active->pipe_enabled)
> @@ -2590,14 +2594,15 @@ static void ilk_compute_wm_results(struct drm_device *dev,
>  
>  	/* LP0 register values */
>  	for_each_intel_crtc(dev, intel_crtc) {
> +		const struct intel_crtc_state *cstate =
> +			to_intel_crtc_state(intel_crtc->base.state);
>  		enum pipe pipe = intel_crtc->pipe;
> -		const struct intel_wm_level *r =
> -			&intel_crtc->wm.active.wm[0];
> +		const struct intel_wm_level *r = &cstate->wm.active.ilk.wm[0];
>  
>  		if (WARN_ON(!r->enable))
>  			continue;
>  
> -		results->wm_linetime[pipe] = intel_crtc->wm.active.linetime;
> +		results->wm_linetime[pipe] = cstate->wm.active.ilk.linetime;
>  
>  		results->wm_pipe[pipe] =
>  			(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
> @@ -3564,16 +3569,15 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  			       struct skl_ddb_allocation *ddb, /* out */
>  			       struct skl_pipe_wm *pipe_wm /* out */)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
>  
>  	skl_allocate_pipe_ddb(crtc, config, cstate, ddb);
>  	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
>  
> -	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> +	if (!memcmp(&cstate->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
>  		return false;
>  
> -	intel_crtc->wm.skl_active = *pipe_wm;
> +	cstate->wm.active.skl = *pipe_wm;
>  
>  	return true;
>  }
> @@ -3706,10 +3710,10 @@ static void ilk_update_wm(struct drm_crtc *crtc)
>  
>  	intel_compute_pipe_wm(cstate, &pipe_wm);
>  
> -	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
> +	if (!memcmp(&cstate->wm.active.ilk, &pipe_wm, sizeof(pipe_wm)))
>  		return;
>  
> -	intel_crtc->wm.active = pipe_wm;
> +	cstate->wm.active.ilk = pipe_wm;
>  
>  	ilk_program_watermarks(dev_priv);
>  }
> @@ -3764,7 +3768,8 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> +	struct skl_pipe_wm *active = &cstate->wm.active.skl;
>  	enum pipe pipe = intel_crtc->pipe;
>  	int level, i, max_level;
>  	uint32_t temp;
> @@ -3827,7 +3832,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct ilk_wm_values *hw = &dev_priv->wm.hw;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct intel_pipe_wm *active = &intel_crtc->wm.active;
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> +	struct intel_pipe_wm *active = &cstate->wm.active.ilk;
>  	enum pipe pipe = intel_crtc->pipe;
>  	static const unsigned int wm0_pipe_reg[] = {
>  		[PIPE_A] = WM0_PIPEA_ILK,
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code
  2015-08-26 12:45   ` Conselvan De Oliveira, Ander
@ 2015-08-26 13:23     ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2015-08-26 13:23 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander; +Cc: intel-gfx

On Wed, Aug 26, 2015 at 12:45:32PM +0000, Conselvan De Oliveira, Ander wrote:
> On Thu, 2015-08-20 at 18:11 -0700, Matt Roper wrote:
> > Just pull the info out of the plane state structure rather than staging
> > it in an additional structure.
> > 
> > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> 
> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
> 
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 133 +++++++++++++++++++++-------------------
> >  1 file changed, 70 insertions(+), 63 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index fff0c22..c9cf7cf 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -1791,9 +1791,6 @@ struct ilk_pipe_wm_parameters {
> >  	bool active;
> >  	uint32_t pipe_htotal;
> >  	uint32_t pixel_rate;
> > -	struct intel_plane_wm_parameters pri;
> > -	struct intel_plane_wm_parameters spr;
> > -	struct intel_plane_wm_parameters cur;
> >  };
> >  
> >  struct ilk_wm_maximums {
> > @@ -1815,25 +1812,25 @@ struct intel_wm_config {
> >   * mem_value must be in 0.1us units.
> >   */
> >  static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> > +				   const struct intel_plane_state *pstate,
> >  				   uint32_t mem_value,
> >  				   bool is_lp)
> >  {
> > +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> >  	uint32_t method1, method2;
> >  
> > -	if (!params->active || !params->pri.enabled)
> > +	if (!params->active || !pstate->visible)
> >  		return 0;
> >  
> > -	method1 = ilk_wm_method1(params->pixel_rate,
> > -				 params->pri.bytes_per_pixel,
> > -				 mem_value);
> > +	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> >  
> >  	if (!is_lp)
> >  		return method1;
> >  
> >  	method2 = ilk_wm_method2(params->pixel_rate,
> >  				 params->pipe_htotal,
> > -				 params->pri.horiz_pixels,
> > -				 params->pri.bytes_per_pixel,
> > +				 drm_rect_width(&pstate->dst),
> > +				 bpp,
> >  				 mem_value);
> >  
> >  	return min(method1, method2);
> > @@ -1844,20 +1841,20 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters 
> > *params,
> >   * mem_value must be in 0.1us units.
> >   */
> >  static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> > +				   const struct intel_plane_state *pstate,
> >  				   uint32_t mem_value)
> >  {
> > +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> >  	uint32_t method1, method2;
> >  
> > -	if (!params->active || !params->spr.enabled)
> > +	if (!params->active || !pstate->visible)
> >  		return 0;
> >  
> > -	method1 = ilk_wm_method1(params->pixel_rate,
> > -				 params->spr.bytes_per_pixel,
> > -				 mem_value);
> > +	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> >  	method2 = ilk_wm_method2(params->pixel_rate,
> >  				 params->pipe_htotal,
> > -				 params->spr.horiz_pixels,
> > -				 params->spr.bytes_per_pixel,
> > +				 drm_rect_width(&pstate->dst),
> > +				 bpp,
> >  				 mem_value);
> >  	return min(method1, method2);
> >  }
> > @@ -1867,28 +1864,32 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters 
> > *params,
> >   * mem_value must be in 0.1us units.
> >   */
> >  static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
> > +				   const struct intel_plane_state *pstate,
> >  				   uint32_t mem_value)
> >  {
> > -	if (!params->active || !params->cur.enabled)
> > +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> > +
> > +	if (!params->active || !pstate->visible)
> >  		return 0;
> >  
> >  	return ilk_wm_method2(params->pixel_rate,
> >  			      params->pipe_htotal,
> > -			      params->cur.horiz_pixels,
> > -			      params->cur.bytes_per_pixel,
> > +			      drm_rect_width(&pstate->dst),
> > +			      bpp,
> >  			      mem_value);
> >  }
> >  
> >  /* Only for WM_LP. */
> >  static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
> > +				   const struct intel_plane_state *pstate,
> >  				   uint32_t pri_val)
> >  {
> > -	if (!params->active || !params->pri.enabled)
> > +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> > +
> > +	if (!params->active || !pstate->visible)
> >  		return 0;
> >  
> > -	return ilk_wm_fbc(pri_val,
> > -			  params->pri.horiz_pixels,
> > -			  params->pri.bytes_per_pixel);
> > +	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
> >  }
> >  
> >  static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
> > @@ -2053,10 +2054,12 @@ static bool ilk_validate_wm_level(int level,
> >  }
> >  
> >  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> > +				 const struct intel_crtc *intel_crtc,
> >  				 int level,
> >  				 const struct ilk_pipe_wm_parameters *p,
> >  				 struct intel_wm_level *result)
> >  {
> > +	struct intel_plane *intel_plane;
> >  	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];
> > @@ -2068,10 +2071,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> >  		cur_latency *= 5;
> >  	}
> >  
> > -	result->pri_val = ilk_compute_pri_wm(p, pri_latency, level);
> > -	result->spr_val = ilk_compute_spr_wm(p, spr_latency);
> > -	result->cur_val = ilk_compute_cur_wm(p, cur_latency);
> > -	result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val);
> > +	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
> > +		struct intel_plane_state *pstate =
> > +			to_intel_plane_state(intel_plane->base.state);
> > +
> > +		switch (intel_plane->base.type) {
> > +		case DRM_PLANE_TYPE_PRIMARY:
> > +			result->pri_val = ilk_compute_pri_wm(p, pstate,
> > +							     pri_latency,
> > +							     level);
> > +			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
> > +							     result->pri_val);
> > +			break;
> > +		case DRM_PLANE_TYPE_OVERLAY:
> > +			result->spr_val = ilk_compute_spr_wm(p, pstate,
> > +							     spr_latency);
> > +			break;
> > +		case DRM_PLANE_TYPE_CURSOR:
> > +			result->cur_val = ilk_compute_cur_wm(p, pstate,
> > +							     cur_latency);
> > +			break;
> > +		}
> > +	}
> > +
> >  	result->enable = true;
> >  }
> >  
> > @@ -2333,10 +2355,7 @@ static void skl_setup_wm_latency(struct drm_device *dev)
> >  static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> >  				      struct ilk_pipe_wm_parameters *p)
> >  {
> > -	struct drm_device *dev = crtc->dev;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -	enum pipe pipe = intel_crtc->pipe;
> > -	struct drm_plane *plane;
> >  
> >  	if (!intel_crtc->active)
> >  		return;
> > @@ -2344,32 +2363,6 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> >  	p->active = true;
> >  	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> >  	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
> > -
> > -	if (crtc->primary->state->fb)
> > -		p->pri.bytes_per_pixel =
> > -			crtc->primary->state->fb->bits_per_pixel / 8;
> > -	else
> > -		p->pri.bytes_per_pixel = 4;
> > -
> > -	p->cur.bytes_per_pixel = 4;
> > -	/*
> > -	 * TODO: for now, assume primary and cursor planes are always enabled.
> > -	 * Setting them to false makes the screen flicker.
> > -	 */
> > -	p->pri.enabled = true;
> > -	p->cur.enabled = true;
> > -
> > -	p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
> > -	p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
> > -
> > -	drm_for_each_legacy_plane(plane, dev) {
> > -		struct intel_plane *intel_plane = to_intel_plane(plane);
> > -
> > -		if (intel_plane->pipe == pipe) {
> > -			p->spr = intel_plane->wm;
> > -			break;
> > -		}
> > -	}
> >  }
> >  
> >  static void ilk_compute_wm_config(struct drm_device *dev,
> > @@ -2397,28 +2390,42 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	const struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct intel_plane *intel_plane;
> > +	struct intel_plane_state *sprstate = NULL;
> >  	int level, max_level = ilk_wm_max_level(dev);
> >  	/* LP0 watermark maximums depend on this pipe alone */
> >  	struct intel_wm_config config = {
> >  		.num_pipes_active = 1,
> > -		.sprites_enabled = params->spr.enabled,
> > -		.sprites_scaled = params->spr.scaled,
> >  	};
> >  	struct ilk_wm_maximums max;
> >  
> > +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> > +		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
> > +			sprstate = to_intel_plane_state(intel_plane->base.state);
> > +			break;
> > +		}
> > +	}
> > +
> > +	config.sprites_enabled = sprstate->visible;
> > +	config.sprites_scaled =
> > +		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
> > +		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;

This will now assume the rects will match when the sprite is invisible.
Not sure that would be the case, so I'd add a 'visible &&' here to make
sure we don't accidentally limite the wm level when the sprite isn't
even enabled.

> > +
> > +
> >  	pipe_wm->pipe_enabled = params->active;
> > -	pipe_wm->sprites_enabled = params->spr.enabled;
> > -	pipe_wm->sprites_scaled = params->spr.scaled;
> > +	pipe_wm->sprites_enabled = sprstate->visible;
> > +	pipe_wm->sprites_scaled = config.sprites_scaled;
> >  
> >  	/* ILK/SNB: LP2+ watermarks only w/o sprites */
> > -	if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled)
> > +	if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
> >  		max_level = 1;
> >  
> >  	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
> > -	if (params->spr.scaled)
> > +	if (config.sprites_scaled)
> >  		max_level = 0;
> >  
> > -	ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]);
> > +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
> >  
> >  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> >  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> > @@ -2435,7 +2442,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> >  	for (level = 1; level <= max_level; level++) {
> >  		struct intel_wm_level wm = {};
> >  
> > -		ilk_compute_wm_level(dev_priv, level, params, &wm);
> > +		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
> >  
> >  		/*
> >  		 * Disable any watermark level that exceeds the
> ---------------------------------------------------------------------
> Intel Finland Oy
> Registered Address: PL 281, 00181 Helsinki 
> Business Identity Code: 0357606 - 4 
> Domiciled in Helsinki 
> 
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 03/13] drm/i915/skl: Simplify wm structures slightly
  2015-08-21  1:11 ` [PATCH 03/13] drm/i915/skl: Simplify wm structures slightly Matt Roper
@ 2015-08-26 13:23   ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-26 13:23 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:11 -0700, Matt Roper wrote:
> A bunch of SKL watermark-related structures have the cursor plane as a
> separate entry from the rest of the planes.  If we just extend the
> relevant plane arrays by one entry and use the top-most array element as
> the cursor, it will simplify future patches.
> 
> There shouldn't be any functional change here; this is just shuffling
> around how the data is stored in some of the data structures.  The whole
> patch is generated with Coccinelle via the following semantic patch:
> 
>         @@ struct skl_pipe_wm_parameters WMP; @@
>         - WMP.cursor
>         + WMP.plane[I915_MAX_PLANES]

This would make the code more confusing. I see that just below the I915_MAX_PLANES there is a enum
plane. Would it make sense to combine I915_MAX_PLANES with that? 

enum plane {
	PLANE_A,
	PLANE_B,
	PLANE_C,
	PLANE_D, /* this would be new, for BXT */
	I915_MAX_PLANES,
	PLANE_CURSOR = I915_MAX_PLANES,
};

Then the code would reference WMP.plane[PLANE_CURSOR].

Ander

> 
>         @@ struct skl_pipe_wm_parameters *WMP; @@
>         - WMP->cursor
>         + WMP->plane[I915_MAX_PLANES]
> 
>         @@ @@
>         struct skl_pipe_wm_parameters {
>         ...
>         - struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
>         + struct intel_plane_wm_parameters plane[I915_MAX_PLANES+1];
>         - struct intel_plane_wm_parameters cursor;
>         ...
>         };
> 
>         @@
>         struct skl_ddb_allocation DDB;
>         expression E;
>         @@
>         - DDB.cursor[E]
>         + DDB.plane[E][I915_MAX_PLANES]
> 
>         @@
>         struct skl_ddb_allocation *DDB;
>         expression E;
>         @@
>         - DDB->cursor[E]
>         + DDB->plane[E][I915_MAX_PLANES]
> 
>         @@ @@
>         struct skl_ddb_allocation {
>         ...
>         - struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
>         + struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES+1];
>         ...
>         - struct skl_ddb_entry cursor[I915_MAX_PIPES];
>         ...
>         };
> 
>         @@
>         struct skl_wm_values WMV;
>         expression E1, E2;
>         @@
>         (
>         - WMV.cursor[E1][E2]
>         + WMV.plane[E1][I915_MAX_PLANES][E2]
>         |
>         - WMV.cursor_trans[E1]
>         + WMV.plane_trans[E1][I915_MAX_PLANES]
>         )
> 
>         @@
>         struct skl_wm_values *WMV;
>         expression E1, E2;
>         @@
>         (
>         - WMV->cursor[E1][E2]
>         + WMV->plane[E1][I915_MAX_PLANES][E2]
>         |
>         - WMV->cursor_trans[E1]
>         + WMV->plane_trans[E1][I915_MAX_PLANES]
>         )
> 
>         @@ @@
>         struct skl_wm_values {
>         ...
>         - uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
>         + uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES+1][8];
>         ...
>         - uint32_t cursor[I915_MAX_PIPES][8];
>         ...
>         - uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
>         + uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES+1];
>         ...
>         - uint32_t cursor_trans[I915_MAX_PIPES];
>         ...
>         };
> 
>         @@ struct skl_wm_level WML; @@
>         (
>         - WML.cursor_en
>         + WML.plane_en[I915_MAX_PLANES]
>         |
>         - WML.cursor_res_b
>         + WML.plane_res_b[I915_MAX_PLANES]
>         |
>         - WML.cursor_res_l
>         + WML.plane_res_l[I915_MAX_PLANES]
>         )
> 
>         @@ struct skl_wm_level *WML; @@
>         (
>         - WML->cursor_en
>         + WML->plane_en[I915_MAX_PLANES]
>         |
>         - WML->cursor_res_b
>         + WML->plane_res_b[I915_MAX_PLANES]
>         |
>         - WML->cursor_res_l
>         + WML->plane_res_l[I915_MAX_PLANES]
>         )
> 
>         @@ @@
>         struct skl_wm_level {
>         ...
>         - bool plane_en[I915_MAX_PLANES];
>         + bool plane_en[I915_MAX_PLANES+1];
>         ...
>         - bool cursor_en;
>         ...
>         - uint16_t plane_res_b[I915_MAX_PLANES];
>         + uint16_t plane_res_b[I915_MAX_PLANES+1];
>         ...
>         - uint8_t plane_res_l[I915_MAX_PLANES];
>         + uint8_t plane_res_l[I915_MAX_PLANES+1];
>         ...
>         - uint16_t cursor_res_b;
>         - uint8_t cursor_res_l;
>         ...
>         };
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c  |  2 +-
>  drivers/gpu/drm/i915/i915_drv.h      | 20 +++-----
>  drivers/gpu/drm/i915/intel_display.c |  4 +-
>  drivers/gpu/drm/i915/intel_pm.c      | 89 +++++++++++++++++++-----------------
>  4 files changed, 56 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 7a28de5..54508f1 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -3148,7 +3148,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
>  				   skl_ddb_entry_size(entry));
>  		}
>  
> -		entry = &ddb->cursor[pipe];
> +		entry = &ddb->plane[pipe][I915_MAX_PLANES];
>  		seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
>  			   entry->end, skl_ddb_entry_size(entry));
>  	}
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index e0f3f05..f04b67e 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1571,28 +1571,22 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
>  
>  struct skl_ddb_allocation {
>  	struct skl_ddb_entry pipe[I915_MAX_PIPES];
> -	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */
> -	struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* y-plane */
> -	struct skl_ddb_entry cursor[I915_MAX_PIPES];
> +	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES + 1]; /* packed/uv */
> +	struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
>  };
>  
>  struct skl_wm_values {
>  	bool dirty[I915_MAX_PIPES];
>  	struct skl_ddb_allocation ddb;
>  	uint32_t wm_linetime[I915_MAX_PIPES];
> -	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> -	uint32_t cursor[I915_MAX_PIPES][8];
> -	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> -	uint32_t cursor_trans[I915_MAX_PIPES];
> +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES + 1][8];
> +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES + 1];
>  };
>  
>  struct skl_wm_level {
> -	bool plane_en[I915_MAX_PLANES];
> -	bool cursor_en;
> -	uint16_t plane_res_b[I915_MAX_PLANES];
> -	uint8_t plane_res_l[I915_MAX_PLANES];
> -	uint16_t cursor_res_b;
> -	uint8_t cursor_res_l;
> +	bool plane_en[I915_MAX_PLANES + 1];
> +	uint16_t plane_res_b[I915_MAX_PLANES + 1];
> +	uint8_t plane_res_l[I915_MAX_PLANES + 1];
>  };
>  
>  /*
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index f604ce1..455b1bd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12552,8 +12552,8 @@ static void check_wm_state(struct drm_device *dev)
>  		}
>  
>  		/* cursor */
> -		hw_entry = &hw_ddb.cursor[pipe];
> -		sw_entry = &sw_ddb->cursor[pipe];
> +		hw_entry = &hw_ddb.plane[pipe][I915_MAX_PLANES];
> +		sw_entry = &sw_ddb->plane[pipe][I915_MAX_PLANES];
>  
>  		if (skl_ddb_entry_equal(hw_entry, sw_entry))
>  			continue;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d82ea82..b9bcb85 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1783,8 +1783,7 @@ struct skl_pipe_wm_parameters {
>  	bool active;
>  	uint32_t pipe_htotal;
>  	uint32_t pixel_rate; /* in KHz */
> -	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> -	struct intel_plane_wm_parameters cursor;
> +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES + 1];
>  };
>  
>  struct ilk_wm_maximums {
> @@ -2898,7 +2897,8 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
>  		}
>  
>  		val = I915_READ(CUR_BUF_CFG(pipe));
> -		skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val);
> +		skl_ddb_entry_init_from_hw(&ddb->plane[pipe][I915_MAX_PLANES],
> +					   val);
>  	}
>  }
>  
> @@ -2967,13 +2967,14 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	alloc_size = skl_ddb_entry_size(alloc);
>  	if (alloc_size == 0) {
>  		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
> -		memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
> +		memset(&ddb->plane[pipe][I915_MAX_PLANES], 0,
> +		       sizeof(ddb->plane[pipe][I915_MAX_PLANES]));
>  		return;
>  	}
>  
>  	cursor_blocks = skl_cursor_allocation(config);
> -	ddb->cursor[pipe].start = alloc->end - cursor_blocks;
> -	ddb->cursor[pipe].end = alloc->end;
> +	ddb->plane[pipe][I915_MAX_PLANES].start = alloc->end - cursor_blocks;
> +	ddb->plane[pipe][I915_MAX_PLANES].end = alloc->end;
>  
>  	alloc_size -= cursor_blocks;
>  	alloc->end -= cursor_blocks;
> @@ -3112,8 +3113,8 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation 
> *new_ddb,
>  		   sizeof(new_ddb->plane[pipe])))
>  		return true;
>  
> -	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
> -		    sizeof(new_ddb->cursor[pipe])))
> +	if (memcmp(&new_ddb->plane[pipe][I915_MAX_PLANES], &cur_ddb
> ->plane[pipe][I915_MAX_PLANES],
> +		    sizeof(new_ddb->plane[pipe][I915_MAX_PLANES])))
>  		return true;
>  
>  	return false;
> @@ -3172,17 +3173,17 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
>  		p->plane[0].rotation = crtc->primary->state->rotation;
>  
>  		fb = crtc->cursor->state->fb;
> -		p->cursor.y_bytes_per_pixel = 0;
> +		p->plane[I915_MAX_PLANES].y_bytes_per_pixel = 0;
>  		if (fb) {
> -			p->cursor.enabled = true;
> -			p->cursor.bytes_per_pixel = fb->bits_per_pixel / 8;
> -			p->cursor.horiz_pixels = crtc->cursor->state->crtc_w;
> -			p->cursor.vert_pixels = crtc->cursor->state->crtc_h;
> +			p->plane[I915_MAX_PLANES].enabled = true;
> +			p->plane[I915_MAX_PLANES].bytes_per_pixel = fb->bits_per_pixel / 8;
> +			p->plane[I915_MAX_PLANES].horiz_pixels = crtc->cursor->state->crtc_w;
> +			p->plane[I915_MAX_PLANES].vert_pixels = crtc->cursor->state->crtc_h;
>  		} else {
> -			p->cursor.enabled = false;
> -			p->cursor.bytes_per_pixel = 0;
> -			p->cursor.horiz_pixels = 64;
> -			p->cursor.vert_pixels = 64;
> +			p->plane[I915_MAX_PLANES].enabled = false;
> +			p->plane[I915_MAX_PLANES].bytes_per_pixel = 0;
> +			p->plane[I915_MAX_PLANES].horiz_pixels = 64;
> +			p->plane[I915_MAX_PLANES].vert_pixels = 64;
>  		}
>  	}
>  
> @@ -3296,11 +3297,12 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
>  						&result->plane_res_l[i]);
>  	}
>  
> -	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
> -	result->cursor_en = skl_compute_plane_wm(dev_priv, p, &p->cursor,
> +	ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][I915_MAX_PLANES]);
> +	result->plane_en[I915_MAX_PLANES] = skl_compute_plane_wm(dev_priv, p,
> +						 &p->plane[I915_MAX_PLANES],
>  						 ddb_blocks, level,
> -						 &result->cursor_res_b,
> -						 &result->cursor_res_l);
> +						 &result->plane_res_b[I915_MAX_PLANES],
> +						 &result->plane_res_l[I915_MAX_PLANES]);
>  }
>  
>  static uint32_t
> @@ -3328,7 +3330,7 @@ static void skl_compute_transition_wm(struct drm_crtc *crtc,
>  	/* Until we know more, just disable transition WMs */
>  	for (i = 0; i < intel_num_planes(intel_crtc); i++)
>  		trans_wm->plane_en[i] = false;
> -	trans_wm->cursor_en = false;
> +	trans_wm->plane_en[I915_MAX_PLANES] = false;
>  }
>  
>  static void skl_compute_pipe_wm(struct drm_crtc *crtc,
> @@ -3377,13 +3379,13 @@ static void skl_compute_wm_results(struct drm_device *dev,
>  
>  		temp = 0;
>  
> -		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
> -		temp |= p_wm->wm[level].cursor_res_b;
> +		temp |= p_wm->wm[level].plane_res_l[I915_MAX_PLANES] << PLANE_WM_LINES_SHIFT;
> +		temp |= p_wm->wm[level].plane_res_b[I915_MAX_PLANES];
>  
> -		if (p_wm->wm[level].cursor_en)
> +		if (p_wm->wm[level].plane_en[I915_MAX_PLANES])
>  			temp |= PLANE_WM_EN;
>  
> -		r->cursor[pipe][level] = temp;
> +		r->plane[pipe][I915_MAX_PLANES][level] = temp;
>  
>  	}
>  
> @@ -3399,12 +3401,12 @@ static void skl_compute_wm_results(struct drm_device *dev,
>  	}
>  
>  	temp = 0;
> -	temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT;
> -	temp |= p_wm->trans_wm.cursor_res_b;
> -	if (p_wm->trans_wm.cursor_en)
> +	temp |= p_wm->trans_wm.plane_res_l[I915_MAX_PLANES] << PLANE_WM_LINES_SHIFT;
> +	temp |= p_wm->trans_wm.plane_res_b[I915_MAX_PLANES];
> +	if (p_wm->trans_wm.plane_en[I915_MAX_PLANES])
>  		temp |= PLANE_WM_EN;
>  
> -	r->cursor_trans[pipe] = temp;
> +	r->plane_trans[pipe][I915_MAX_PLANES] = temp;
>  
>  	r->wm_linetime[pipe] = p_wm->linetime;
>  }
> @@ -3438,12 +3440,13 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
>  				I915_WRITE(PLANE_WM(pipe, i, level),
>  					   new->plane[pipe][i][level]);
>  			I915_WRITE(CUR_WM(pipe, level),
> -				   new->cursor[pipe][level]);
> +				   new->plane[pipe][I915_MAX_PLANES][level]);
>  		}
>  		for (i = 0; i < intel_num_planes(crtc); i++)
>  			I915_WRITE(PLANE_WM_TRANS(pipe, i),
>  				   new->plane_trans[pipe][i]);
> -		I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> +		I915_WRITE(CUR_WM_TRANS(pipe),
> +			   new->plane_trans[pipe][I915_MAX_PLANES]);
>  
>  		for (i = 0; i < intel_num_planes(crtc); i++) {
>  			skl_ddb_entry_write(dev_priv,
> @@ -3455,7 +3458,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
>  		}
>  
>  		skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
> -				    &new->ddb.cursor[pipe]);
> +				    &new->ddb.plane[pipe][I915_MAX_PLANES]);
>  	}
>  }
>  
> @@ -3809,10 +3812,10 @@ static void skl_pipe_wm_active_state(uint32_t val,
>  					(val >> PLANE_WM_LINES_SHIFT) &
>  						PLANE_WM_LINES_MASK;
>  		} else {
> -			active->wm[level].cursor_en = is_enabled;
> -			active->wm[level].cursor_res_b =
> +			active->wm[level].plane_en[I915_MAX_PLANES] = is_enabled;
> +			active->wm[level].plane_res_b[I915_MAX_PLANES] =
>  					val & PLANE_WM_BLOCKS_MASK;
> -			active->wm[level].cursor_res_l =
> +			active->wm[level].plane_res_l[I915_MAX_PLANES] =
>  					(val >> PLANE_WM_LINES_SHIFT) &
>  						PLANE_WM_LINES_MASK;
>  		}
> @@ -3825,10 +3828,10 @@ static void skl_pipe_wm_active_state(uint32_t val,
>  					(val >> PLANE_WM_LINES_SHIFT) &
>  						PLANE_WM_LINES_MASK;
>  		} else {
> -			active->trans_wm.cursor_en = is_enabled;
> -			active->trans_wm.cursor_res_b =
> +			active->trans_wm.plane_en[I915_MAX_PLANES] = is_enabled;
> +			active->trans_wm.plane_res_b[I915_MAX_PLANES] =
>  					val & PLANE_WM_BLOCKS_MASK;
> -			active->trans_wm.cursor_res_l =
> +			active->trans_wm.plane_res_l[I915_MAX_PLANES] =
>  					(val >> PLANE_WM_LINES_SHIFT) &
>  						PLANE_WM_LINES_MASK;
>  		}
> @@ -3854,12 +3857,12 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  		for (i = 0; i < intel_num_planes(intel_crtc); i++)
>  			hw->plane[pipe][i][level] =
>  					I915_READ(PLANE_WM(pipe, i, level));
> -		hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
> +		hw->plane[pipe][I915_MAX_PLANES][level] = I915_READ(CUR_WM(pipe, level));
>  	}
>  
>  	for (i = 0; i < intel_num_planes(intel_crtc); i++)
>  		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
> -	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
> +	hw->plane_trans[pipe][I915_MAX_PLANES] = I915_READ(CUR_WM_TRANS(pipe));
>  
>  	if (!intel_crtc->active)
>  		return;
> @@ -3874,7 +3877,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  			skl_pipe_wm_active_state(temp, active, false,
>  						false, i, level);
>  		}
> -		temp = hw->cursor[pipe][level];
> +		temp = hw->plane[pipe][I915_MAX_PLANES][level];
>  		skl_pipe_wm_active_state(temp, active, false, true, i, level);
>  	}
>  
> @@ -3883,7 +3886,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  		skl_pipe_wm_active_state(temp, active, true, false, i, 0);
>  	}
>  
> -	temp = hw->cursor_trans[pipe];
> +	temp = hw->plane_trans[pipe][I915_MAX_PLANES];
>  	skl_pipe_wm_active_state(temp, active, true, true, i, 0);
>  }
>  
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  2015-08-21  1:11 ` [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM Matt Roper
  2015-08-26 12:45   ` Ander Conselvan De Oliveira
@ 2015-08-26 13:39   ` Ville Syrjälä
  2015-08-26 15:37     ` Matt Roper
  1 sibling, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2015-08-26 13:39 UTC (permalink / raw)
  To: Matt Roper; +Cc: ander.conselvan.de.oliveira, intel-gfx

On Thu, Aug 20, 2015 at 06:11:53PM -0700, Matt Roper wrote:
> Just pull the info out of the CRTC state structure rather than staging
> it in an additional structure.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 84 ++++++++++++++---------------------------
>  1 file changed, 28 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c9cf7cf..d82ea82 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1787,12 +1787,6 @@ struct skl_pipe_wm_parameters {
>  	struct intel_plane_wm_parameters cursor;
>  };
>  
> -struct ilk_pipe_wm_parameters {
> -	bool active;
> -	uint32_t pipe_htotal;
> -	uint32_t pixel_rate;
> -};
> -
>  struct ilk_wm_maximums {
>  	uint16_t pri;
>  	uint16_t spr;
> @@ -1811,7 +1805,7 @@ struct intel_wm_config {
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
>   */
> -static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> +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)
> @@ -1819,16 +1813,16 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  	uint32_t method1, method2;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;

Previously we lookd at crtc->active, now we look at state->base.active.
Since the atomic modeset code is a bit insane and doesn't have an
intermediate atomic state for the disable->re-enable case, I'm not sure
this will fly currently.

I'd be much happier if someone added the intermediate atomic state to
handle pipe disabling in a nicer way. Afterwards we should be able to
elimiate all special cases dealing with watermarks and just do the wm
updates from the commit_planes (or whatever it was called).

>  
> -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
>  
>  	if (!is_lp)
>  		return method1;
>  
> -	method2 = ilk_wm_method2(params->pixel_rate,
> -				 params->pipe_htotal,
> +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> +				 cstate->base.adjusted_mode.crtc_htotal,
>  				 drm_rect_width(&pstate->dst),
>  				 bpp,
>  				 mem_value);
> @@ -1840,19 +1834,19 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
>   */
> -static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> +static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
>  				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value)
>  {
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  	uint32_t method1, method2;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
> -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> -	method2 = ilk_wm_method2(params->pixel_rate,
> -				 params->pipe_htotal,
> +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
> +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> +				 cstate->base.adjusted_mode.crtc_htotal,
>  				 drm_rect_width(&pstate->dst),
>  				 bpp,
>  				 mem_value);
> @@ -1863,30 +1857,30 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
>   */
> -static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
> +static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
>  				   const struct intel_plane_state *pstate,
>  				   uint32_t mem_value)
>  {
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
> -	return ilk_wm_method2(params->pixel_rate,
> -			      params->pipe_htotal,
> +	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> +			      cstate->base.adjusted_mode.crtc_htotal,
>  			      drm_rect_width(&pstate->dst),
>  			      bpp,
>  			      mem_value);
>  }
>  
>  /* Only for WM_LP. */
> -static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
> +static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
>  				   const struct intel_plane_state *pstate,
>  				   uint32_t pri_val)
>  {
>  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
>  
> -	if (!params->active || !pstate->visible)
> +	if (!cstate->base.active || !pstate->visible)
>  		return 0;
>  
>  	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
> @@ -2056,7 +2050,7 @@ static bool ilk_validate_wm_level(int level,
>  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  				 const struct intel_crtc *intel_crtc,
>  				 int level,
> -				 const struct ilk_pipe_wm_parameters *p,
> +				 struct intel_crtc_state *cstate,
>  				 struct intel_wm_level *result)
>  {
>  	struct intel_plane *intel_plane;
> @@ -2077,18 +2071,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  
>  		switch (intel_plane->base.type) {
>  		case DRM_PLANE_TYPE_PRIMARY:
> -			result->pri_val = ilk_compute_pri_wm(p, pstate,
> +			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
>  							     pri_latency,
>  							     level);
> -			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
> +			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
>  							     result->pri_val);
>  			break;
>  		case DRM_PLANE_TYPE_OVERLAY:
> -			result->spr_val = ilk_compute_spr_wm(p, pstate,
> +			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
>  							     spr_latency);
>  			break;
>  		case DRM_PLANE_TYPE_CURSOR:
> -			result->cur_val = ilk_compute_cur_wm(p, pstate,
> +			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
>  							     cur_latency);
>  			break;
>  		}
> @@ -2352,19 +2346,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
>  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
>  }
>  
> -static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> -				      struct ilk_pipe_wm_parameters *p)
> -{
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	if (!intel_crtc->active)
> -		return;
> -
> -	p->active = true;
> -	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> -	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
> -}
> -
>  static void ilk_compute_wm_config(struct drm_device *dev,
>  				  struct intel_wm_config *config)
>  {
> @@ -2384,10 +2365,10 @@ static void ilk_compute_wm_config(struct drm_device *dev,
>  }
>  
>  /* Compute new watermarks for the pipe */
> -static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> -				  const struct ilk_pipe_wm_parameters *params,
> +static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  				  struct intel_pipe_wm *pipe_wm)
>  {
> +	struct drm_crtc *crtc = cstate->base.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	const struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -2412,8 +2393,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
>  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
>  
> -
> -	pipe_wm->pipe_enabled = params->active;
> +	pipe_wm->pipe_enabled = cstate->base.active;
>  	pipe_wm->sprites_enabled = sprstate->visible;
>  	pipe_wm->sprites_scaled = config.sprites_scaled;
>  
> @@ -2425,7 +2405,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  	if (config.sprites_scaled)
>  		max_level = 0;
>  
> -	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
> +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
>  
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> @@ -2442,7 +2422,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
>  	for (level = 1; level <= max_level; level++) {
>  		struct intel_wm_level wm = {};
>  
> -		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
> +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
>  
>  		/*
>  		 * Disable any watermark level that exceeds the
> @@ -3748,19 +3728,17 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
>  static void ilk_update_wm(struct drm_crtc *crtc)
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct ilk_wm_maximums max;
> -	struct ilk_pipe_wm_parameters params = {};
>  	struct ilk_wm_values results = {};
>  	enum intel_ddb_partitioning partitioning;
>  	struct intel_pipe_wm pipe_wm = {};
>  	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
>  	struct intel_wm_config config = {};
>  
> -	ilk_compute_wm_parameters(crtc, &params);
> -
> -	intel_compute_pipe_wm(crtc, &params, &pipe_wm);
> +	intel_compute_pipe_wm(cstate, &pipe_wm);
>  
>  	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
>  		return;
> @@ -3800,12 +3778,6 @@ ilk_update_sprite_wm(struct drm_plane *plane,
>  	struct drm_device *dev = plane->dev;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  
> -	intel_plane->wm.enabled = enabled;
> -	intel_plane->wm.scaled = scaled;
> -	intel_plane->wm.horiz_pixels = sprite_width;
> -	intel_plane->wm.vert_pixels = sprite_width;
> -	intel_plane->wm.bytes_per_pixel = pixel_size;
> -
>  	/*
>  	 * IVB workaround: must disable low power watermarks for at least
>  	 * one frame before enabling scaling.  LP watermarks can be re-enabled
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  2015-08-26 13:39   ` Ville Syrjälä
@ 2015-08-26 15:37     ` Matt Roper
  2015-08-26 15:51       ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-08-26 15:37 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: ander.conselvan.de.oliveira, intel-gfx

On Wed, Aug 26, 2015 at 04:39:12PM +0300, Ville Syrjälä wrote:
> On Thu, Aug 20, 2015 at 06:11:53PM -0700, Matt Roper wrote:
> > Just pull the info out of the CRTC state structure rather than staging
> > it in an additional structure.
> > 
> > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 84 ++++++++++++++---------------------------
> >  1 file changed, 28 insertions(+), 56 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index c9cf7cf..d82ea82 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -1787,12 +1787,6 @@ struct skl_pipe_wm_parameters {
> >  	struct intel_plane_wm_parameters cursor;
> >  };
> >  
> > -struct ilk_pipe_wm_parameters {
> > -	bool active;
> > -	uint32_t pipe_htotal;
> > -	uint32_t pixel_rate;
> > -};
> > -
> >  struct ilk_wm_maximums {
> >  	uint16_t pri;
> >  	uint16_t spr;
> > @@ -1811,7 +1805,7 @@ struct intel_wm_config {
> >   * For both WM_PIPE and WM_LP.
> >   * mem_value must be in 0.1us units.
> >   */
> > -static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> > +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)
> > @@ -1819,16 +1813,16 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> >  	uint32_t method1, method2;
> >  
> > -	if (!params->active || !pstate->visible)
> > +	if (!cstate->base.active || !pstate->visible)
> >  		return 0;
> 
> Previously we lookd at crtc->active, now we look at state->base.active.
> Since the atomic modeset code is a bit insane and doesn't have an
> intermediate atomic state for the disable->re-enable case, I'm not sure
> this will fly currently.
> 
> I'd be much happier if someone added the intermediate atomic state to
> handle pipe disabling in a nicer way. Afterwards we should be able to
> elimiate all special cases dealing with watermarks and just do the wm
> updates from the commit_planes (or whatever it was called).

I think I'm missing some of the context for your comment.  At the moment
we update watermarks after vblank if the CRTC is being re-enabled and
before the vblank in other cases, so it seems like if we use
crtc->active here, then when we get to the post-vblank watermark update
we won't have any watermark values since we'll be acting on the old data
that says the CRTC is still off.

When you talk about intermediate atomic state are you saying that you
want to see CRTC enables take a two step process where the CRTC gets
enabled with no planes first, then all the planes get turned on during
the next vblank?


Matt

> 
> >  
> > -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> > +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
> >  
> >  	if (!is_lp)
> >  		return method1;
> >  
> > -	method2 = ilk_wm_method2(params->pixel_rate,
> > -				 params->pipe_htotal,
> > +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> > +				 cstate->base.adjusted_mode.crtc_htotal,
> >  				 drm_rect_width(&pstate->dst),
> >  				 bpp,
> >  				 mem_value);
> > @@ -1840,19 +1834,19 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> >   * For both WM_PIPE and WM_LP.
> >   * mem_value must be in 0.1us units.
> >   */
> > -static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> > +static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
> >  				   const struct intel_plane_state *pstate,
> >  				   uint32_t mem_value)
> >  {
> >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> >  	uint32_t method1, method2;
> >  
> > -	if (!params->active || !pstate->visible)
> > +	if (!cstate->base.active || !pstate->visible)
> >  		return 0;
> >  
> > -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> > -	method2 = ilk_wm_method2(params->pixel_rate,
> > -				 params->pipe_htotal,
> > +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
> > +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> > +				 cstate->base.adjusted_mode.crtc_htotal,
> >  				 drm_rect_width(&pstate->dst),
> >  				 bpp,
> >  				 mem_value);
> > @@ -1863,30 +1857,30 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> >   * For both WM_PIPE and WM_LP.
> >   * mem_value must be in 0.1us units.
> >   */
> > -static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
> > +static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
> >  				   const struct intel_plane_state *pstate,
> >  				   uint32_t mem_value)
> >  {
> >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> >  
> > -	if (!params->active || !pstate->visible)
> > +	if (!cstate->base.active || !pstate->visible)
> >  		return 0;
> >  
> > -	return ilk_wm_method2(params->pixel_rate,
> > -			      params->pipe_htotal,
> > +	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> > +			      cstate->base.adjusted_mode.crtc_htotal,
> >  			      drm_rect_width(&pstate->dst),
> >  			      bpp,
> >  			      mem_value);
> >  }
> >  
> >  /* Only for WM_LP. */
> > -static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
> > +static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
> >  				   const struct intel_plane_state *pstate,
> >  				   uint32_t pri_val)
> >  {
> >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> >  
> > -	if (!params->active || !pstate->visible)
> > +	if (!cstate->base.active || !pstate->visible)
> >  		return 0;
> >  
> >  	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
> > @@ -2056,7 +2050,7 @@ static bool ilk_validate_wm_level(int level,
> >  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> >  				 const struct intel_crtc *intel_crtc,
> >  				 int level,
> > -				 const struct ilk_pipe_wm_parameters *p,
> > +				 struct intel_crtc_state *cstate,
> >  				 struct intel_wm_level *result)
> >  {
> >  	struct intel_plane *intel_plane;
> > @@ -2077,18 +2071,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> >  
> >  		switch (intel_plane->base.type) {
> >  		case DRM_PLANE_TYPE_PRIMARY:
> > -			result->pri_val = ilk_compute_pri_wm(p, pstate,
> > +			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
> >  							     pri_latency,
> >  							     level);
> > -			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
> > +			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
> >  							     result->pri_val);
> >  			break;
> >  		case DRM_PLANE_TYPE_OVERLAY:
> > -			result->spr_val = ilk_compute_spr_wm(p, pstate,
> > +			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
> >  							     spr_latency);
> >  			break;
> >  		case DRM_PLANE_TYPE_CURSOR:
> > -			result->cur_val = ilk_compute_cur_wm(p, pstate,
> > +			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
> >  							     cur_latency);
> >  			break;
> >  		}
> > @@ -2352,19 +2346,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
> >  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
> >  }
> >  
> > -static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> > -				      struct ilk_pipe_wm_parameters *p)
> > -{
> > -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -
> > -	if (!intel_crtc->active)
> > -		return;
> > -
> > -	p->active = true;
> > -	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> > -	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
> > -}
> > -
> >  static void ilk_compute_wm_config(struct drm_device *dev,
> >  				  struct intel_wm_config *config)
> >  {
> > @@ -2384,10 +2365,10 @@ static void ilk_compute_wm_config(struct drm_device *dev,
> >  }
> >  
> >  /* Compute new watermarks for the pipe */
> > -static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> > -				  const struct ilk_pipe_wm_parameters *params,
> > +static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
> >  				  struct intel_pipe_wm *pipe_wm)
> >  {
> > +	struct drm_crtc *crtc = cstate->base.crtc;
> >  	struct drm_device *dev = crtc->dev;
> >  	const struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -2412,8 +2393,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> >  		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
> >  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
> >  
> > -
> > -	pipe_wm->pipe_enabled = params->active;
> > +	pipe_wm->pipe_enabled = cstate->base.active;
> >  	pipe_wm->sprites_enabled = sprstate->visible;
> >  	pipe_wm->sprites_scaled = config.sprites_scaled;
> >  
> > @@ -2425,7 +2405,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> >  	if (config.sprites_scaled)
> >  		max_level = 0;
> >  
> > -	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
> > +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
> >  
> >  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> >  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> > @@ -2442,7 +2422,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> >  	for (level = 1; level <= max_level; level++) {
> >  		struct intel_wm_level wm = {};
> >  
> > -		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
> > +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
> >  
> >  		/*
> >  		 * Disable any watermark level that exceeds the
> > @@ -3748,19 +3728,17 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
> >  static void ilk_update_wm(struct drm_crtc *crtc)
> >  {
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct ilk_wm_maximums max;
> > -	struct ilk_pipe_wm_parameters params = {};
> >  	struct ilk_wm_values results = {};
> >  	enum intel_ddb_partitioning partitioning;
> >  	struct intel_pipe_wm pipe_wm = {};
> >  	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
> >  	struct intel_wm_config config = {};
> >  
> > -	ilk_compute_wm_parameters(crtc, &params);
> > -
> > -	intel_compute_pipe_wm(crtc, &params, &pipe_wm);
> > +	intel_compute_pipe_wm(cstate, &pipe_wm);
> >  
> >  	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
> >  		return;
> > @@ -3800,12 +3778,6 @@ ilk_update_sprite_wm(struct drm_plane *plane,
> >  	struct drm_device *dev = plane->dev;
> >  	struct intel_plane *intel_plane = to_intel_plane(plane);
> >  
> > -	intel_plane->wm.enabled = enabled;
> > -	intel_plane->wm.scaled = scaled;
> > -	intel_plane->wm.horiz_pixels = sprite_width;
> > -	intel_plane->wm.vert_pixels = sprite_width;
> > -	intel_plane->wm.bytes_per_pixel = pixel_size;
> > -
> >  	/*
> >  	 * IVB workaround: must disable low power watermarks for at least
> >  	 * one frame before enabling scaling.  LP watermarks can be re-enabled
> > -- 
> > 2.1.4
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
  2015-08-26 15:37     ` Matt Roper
@ 2015-08-26 15:51       ` Ville Syrjälä
  2015-08-28 23:57         ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Matt Roper
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2015-08-26 15:51 UTC (permalink / raw)
  To: Matt Roper; +Cc: ander.conselvan.de.oliveira, intel-gfx

On Wed, Aug 26, 2015 at 08:37:41AM -0700, Matt Roper wrote:
> On Wed, Aug 26, 2015 at 04:39:12PM +0300, Ville Syrjälä wrote:
> > On Thu, Aug 20, 2015 at 06:11:53PM -0700, Matt Roper wrote:
> > > Just pull the info out of the CRTC state structure rather than staging
> > > it in an additional structure.
> > > 
> > > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_pm.c | 84 ++++++++++++++---------------------------
> > >  1 file changed, 28 insertions(+), 56 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > index c9cf7cf..d82ea82 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -1787,12 +1787,6 @@ struct skl_pipe_wm_parameters {
> > >  	struct intel_plane_wm_parameters cursor;
> > >  };
> > >  
> > > -struct ilk_pipe_wm_parameters {
> > > -	bool active;
> > > -	uint32_t pipe_htotal;
> > > -	uint32_t pixel_rate;
> > > -};
> > > -
> > >  struct ilk_wm_maximums {
> > >  	uint16_t pri;
> > >  	uint16_t spr;
> > > @@ -1811,7 +1805,7 @@ struct intel_wm_config {
> > >   * For both WM_PIPE and WM_LP.
> > >   * mem_value must be in 0.1us units.
> > >   */
> > > -static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> > > +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)
> > > @@ -1819,16 +1813,16 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> > >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> > >  	uint32_t method1, method2;
> > >  
> > > -	if (!params->active || !pstate->visible)
> > > +	if (!cstate->base.active || !pstate->visible)
> > >  		return 0;
> > 
> > Previously we lookd at crtc->active, now we look at state->base.active.
> > Since the atomic modeset code is a bit insane and doesn't have an
> > intermediate atomic state for the disable->re-enable case, I'm not sure
> > this will fly currently.
> > 
> > I'd be much happier if someone added the intermediate atomic state to
> > handle pipe disabling in a nicer way. Afterwards we should be able to
> > elimiate all special cases dealing with watermarks and just do the wm
> > updates from the commit_planes (or whatever it was called).
> 
> I think I'm missing some of the context for your comment.  At the moment
> we update watermarks after vblank if the CRTC is being re-enabled and
> before the vblank in other cases, so it seems like if we use
> crtc->active here, then when we get to the post-vblank watermark update
> we won't have any watermark values since we'll be acting on the old data
> that says the CRTC is still off.
> 
> When you talk about intermediate atomic state are you saying that you
> want to see CRTC enables take a two step process where the CRTC gets
> enabled with no planes first, then all the planes get turned on during
> the next vblank?

What I think should happen is something like this:

// whatever the user wanted
compute_final_atomic_state()

// include all crtcs in the intermediate state which are
// getting disabled (even temporarily to perform a modeset)
compute_intermediate_atomic_state()

ret = check_state_change(old, intermediate)
ret = check_state_change(intermediate, new)

// commit all planes in on go to make the pop out as atomically as
// possible
for_each_crtc_in(intermediate) {
        commit_planes()
}

for_each_crtc_in(intermediate) {
        disable_crtc()
}

for_each_crtc_in(new) {
        if (!currently_active)
                crtc_enable()
}

// commit all planes in on go to make the pop in as atomically as
// possible
for_each_crtc_in(new) {
        commit_planes()
}

> 
> 
> Matt
> 
> > 
> > >  
> > > -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> > > +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
> > >  
> > >  	if (!is_lp)
> > >  		return method1;
> > >  
> > > -	method2 = ilk_wm_method2(params->pixel_rate,
> > > -				 params->pipe_htotal,
> > > +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> > > +				 cstate->base.adjusted_mode.crtc_htotal,
> > >  				 drm_rect_width(&pstate->dst),
> > >  				 bpp,
> > >  				 mem_value);
> > > @@ -1840,19 +1834,19 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
> > >   * For both WM_PIPE and WM_LP.
> > >   * mem_value must be in 0.1us units.
> > >   */
> > > -static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> > > +static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
> > >  				   const struct intel_plane_state *pstate,
> > >  				   uint32_t mem_value)
> > >  {
> > >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> > >  	uint32_t method1, method2;
> > >  
> > > -	if (!params->active || !pstate->visible)
> > > +	if (!cstate->base.active || !pstate->visible)
> > >  		return 0;
> > >  
> > > -	method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
> > > -	method2 = ilk_wm_method2(params->pixel_rate,
> > > -				 params->pipe_htotal,
> > > +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
> > > +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> > > +				 cstate->base.adjusted_mode.crtc_htotal,
> > >  				 drm_rect_width(&pstate->dst),
> > >  				 bpp,
> > >  				 mem_value);
> > > @@ -1863,30 +1857,30 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
> > >   * For both WM_PIPE and WM_LP.
> > >   * mem_value must be in 0.1us units.
> > >   */
> > > -static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
> > > +static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
> > >  				   const struct intel_plane_state *pstate,
> > >  				   uint32_t mem_value)
> > >  {
> > >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> > >  
> > > -	if (!params->active || !pstate->visible)
> > > +	if (!cstate->base.active || !pstate->visible)
> > >  		return 0;
> > >  
> > > -	return ilk_wm_method2(params->pixel_rate,
> > > -			      params->pipe_htotal,
> > > +	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
> > > +			      cstate->base.adjusted_mode.crtc_htotal,
> > >  			      drm_rect_width(&pstate->dst),
> > >  			      bpp,
> > >  			      mem_value);
> > >  }
> > >  
> > >  /* Only for WM_LP. */
> > > -static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
> > > +static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
> > >  				   const struct intel_plane_state *pstate,
> > >  				   uint32_t pri_val)
> > >  {
> > >  	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
> > >  
> > > -	if (!params->active || !pstate->visible)
> > > +	if (!cstate->base.active || !pstate->visible)
> > >  		return 0;
> > >  
> > >  	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
> > > @@ -2056,7 +2050,7 @@ static bool ilk_validate_wm_level(int level,
> > >  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> > >  				 const struct intel_crtc *intel_crtc,
> > >  				 int level,
> > > -				 const struct ilk_pipe_wm_parameters *p,
> > > +				 struct intel_crtc_state *cstate,
> > >  				 struct intel_wm_level *result)
> > >  {
> > >  	struct intel_plane *intel_plane;
> > > @@ -2077,18 +2071,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
> > >  
> > >  		switch (intel_plane->base.type) {
> > >  		case DRM_PLANE_TYPE_PRIMARY:
> > > -			result->pri_val = ilk_compute_pri_wm(p, pstate,
> > > +			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
> > >  							     pri_latency,
> > >  							     level);
> > > -			result->fbc_val = ilk_compute_fbc_wm(p, pstate,
> > > +			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
> > >  							     result->pri_val);
> > >  			break;
> > >  		case DRM_PLANE_TYPE_OVERLAY:
> > > -			result->spr_val = ilk_compute_spr_wm(p, pstate,
> > > +			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
> > >  							     spr_latency);
> > >  			break;
> > >  		case DRM_PLANE_TYPE_CURSOR:
> > > -			result->cur_val = ilk_compute_cur_wm(p, pstate,
> > > +			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
> > >  							     cur_latency);
> > >  			break;
> > >  		}
> > > @@ -2352,19 +2346,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
> > >  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
> > >  }
> > >  
> > > -static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> > > -				      struct ilk_pipe_wm_parameters *p)
> > > -{
> > > -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > > -
> > > -	if (!intel_crtc->active)
> > > -		return;
> > > -
> > > -	p->active = true;
> > > -	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> > > -	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
> > > -}
> > > -
> > >  static void ilk_compute_wm_config(struct drm_device *dev,
> > >  				  struct intel_wm_config *config)
> > >  {
> > > @@ -2384,10 +2365,10 @@ static void ilk_compute_wm_config(struct drm_device *dev,
> > >  }
> > >  
> > >  /* Compute new watermarks for the pipe */
> > > -static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> > > -				  const struct ilk_pipe_wm_parameters *params,
> > > +static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
> > >  				  struct intel_pipe_wm *pipe_wm)
> > >  {
> > > +	struct drm_crtc *crtc = cstate->base.crtc;
> > >  	struct drm_device *dev = crtc->dev;
> > >  	const struct drm_i915_private *dev_priv = dev->dev_private;
> > >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > > @@ -2412,8 +2393,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> > >  		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
> > >  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
> > >  
> > > -
> > > -	pipe_wm->pipe_enabled = params->active;
> > > +	pipe_wm->pipe_enabled = cstate->base.active;
> > >  	pipe_wm->sprites_enabled = sprstate->visible;
> > >  	pipe_wm->sprites_scaled = config.sprites_scaled;
> > >  
> > > @@ -2425,7 +2405,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> > >  	if (config.sprites_scaled)
> > >  		max_level = 0;
> > >  
> > > -	ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
> > > +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
> > >  
> > >  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> > >  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> > > @@ -2442,7 +2422,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
> > >  	for (level = 1; level <= max_level; level++) {
> > >  		struct intel_wm_level wm = {};
> > >  
> > > -		ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
> > > +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
> > >  
> > >  		/*
> > >  		 * Disable any watermark level that exceeds the
> > > @@ -3748,19 +3728,17 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
> > >  static void ilk_update_wm(struct drm_crtc *crtc)
> > >  {
> > >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > > +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> > >  	struct drm_device *dev = crtc->dev;
> > >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > >  	struct ilk_wm_maximums max;
> > > -	struct ilk_pipe_wm_parameters params = {};
> > >  	struct ilk_wm_values results = {};
> > >  	enum intel_ddb_partitioning partitioning;
> > >  	struct intel_pipe_wm pipe_wm = {};
> > >  	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
> > >  	struct intel_wm_config config = {};
> > >  
> > > -	ilk_compute_wm_parameters(crtc, &params);
> > > -
> > > -	intel_compute_pipe_wm(crtc, &params, &pipe_wm);
> > > +	intel_compute_pipe_wm(cstate, &pipe_wm);
> > >  
> > >  	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
> > >  		return;
> > > @@ -3800,12 +3778,6 @@ ilk_update_sprite_wm(struct drm_plane *plane,
> > >  	struct drm_device *dev = plane->dev;
> > >  	struct intel_plane *intel_plane = to_intel_plane(plane);
> > >  
> > > -	intel_plane->wm.enabled = enabled;
> > > -	intel_plane->wm.scaled = scaled;
> > > -	intel_plane->wm.horiz_pixels = sprite_width;
> > > -	intel_plane->wm.vert_pixels = sprite_width;
> > > -	intel_plane->wm.bytes_per_pixel = pixel_size;
> > > -
> > >  	/*
> > >  	 * IVB workaround: must disable low power watermarks for at least
> > >  	 * one frame before enabling scaling.  LP watermarks can be re-enabled
> > > -- 
> > > 2.1.4
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel OTC
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

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

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

* Re: [PATCH 00/13] Atomic watermark updates (v3)
  2015-08-26  4:33 ` [PATCH 00/13] Atomic watermark updates (v3) Hindman, Gavin
@ 2015-08-26 18:07   ` Matt Roper
  0 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-26 18:07 UTC (permalink / raw)
  To: Hindman, Gavin; +Cc: Conselvan De Oliveira, Ander, intel-gfx

On Tue, Aug 25, 2015 at 09:33:41PM -0700, Hindman, Gavin wrote:
> Does this series comprehend all of the ddr-dvfs/PM-5 watermark reworks that Ville did towards the end of CHV, or is this series additive to that?

Are you referring to the series

    [PATCH 00/10] drm/i915: Another WM rewrite to enable DDR DVFS on CHV

?  If so, then I believe the work here should be orthogonal to that.
Ville's work there primarily deals with how the VLV/CHV-style watermarks
are calculated in a hardware-specific manner, whereas my series is more
about precomputing state in general earlier in the atomic pipeline so
that we can program the right values at the right times later.  My
series allows the details for specific platforms to be transitioned over
one at a time without impacting the other platforms, and so far I've
only moved ILK-style and SKL-style WM's over; I haven't touched the
VLV/CHV-style yet.  When we have the core code in a state everyone is
happy with and get to transitioning VLV/CHV, I don't think there should
be any conflicts with Ville's work.

Ville did have one general, platform-independent patch at the beginning of
his series, but my work should already be rebased to build on top of
that, so no concerns there.


Matt

> 
> Gavin Hindman
> Senior Program Manager
> SSG/OTC – Open Source Technology Center
> 
> 
> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Matt Roper
> Sent: Thursday, August 20, 2015 6:12 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Conselvan De Oliveira, Ander
> Subject: [Intel-gfx] [PATCH 00/13] Atomic watermark updates (v3)
> 
> Previous atomic watermark patches were posted here:
>   http://lists.freedesktop.org/archives/intel-gfx/2015-July/070465.html
> 
> Key changes since the last series:
>  * Quite a bit of rebasing; I got pulled away from working on this for a while,
>    so parts of the upstream code evolved a bit before I was able to get back
>    to working on this.
>  * Completely drop the async aspect of writing the final watermarks on
>    platforms that need two-step programming.  Although this is the direction we
>    want to go eventually, Maarten has indicated that what I was doing in
>    previous patch sets was going to lead to conflicts with some of his
>    in-progress work and asked that I just write the final watermarks at the
>    very end of the atomic transaction, after waiting for vblanks.  We can
>    revisit the async final step again after Maarten's work lands and leverage
>    the new interfaces he adds.  In the meantime, this simplifies things a
>    bit since we don't need to worry about async final watermark writing
>    racing with our next transaction and clobbering the intermediate values
>    for that next transaction that we've already written.
>  * Early SKL-style atomic watermarks (completely untested at the moment!).  Even
>    though gen9 doesn't need the two-step programming process, we now
>    pre-compute gen9 watermark values during the check phase and write+flush
>    them during commit.  However I think there's still more refactoring that
>    should be eventually done here.  We trigger watermark updates on a per-crtc
>    basis, but the end results are global, not per-crtc.  In an atomic
>    transaction this could currently lead to us re-calculating the same values
>    multiple times if multiple CRTC's all trigger a WM update.   Note that I
>    haven't had a chance to run any of this on real gen9 hardware yet, so all of
>    the SKL patches here should be considered RFC at best; they may be
>    completely broken.
>  * Various review feedback from Daniel, Ville, and Maarten from previous
>    iterations.
> 
> 
> Matt Roper (12):
>   drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM
>     code
>   drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM
>   drm/i915/skl: Simplify wm structures slightly
>   drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM
>   drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check
>   drm/i915: Drop intel_update_sprite_watermarks
>   drm/i915: Move active watermarks into CRTC state (v2)
>   drm/i915: Calculate ILK-style watermarks during atomic check (v2)
>   drm/i915: Calculate watermark configuration during atomic check
>   drm/i915: Add two-stage ILK-style watermark programming (v3)
>   drm/i915/skl: Switch to atomic watermark programming
>   drm/i915/skl: Clarify pending vs hw watermark values
> 
> Ville Syrjälä (1):
>   drm/i915: Refactor ilk_update_wm (v3)
> 
>  drivers/gpu/drm/i915/i915_debugfs.c  |   4 +-
>  drivers/gpu/drm/i915/i915_drv.h      |  68 ++-
>  drivers/gpu/drm/i915/intel_atomic.c  |   1 +
>  drivers/gpu/drm/i915/intel_display.c | 184 +++++++-
>  drivers/gpu/drm/i915/intel_drv.h     |  81 +++-
>  drivers/gpu/drm/i915/intel_pm.c      | 860 ++++++++++++++++-------------------
>  drivers/gpu/drm/i915/intel_sprite.c  |  15 -
>  7 files changed, 659 insertions(+), 554 deletions(-)
> 
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/13] drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM
  2015-08-21  1:11 ` [PATCH 04/13] drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM Matt Roper
@ 2015-08-27 12:55   ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-27 12:55 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:11 -0700, Matt Roper wrote:
> Just pull the info out of the state structures rather than staging
> it in an additional set of structures.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 304 ++++++++++++++++++----------------------
>  1 file changed, 135 insertions(+), 169 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index b9bcb85..0cfba0a 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1779,13 +1779,6 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
>  	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
>  }
>  
> -struct skl_pipe_wm_parameters {
> -	bool active;
> -	uint32_t pipe_htotal;
> -	uint32_t pixel_rate; /* in KHz */
> -	struct intel_plane_wm_parameters plane[I915_MAX_PLANES + 1];
> -};
> -
>  struct ilk_wm_maximums {
>  	uint16_t pri;
>  	uint16_t spr;
> @@ -2826,18 +2819,40 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
>  #define SKL_DDB_SIZE		896	/* in blocks */
>  #define BXT_DDB_SIZE		512
>  
> +/*
> + * Return the index of a plane in the SKL DDB and wm result arrays.  Primary
> + * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES, and
> + * other universal planes are in indices 1..n.  Note that this may leave
> + * unused indices between the top "sprite" plane and the cursor.
> + */
> +static int
> +skl_wm_plane_id(const struct intel_plane *plane)
> +{
> +	switch (plane->base.type) {
> +	case DRM_PLANE_TYPE_PRIMARY:
> +		return 0;
> +	case DRM_PLANE_TYPE_CURSOR:
> +		return I915_MAX_PLANES;
> +	case DRM_PLANE_TYPE_OVERLAY:
> +		return plane->plane;
> +	default:
> +		MISSING_CASE(plane->base.type);
> +		return plane->plane;
> +	}
> +}
> +
>  static void
>  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  				   struct drm_crtc *for_crtc,
>  				   const struct intel_wm_config *config,
> -				   const struct skl_pipe_wm_parameters *params,
> +				   const struct intel_crtc_state *cstate,
>  				   struct skl_ddb_entry *alloc /* out */)
>  {
>  	struct drm_crtc *crtc;
>  	unsigned int pipe_size, ddb_size;
>  	int nth_active_pipe;
>  
> -	if (!params->active) {
> +	if (!cstate->base.active) {
>  		alloc->start = 0;
>  		alloc->end = 0;
>  		return;
> @@ -2903,19 +2918,27 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
>  }
>  
>  static unsigned int
> -skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
> +skl_plane_relative_data_rate(const struct drm_plane_state *state, int y)
>  {
> +	struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
> +	struct drm_framebuffer *fb = state->fb;
>  
>  	/* for planar format */
> -	if (p->y_bytes_per_pixel) {
> +	if (fb->pixel_format == DRM_FORMAT_NV12) {
>  		if (y)  /* y-plane data rate */
> -			return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel;
> +			return intel_crtc->config->pipe_src_w *
> +				intel_crtc->config->pipe_src_h *
> +				drm_format_plane_cpp(fb->pixel_format, 0);
>  		else    /* uv-plane data rate */
> -			return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel;
> +			return (intel_crtc->config->pipe_src_w/2) *
> +				(intel_crtc->config->pipe_src_h/2) *
> +				drm_format_plane_cpp(fb->pixel_format, 1);
>  	}
>  
>  	/* for packed formats */
> -	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
> +	return intel_crtc->config->pipe_src_w *
> +		intel_crtc->config->pipe_src_h *
> +		fb->bits_per_pixel / 8;
>  }
>  
>  /*
> @@ -2924,23 +2947,24 @@ skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, 
> int y)
>   *   3 * 4096 * 8192  * 4 < 2^32
>   */
>  static unsigned int
> -skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
> -				 const struct skl_pipe_wm_parameters *params)
> +skl_get_total_relative_data_rate(const struct intel_crtc *intel_crtc)
>  {
> +	struct drm_device *dev = intel_crtc->base.dev;
> +	const struct intel_plane *intel_plane;
>  	unsigned int total_data_rate = 0;
> -	int plane;
>  
> -	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> -		const struct intel_plane_wm_parameters *p;
> +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +		const struct drm_plane_state *state = intel_plane->base.state;
>  
> -		p = &params->plane[plane];
> -		if (!p->enabled)
> +		if (WARN_ON(state->fb == NULL))
>  			continue;
>  
> -		total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */
> -		if (p->y_bytes_per_pixel) {
> -			total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */
> -		}
> +		/* packed/uv */
> +		total_data_rate += skl_plane_relative_data_rate(state, 0);
> +
> +		if (state->fb->pixel_format == DRM_FORMAT_NV12)
> +			/* y-plane */
> +			total_data_rate += skl_plane_relative_data_rate(state, 1);
>  	}
>  
>  	return total_data_rate;
> @@ -2949,21 +2973,20 @@ skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
>  static void
>  skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  		      const struct intel_wm_config *config,
> -		      const struct skl_pipe_wm_parameters *params,
> +		      const struct intel_crtc_state *cstate,
>  		      struct skl_ddb_allocation *ddb /* out */)
>  {
>  	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_plane *intel_plane;
>  	enum pipe pipe = intel_crtc->pipe;
>  	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
>  	uint16_t alloc_size, start, cursor_blocks;
>  	uint16_t minimum[I915_MAX_PLANES];
>  	uint16_t y_minimum[I915_MAX_PLANES];
>  	unsigned int total_data_rate;
> -	int plane;
>  
> -	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc);
> +	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, cstate, alloc);
>  	alloc_size = skl_ddb_entry_size(alloc);
>  	if (alloc_size == 0) {
>  		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
> @@ -2980,17 +3003,20 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	alloc->end -= cursor_blocks;
>  
>  	/* 1. Allocate the mininum required blocks for each active plane */
> -	for_each_plane(dev_priv, pipe, plane) {
> -		const struct intel_plane_wm_parameters *p;
> +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +		struct drm_plane *plane = &intel_plane->base;
> +		struct drm_framebuffer *fb = plane->fb;
> +		int id = skl_wm_plane_id(intel_plane);
>  
> -		p = &params->plane[plane];
> -		if (!p->enabled)
> +		if (fb == NULL)
> +			continue;
> +		if (plane->type == DRM_PLANE_TYPE_CURSOR)
>  			continue;
>  
> -		minimum[plane] = 8;
> -		alloc_size -= minimum[plane];
> -		y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0;
> -		alloc_size -= y_minimum[plane];
> +		minimum[id] = 8;
> +		alloc_size -= minimum[id];
> +		y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
> +		alloc_size -= y_minimum[id];
>  	}
>  
>  	/*
> @@ -2999,45 +3025,45 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	 *
>  	 * FIXME: we may not allocate every single block here.
>  	 */
> -	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
> +	total_data_rate = skl_get_total_relative_data_rate(intel_crtc);
>  
>  	start = alloc->start;
> -	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> -		const struct intel_plane_wm_parameters *p;
> +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +		struct drm_plane_state *state = intel_plane->base.state;
>  		unsigned int data_rate, y_data_rate;
>  		uint16_t plane_blocks, y_plane_blocks = 0;
> +		int id = skl_wm_plane_id(intel_plane);
>  
> -		p = &params->plane[plane];
> -		if (!p->enabled)
> +		if (state->fb == NULL)
>  			continue;

Doesn't this need

	if (plane->type == DRM_PLANE_TYPE_CURSOR)
		continue;

like above?

>  
> -		data_rate = skl_plane_relative_data_rate(p, 0);
> +		data_rate = skl_plane_relative_data_rate(state, 0);
>  
>  		/*
>  		 * allocation for (packed formats) or (uv-plane part of planar format):
>  		 * promote the expression to 64 bits to avoid overflowing, the
>  		 * result is < available as data_rate / total_data_rate < 1
>  		 */
> -		plane_blocks = minimum[plane];
> +		plane_blocks = minimum[id];
>  		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
>  					total_data_rate);
>  
> -		ddb->plane[pipe][plane].start = start;
> -		ddb->plane[pipe][plane].end = start + plane_blocks;
> +		ddb->plane[pipe][id].start = start;
> +		ddb->plane[pipe][id].end = start + plane_blocks;
>  
>  		start += plane_blocks;
>  
>  		/*
>  		 * allocation for y_plane part of planar format:
>  		 */
> -		if (p->y_bytes_per_pixel) {
> -			y_data_rate = skl_plane_relative_data_rate(p, 1);
> -			y_plane_blocks = y_minimum[plane];
> +		if (state->fb->pixel_format == DRM_FORMAT_NV12) {
> +			y_data_rate = skl_plane_relative_data_rate(state, 1);
> +			y_plane_blocks = y_minimum[id];
>  			y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
>  						total_data_rate);
>  
> -			ddb->y_plane[pipe][plane].start = start;
> -			ddb->y_plane[pipe][plane].end = start + y_plane_blocks;
> +			ddb->y_plane[pipe][id].start = start;
> +			ddb->y_plane[pipe][id].end = start + y_plane_blocks;
>  
>  			start += y_plane_blocks;
>  		}
> @@ -3138,72 +3164,16 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
>  	}
>  }
>  
> -static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
> -					   struct skl_pipe_wm_parameters *p)
> -{
> -	struct drm_device *dev = crtc->dev;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum pipe pipe = intel_crtc->pipe;
> -	struct drm_plane *plane;
> -	struct drm_framebuffer *fb;
> -	int i = 1; /* Index for sprite planes start */
> -
> -	p->active = intel_crtc->active;
> -	if (p->active) {
> -		p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> -		p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
> -
> -		fb = crtc->primary->state->fb;
> -		/* For planar: Bpp is for uv plane, y_Bpp is for y plane */
> -		if (fb) {
> -			p->plane[0].enabled = true;
> -			p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
> -				drm_format_plane_cpp(fb->pixel_format, 1) : fb->bits_per_pixel / 
> 8;
> -			p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
> -				drm_format_plane_cpp(fb->pixel_format, 0) : 0;
> -			p->plane[0].tiling = fb->modifier[0];
> -		} else {
> -			p->plane[0].enabled = false;
> -			p->plane[0].bytes_per_pixel = 0;
> -			p->plane[0].y_bytes_per_pixel = 0;
> -			p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
> -		}
> -		p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
> -		p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
> -		p->plane[0].rotation = crtc->primary->state->rotation;
> -
> -		fb = crtc->cursor->state->fb;
> -		p->plane[I915_MAX_PLANES].y_bytes_per_pixel = 0;
> -		if (fb) {
> -			p->plane[I915_MAX_PLANES].enabled = true;
> -			p->plane[I915_MAX_PLANES].bytes_per_pixel = fb->bits_per_pixel / 8;
> -			p->plane[I915_MAX_PLANES].horiz_pixels = crtc->cursor->state->crtc_w;
> -			p->plane[I915_MAX_PLANES].vert_pixels = crtc->cursor->state->crtc_h;
> -		} else {
> -			p->plane[I915_MAX_PLANES].enabled = false;
> -			p->plane[I915_MAX_PLANES].bytes_per_pixel = 0;
> -			p->plane[I915_MAX_PLANES].horiz_pixels = 64;
> -			p->plane[I915_MAX_PLANES].vert_pixels = 64;
> -		}
> -	}
> -
> -	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> -		struct intel_plane *intel_plane = to_intel_plane(plane);
> -
> -		if (intel_plane->pipe == pipe &&
> -			plane->type == DRM_PLANE_TYPE_OVERLAY)
> -			p->plane[i++] = intel_plane->wm;
> -	}
> -}
> -
>  static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> -				 struct skl_pipe_wm_parameters *p,
> -				 struct intel_plane_wm_parameters *p_params,
> +				 struct intel_crtc *intel_crtc,
> +				 struct intel_plane *intel_plane,
>  				 uint16_t ddb_allocation,
>  				 int level,
>  				 uint16_t *out_blocks, /* out */
>  				 uint8_t *out_lines /* out */)
>  {
> +	struct drm_plane *plane = &intel_plane->base;
> +	struct drm_framebuffer *fb = plane->state->fb;
>  	uint32_t latency = dev_priv->wm.skl_latency[level];
>  	uint32_t method1, method2;
>  	uint32_t plane_bytes_per_line, plane_blocks_per_line;
> @@ -3211,31 +3181,35 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	uint32_t selected_result;
>  	uint8_t bytes_per_pixel;
>  
> -	if (latency == 0 || !p->active || !p_params->enabled)
> +	if (latency == 0 || !intel_crtc->active || !fb)

In other places you replaced p->actice with cstate->active. Is there a reason why this one doesn't
look at the state? 

>  		return false;
>  
> -	bytes_per_pixel = p_params->y_bytes_per_pixel ?
> -		p_params->y_bytes_per_pixel :
> -		p_params->bytes_per_pixel;
> -	method1 = skl_wm_method1(p->pixel_rate,
> +	bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
> +		drm_format_plane_cpp(DRM_FORMAT_NV12, 0) :
> +		fb->bits_per_pixel / 8;
> +	method1 = skl_wm_method1(skl_pipe_pixel_rate(intel_crtc->config),
>  				 bytes_per_pixel,
>  				 latency);
> -	method2 = skl_wm_method2(p->pixel_rate,
> -				 p->pipe_htotal,
> -				 p_params->horiz_pixels,
> +	method2 = skl_wm_method2(skl_pipe_pixel_rate(intel_crtc->config),
> +				 intel_crtc->config->base.adjusted_mode.crtc_htotal,
> +				 intel_crtc->config->pipe_src_w,

The other functions were changed to receive the crtc state as an argument. Maybe it would be good to
do that here too for consistency.

Ander

>  				 bytes_per_pixel,
> -				 p_params->tiling,
> +				 fb->modifier[0],
>  				 latency);
>  
> -	plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel;
> +	plane_bytes_per_line = intel_crtc->config->pipe_src_w * bytes_per_pixel;
>  	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
>  
> -	if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
> -	    p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
> +	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> +	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
>  		uint32_t min_scanlines = 4;
>  		uint32_t y_tile_minimum;
> -		if (intel_rotation_90_or_270(p_params->rotation)) {
> -			switch (p_params->bytes_per_pixel) {
> +		if (intel_rotation_90_or_270(plane->state->rotation)) {
> +			int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
> +				drm_format_plane_cpp(fb->pixel_format, 1) :
> +				fb->bits_per_pixel / 8;
> +
> +			switch (bpp) {
>  			case 1:
>  				min_scanlines = 16;
>  				break;
> @@ -3259,8 +3233,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
>  
>  	if (level >= 1 && level <= 7) {
> -		if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
> -		    p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
> +		if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> +		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
>  			res_lines += 4;
>  		else
>  			res_blocks++;
> @@ -3277,65 +3251,64 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  
>  static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
>  				 struct skl_ddb_allocation *ddb,
> -				 struct skl_pipe_wm_parameters *p,
> -				 enum pipe pipe,
> +				 struct intel_crtc *intel_crtc,
>  				 int level,
> -				 int num_planes,
>  				 struct skl_wm_level *result)
>  {
> +	struct drm_device *dev = intel_crtc->base.dev;
> +	struct intel_plane *intel_plane;
>  	uint16_t ddb_blocks;
> -	int i;
> +	enum pipe pipe = intel_crtc->pipe;
> +
> +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +		int i = skl_wm_plane_id(intel_plane);
>  
> -	for (i = 0; i < num_planes; i++) {
>  		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
>  
>  		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
> -						p, &p->plane[i],
> +						intel_crtc,
> +						intel_plane,
>  						ddb_blocks,
>  						level,
>  						&result->plane_res_b[i],
>  						&result->plane_res_l[i]);
>  	}
> -
> -	ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][I915_MAX_PLANES]);
> -	result->plane_en[I915_MAX_PLANES] = skl_compute_plane_wm(dev_priv, p,
> -						 &p->plane[I915_MAX_PLANES],
> -						 ddb_blocks, level,
> -						 &result->plane_res_b[I915_MAX_PLANES],
> -						 &result->plane_res_l[I915_MAX_PLANES]);
>  }
>  
>  static uint32_t
> -skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
> +skl_compute_linetime_wm(struct intel_crtc_state *cstate)
>  {
> -	if (!to_intel_crtc(crtc)->active)
> +	if (!cstate->base.active)
>  		return 0;
>  
> -	if (WARN_ON(p->pixel_rate == 0))
> +	if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
>  		return 0;
>  
> -	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
> +	return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
> +			    skl_pipe_pixel_rate(cstate));
>  }
>  
> -static void skl_compute_transition_wm(struct drm_crtc *crtc,
> -				      struct skl_pipe_wm_parameters *params,
> +static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
>  				      struct skl_wm_level *trans_wm /* out */)
>  {
> +	struct drm_crtc *crtc = cstate->base.crtc;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	int i;
> +	struct intel_plane *intel_plane;
>  
> -	if (!params->active)
> +	if (!cstate->base.active)
>  		return;
>  
>  	/* Until we know more, just disable transition WMs */
> -	for (i = 0; i < intel_num_planes(intel_crtc); i++)
> +	for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
> +		int i = skl_wm_plane_id(intel_plane);
> +
>  		trans_wm->plane_en[i] = false;
> -	trans_wm->plane_en[I915_MAX_PLANES] = false;
> +	}
>  }
>  
>  static void skl_compute_pipe_wm(struct drm_crtc *crtc,
>  				struct skl_ddb_allocation *ddb,
> -				struct skl_pipe_wm_parameters *params,
> +				struct intel_crtc_state *cstate,
>  				struct skl_pipe_wm *pipe_wm)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -3344,17 +3317,15 @@ static void skl_compute_pipe_wm(struct drm_crtc *crtc,
>  	int level, max_level = ilk_wm_max_level(dev);
>  
>  	for (level = 0; level <= max_level; level++) {
> -		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
> -				     level, intel_num_planes(intel_crtc),
> -				     &pipe_wm->wm[level]);
> +		skl_compute_wm_level(dev_priv, ddb, intel_crtc,
> +				     level, &pipe_wm->wm[level]);
>  	}
> -	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
> +	pipe_wm->linetime = skl_compute_linetime_wm(cstate);
>  
> -	skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm);
> +	skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
>  }
>  
>  static void skl_compute_wm_results(struct drm_device *dev,
> -				   struct skl_pipe_wm_parameters *p,
>  				   struct skl_pipe_wm *p_wm,
>  				   struct skl_wm_values *r,
>  				   struct intel_crtc *intel_crtc)
> @@ -3598,16 +3569,15 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
>  }
>  
>  static bool skl_update_pipe_wm(struct drm_crtc *crtc,
> -			       struct skl_pipe_wm_parameters *params,
>  			       struct intel_wm_config *config,
>  			       struct skl_ddb_allocation *ddb, /* out */
>  			       struct skl_pipe_wm *pipe_wm /* out */)
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
>  
> -	skl_compute_wm_pipe_parameters(crtc, params);
> -	skl_allocate_pipe_ddb(crtc, config, params, ddb);
> -	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
> +	skl_allocate_pipe_ddb(crtc, config, cstate, ddb);
> +	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
>  
>  	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
>  		return false;
> @@ -3640,7 +3610,6 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
>  	 */
>  	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
>  				base.head) {
> -		struct skl_pipe_wm_parameters params = {};
>  		struct skl_pipe_wm pipe_wm = {};
>  		bool wm_changed;
>  
> @@ -3650,8 +3619,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
>  		if (!intel_crtc->active)
>  			continue;
>  
> -		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
> -						&params, config,
> +		wm_changed = skl_update_pipe_wm(&intel_crtc->base, config,
>  						&r->ddb, &pipe_wm);
>  
>  		/*
> @@ -3661,7 +3629,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
>  		 */
>  		WARN_ON(!wm_changed);
>  
> -		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
> +		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
>  		r->dirty[intel_crtc->pipe] = true;
>  	}
>  }
> @@ -3671,7 +3639,6 @@ static void skl_update_wm(struct drm_crtc *crtc)
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct skl_pipe_wm_parameters params = {};
>  	struct skl_wm_values *results = &dev_priv->wm.skl_results;
>  	struct skl_pipe_wm pipe_wm = {};
>  	struct intel_wm_config config = {};
> @@ -3680,11 +3647,10 @@ static void skl_update_wm(struct drm_crtc *crtc)
>  
>  	skl_compute_wm_global_parameters(dev, &config);
>  
> -	if (!skl_update_pipe_wm(crtc, &params, &config,
> -				&results->ddb, &pipe_wm))
> +	if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
>  		return;
>  
> -	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
> +	skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
>  	results->dirty[intel_crtc->pipe] = true;
>  
>  	skl_update_other_pipe_wm(dev, crtc, &config, results);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2)
  2015-08-21  1:12 ` [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2) Matt Roper
@ 2015-08-28 12:53   ` Ander Conselvan De Oliveira
  2015-08-28 12:56   ` Ander Conselvan De Oliveira
  1 sibling, 0 replies; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-28 12:53 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:12 -0700, Matt Roper wrote:
> Calculate pipe watermarks during atomic calculation phase, based on the
> contents of the atomic transaction's state structure.  We still program
> the watermarks at the same time we did before, but the computation now
> happens much earlier.
> 
> While this patch isn't too exciting by itself, it paves the way for
> future patches.  The eventual goal (which will be realized in future
> patches in this series) is to calculate multiple sets up watermark
> values up front, and then program them at different times (pre- vs
> post-vblank) on the platforms that need a two-step watermark update.
> 
> While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since
> this function only applies to ILK-style watermarks and we have a
> completely different function for SKL-style watermarks.
> 
> Note that the original code had a memcmp() in ilk_update_wm() to avoid
> calling ilk_program_watermarks() if the watermarks hadn't changed.  This
> memcmp vanishes here, which means we may do some unnecessary result
> generation and merging in cases where watermarks didn't change, but the
> lower-level function ilk_write_wm_values already makes sure that we
> don't actually try to program the watermark registers again.
> 
> v2: Squash a few commits from the original series together; no longer
>     leave pre-calculated wm's in a separate temporary structure since
>     it's easier to follow the logic if we just cut over to using the
>     pre-calculated values directly.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  2 +
>  drivers/gpu/drm/i915/intel_display.c |  6 +++
>  drivers/gpu/drm/i915/intel_drv.h     |  2 +
>  drivers/gpu/drm/i915/intel_pm.c      | 87 ++++++++++++++++++------------------
>  4 files changed, 53 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 7c58f38..c91bab9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -620,6 +620,8 @@ struct drm_i915_display_funcs {
>  			  int target, int refclk,
>  			  struct dpll *match_clock,
>  			  struct dpll *best_clock);
> +	int (*compute_pipe_wm)(struct drm_crtc *crtc,
> +			       struct drm_atomic_state *state);
>  	void (*update_wm)(struct drm_crtc *crtc);
>  	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
>  	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 6bcc3da..c40f025 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11791,6 +11791,12 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  	}
>  
>  	ret = 0;
> +	if (dev_priv->display.compute_pipe_wm) {
> +		ret = dev_priv->display.compute_pipe_wm(crtc, state);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	if (INTEL_INFO(dev)->gen >= 9) {
>  		if (mode_changed)
>  			ret = skl_update_scaler_crtc(pipe_config);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index dfbfba9..f9cac4b 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1427,6 +1427,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
>  int intel_atomic_setup_scalers(struct drm_device *dev,
>  	struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state);
> +int intel_check_crtc(struct drm_crtc *crtc,
> +		     struct drm_crtc_state *state);
>  
>  /* intel_atomic_plane.c */
>  struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 04fc092..bc29260 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2043,9 +2043,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  				 const struct intel_crtc *intel_crtc,
>  				 int level,
>  				 struct intel_crtc_state *cstate,
> +				 struct intel_plane_state *pristate,
> +				 struct intel_plane_state *sprstate,
> +				 struct intel_plane_state *curstate,
>  				 struct intel_wm_level *result)
>  {
> -	struct intel_plane *intel_plane;
>  	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];
> @@ -2057,29 +2059,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  		cur_latency *= 5;
>  	}
>  
> -	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
> -		struct intel_plane_state *pstate =
> -			to_intel_plane_state(intel_plane->base.state);
> -
> -		switch (intel_plane->base.type) {
> -		case DRM_PLANE_TYPE_PRIMARY:
> -			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
> -							     pri_latency,
> -							     level);
> -			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
> -							     result->pri_val);
> -			break;
> -		case DRM_PLANE_TYPE_OVERLAY:
> -			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
> -							     spr_latency);
> -			break;
> -		case DRM_PLANE_TYPE_CURSOR:
> -			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
> -							     cur_latency);
> -			break;
> -		}
> -	}
> -
> +	result->pri_val = ilk_compute_pri_wm(cstate, pristate,
> +					     pri_latency, level);
> +	result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
> +	result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
> +	result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
>  	result->enable = true;
>  }
>  
> @@ -2359,15 +2343,20 @@ static void ilk_compute_wm_config(struct drm_device *dev,
>  }
>  
>  /* Compute new watermarks for the pipe */
> -static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
> -				  struct intel_pipe_wm *pipe_wm)
> +static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
> +			       struct drm_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = cstate->base.crtc;
> +	struct intel_pipe_wm *pipe_wm;
>  	struct drm_device *dev = crtc->dev;
>  	const struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_crtc_state *cs;
> +	struct intel_crtc_state *cstate = NULL;
>  	struct intel_plane *intel_plane;
> +	struct drm_plane_state *ps;
> +	struct intel_plane_state *pristate = NULL;
>  	struct intel_plane_state *sprstate = NULL;
> +	struct intel_plane_state *curstate = NULL;
>  	int level, max_level = ilk_wm_max_level(dev);
>  	/* LP0 watermark maximums depend on this pipe alone */
>  	struct intel_wm_config config = {
> @@ -2375,11 +2364,26 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  	};
>  	struct ilk_wm_maximums max;
>  
> +	cs = drm_atomic_get_crtc_state(state, crtc);
> +	if (IS_ERR(cs))
> +		return PTR_ERR(cs);
> +	else
> +		cstate = to_intel_crtc_state(cs);

You could replace this with intel_atomic_get_crtc_state(). Maybe even pass an intel_crtc to this
function instead of a drm one, since there is only one other place besides this where the drm one is
used.

Ander

> +
> +	pipe_wm = &cstate->wm.active.ilk;
> +
>  	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> -		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
> -			sprstate = to_intel_plane_state(intel_plane->base.state);
> -			break;
> -		}
> +		ps = drm_atomic_get_plane_state(state,
> +						&intel_plane->base);
> +		if (IS_ERR(ps))
> +			return PTR_ERR(ps);
> +
> +		if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
> +			pristate = to_intel_plane_state(ps);
> +		else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
> +			sprstate = to_intel_plane_state(ps);
> +		else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
> +			curstate = to_intel_plane_state(ps);
>  	}
>  
>  	config.sprites_enabled = sprstate->visible;
> @@ -2388,7 +2392,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
>  
>  	pipe_wm->pipe_enabled = cstate->base.active;
> -	pipe_wm->sprites_enabled = sprstate->visible;
> +	pipe_wm->sprites_enabled = config.sprites_enabled;
>  	pipe_wm->sprites_scaled = config.sprites_scaled;
>  
>  	/* ILK/SNB: LP2+ watermarks only w/o sprites */
> @@ -2399,7 +2403,8 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  	if (config.sprites_scaled)
>  		max_level = 0;
>  
> -	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
> +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
> +			     pristate, sprstate, curstate, &pipe_wm->wm[0]);
>  
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> @@ -2409,14 +2414,15 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  
>  	/* At least LP0 must be valid */
>  	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
> -		return false;
> +		return -EINVAL;
>  
>  	ilk_compute_wm_reg_maximums(dev, 1, &max);
>  
>  	for (level = 1; level <= max_level; level++) {
>  		struct intel_wm_level wm = {};
>  
> -		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
> +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
> +				     pristate, sprstate, curstate, &wm);
>  
>  		/*
>  		 * Disable any watermark level that exceeds the
> @@ -2429,7 +2435,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  		pipe_wm->wm[level] = wm;
>  	}
>  
> -	return true;
> +	return 0;
>  }
>  
>  /*
> @@ -3694,7 +3700,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> -	struct intel_pipe_wm pipe_wm = {};
>  
>  	/*
>  	 * IVB workaround: must disable low power watermarks for at least
> @@ -3708,13 +3713,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
>  		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
>  	}
>  
> -	intel_compute_pipe_wm(cstate, &pipe_wm);
> -
> -	if (!memcmp(&cstate->wm.active.ilk, &pipe_wm, sizeof(pipe_wm)))
> -		return;
> -
> -	cstate->wm.active.ilk = pipe_wm;
> -
>  	ilk_program_watermarks(dev_priv);
>  }
>  
> @@ -6994,6 +6992,7 @@ void intel_init_pm(struct drm_device *dev)
>  		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
>  		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
>  			dev_priv->display.update_wm = ilk_update_wm;
> +			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
>  		} else {
>  			DRM_DEBUG_KMS("Failed to read display plane latency. "
>  				      "Disable CxSR\n");
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2)
  2015-08-21  1:12 ` [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2) Matt Roper
  2015-08-28 12:53   ` Ander Conselvan De Oliveira
@ 2015-08-28 12:56   ` Ander Conselvan De Oliveira
  1 sibling, 0 replies; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-28 12:56 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:12 -0700, Matt Roper wrote:
> Calculate pipe watermarks during atomic calculation phase, based on the
> contents of the atomic transaction's state structure.  We still program
> the watermarks at the same time we did before, but the computation now
> happens much earlier.
> 
> While this patch isn't too exciting by itself, it paves the way for
> future patches.  The eventual goal (which will be realized in future
> patches in this series) is to calculate multiple sets up watermark
> values up front, and then program them at different times (pre- vs
> post-vblank) on the platforms that need a two-step watermark update.
> 
> While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since
> this function only applies to ILK-style watermarks and we have a
> completely different function for SKL-style watermarks.
> 
> Note that the original code had a memcmp() in ilk_update_wm() to avoid
> calling ilk_program_watermarks() if the watermarks hadn't changed.  This
> memcmp vanishes here, which means we may do some unnecessary result
> generation and merging in cases where watermarks didn't change, but the
> lower-level function ilk_write_wm_values already makes sure that we
> don't actually try to program the watermark registers again.
> 
> v2: Squash a few commits from the original series together; no longer
>     leave pre-calculated wm's in a separate temporary structure since
>     it's easier to follow the logic if we just cut over to using the
>     pre-calculated values directly.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  2 +
>  drivers/gpu/drm/i915/intel_display.c |  6 +++
>  drivers/gpu/drm/i915/intel_drv.h     |  2 +
>  drivers/gpu/drm/i915/intel_pm.c      | 87 ++++++++++++++++++------------------
>  4 files changed, 53 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 7c58f38..c91bab9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -620,6 +620,8 @@ struct drm_i915_display_funcs {
>  			  int target, int refclk,
>  			  struct dpll *match_clock,
>  			  struct dpll *best_clock);
> +	int (*compute_pipe_wm)(struct drm_crtc *crtc,
> +			       struct drm_atomic_state *state);
>  	void (*update_wm)(struct drm_crtc *crtc);
>  	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
>  	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 6bcc3da..c40f025 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11791,6 +11791,12 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  	}
>  
>  	ret = 0;
> +	if (dev_priv->display.compute_pipe_wm) {
> +		ret = dev_priv->display.compute_pipe_wm(crtc, state);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	if (INTEL_INFO(dev)->gen >= 9) {
>  		if (mode_changed)
>  			ret = skl_update_scaler_crtc(pipe_config);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index dfbfba9..f9cac4b 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1427,6 +1427,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
>  int intel_atomic_setup_scalers(struct drm_device *dev,
>  	struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state);
> +int intel_check_crtc(struct drm_crtc *crtc,
> +		     struct drm_crtc_state *state);

This function is not defined or used anywhere in the patch.

Ander

>  
>  /* intel_atomic_plane.c */
>  struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 04fc092..bc29260 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2043,9 +2043,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  				 const struct intel_crtc *intel_crtc,
>  				 int level,
>  				 struct intel_crtc_state *cstate,
> +				 struct intel_plane_state *pristate,
> +				 struct intel_plane_state *sprstate,
> +				 struct intel_plane_state *curstate,
>  				 struct intel_wm_level *result)
>  {
> -	struct intel_plane *intel_plane;
>  	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];
> @@ -2057,29 +2059,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
>  		cur_latency *= 5;
>  	}
>  
> -	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
> -		struct intel_plane_state *pstate =
> -			to_intel_plane_state(intel_plane->base.state);
> -
> -		switch (intel_plane->base.type) {
> -		case DRM_PLANE_TYPE_PRIMARY:
> -			result->pri_val = ilk_compute_pri_wm(cstate, pstate,
> -							     pri_latency,
> -							     level);
> -			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
> -							     result->pri_val);
> -			break;
> -		case DRM_PLANE_TYPE_OVERLAY:
> -			result->spr_val = ilk_compute_spr_wm(cstate, pstate,
> -							     spr_latency);
> -			break;
> -		case DRM_PLANE_TYPE_CURSOR:
> -			result->cur_val = ilk_compute_cur_wm(cstate, pstate,
> -							     cur_latency);
> -			break;
> -		}
> -	}
> -
> +	result->pri_val = ilk_compute_pri_wm(cstate, pristate,
> +					     pri_latency, level);
> +	result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
> +	result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
> +	result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
>  	result->enable = true;
>  }
>  
> @@ -2359,15 +2343,20 @@ static void ilk_compute_wm_config(struct drm_device *dev,
>  }
>  
>  /* Compute new watermarks for the pipe */
> -static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
> -				  struct intel_pipe_wm *pipe_wm)
> +static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
> +			       struct drm_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = cstate->base.crtc;
> +	struct intel_pipe_wm *pipe_wm;
>  	struct drm_device *dev = crtc->dev;
>  	const struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_crtc_state *cs;
> +	struct intel_crtc_state *cstate = NULL;
>  	struct intel_plane *intel_plane;
> +	struct drm_plane_state *ps;
> +	struct intel_plane_state *pristate = NULL;
>  	struct intel_plane_state *sprstate = NULL;
> +	struct intel_plane_state *curstate = NULL;
>  	int level, max_level = ilk_wm_max_level(dev);
>  	/* LP0 watermark maximums depend on this pipe alone */
>  	struct intel_wm_config config = {
> @@ -2375,11 +2364,26 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  	};
>  	struct ilk_wm_maximums max;
>  
> +	cs = drm_atomic_get_crtc_state(state, crtc);
> +	if (IS_ERR(cs))
> +		return PTR_ERR(cs);
> +	else
> +		cstate = to_intel_crtc_state(cs);
> +
> +	pipe_wm = &cstate->wm.active.ilk;
> +
>  	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> -		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
> -			sprstate = to_intel_plane_state(intel_plane->base.state);
> -			break;
> -		}
> +		ps = drm_atomic_get_plane_state(state,
> +						&intel_plane->base);
> +		if (IS_ERR(ps))
> +			return PTR_ERR(ps);
> +
> +		if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
> +			pristate = to_intel_plane_state(ps);
> +		else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
> +			sprstate = to_intel_plane_state(ps);
> +		else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
> +			curstate = to_intel_plane_state(ps);
>  	}
>  
>  	config.sprites_enabled = sprstate->visible;
> @@ -2388,7 +2392,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
>  
>  	pipe_wm->pipe_enabled = cstate->base.active;
> -	pipe_wm->sprites_enabled = sprstate->visible;
> +	pipe_wm->sprites_enabled = config.sprites_enabled;
>  	pipe_wm->sprites_scaled = config.sprites_scaled;
>  
>  	/* ILK/SNB: LP2+ watermarks only w/o sprites */
> @@ -2399,7 +2403,8 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  	if (config.sprites_scaled)
>  		max_level = 0;
>  
> -	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
> +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
> +			     pristate, sprstate, curstate, &pipe_wm->wm[0]);
>  
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
> @@ -2409,14 +2414,15 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  
>  	/* At least LP0 must be valid */
>  	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
> -		return false;
> +		return -EINVAL;
>  
>  	ilk_compute_wm_reg_maximums(dev, 1, &max);
>  
>  	for (level = 1; level <= max_level; level++) {
>  		struct intel_wm_level wm = {};
>  
> -		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
> +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
> +				     pristate, sprstate, curstate, &wm);
>  
>  		/*
>  		 * Disable any watermark level that exceeds the
> @@ -2429,7 +2435,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
>  		pipe_wm->wm[level] = wm;
>  	}
>  
> -	return true;
> +	return 0;
>  }
>  
>  /*
> @@ -3694,7 +3700,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> -	struct intel_pipe_wm pipe_wm = {};
>  
>  	/*
>  	 * IVB workaround: must disable low power watermarks for at least
> @@ -3708,13 +3713,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
>  		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
>  	}
>  
> -	intel_compute_pipe_wm(cstate, &pipe_wm);
> -
> -	if (!memcmp(&cstate->wm.active.ilk, &pipe_wm, sizeof(pipe_wm)))
> -		return;
> -
> -	cstate->wm.active.ilk = pipe_wm;
> -
>  	ilk_program_watermarks(dev_priv);
>  }
>  
> @@ -6994,6 +6992,7 @@ void intel_init_pm(struct drm_device *dev)
>  		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
>  		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
>  			dev_priv->display.update_wm = ilk_update_wm;
> +			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
>  		} else {
>  			DRM_DEBUG_KMS("Failed to read display plane latency. "
>  				      "Disable CxSR\n");
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check
  2015-08-21  1:12 ` [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check Matt Roper
@ 2015-08-28 13:42   ` Ander Conselvan De Oliveira
  2015-09-01  5:32     ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-28 13:42 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:12 -0700, Matt Roper wrote:
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      | 10 ++++++
>  drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_drv.h     |  1 +
>  drivers/gpu/drm/i915/intel_pm.c      | 66 +++++++-----------------------------
>  4 files changed, 71 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c91bab9..ac13cd7 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1686,6 +1686,13 @@ struct i915_execbuffer_params {
>  	struct drm_i915_gem_request     *request;
>  };
>  
> +/* used in computing the new watermarks state */
> +struct intel_wm_config {
> +	unsigned int num_pipes_active;
> +	bool sprites_enabled;
> +	bool sprites_scaled;
> +};
> +
>  struct drm_i915_private {
>  	struct drm_device *dev;
>  	struct kmem_cache *objects;
> @@ -1903,6 +1910,9 @@ struct drm_i915_private {
>  		 */
>  		uint16_t skl_latency[8];
>  
> +		/* Committed wm config */
> +		struct intel_wm_config config;
> +
>  		/*
>  		 * The skl_wm_values structure is a bit too big for stack
>  		 * allocation, so we keep the staging struct where we store
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c40f025..8e9d87a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13005,6 +13005,44 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  	return 0;
>  }
>  
> +/*
> + * Handle calculation of various watermark data at the end of the atomic check
> + * phase.  The code here should be run after the per-crtc and per-plane 'check'
> + * handlers to ensure that all derived state has been updated.
> + */
> +static void calc_watermark_data(struct drm_atomic_state *state)
> +{
> +	struct drm_device *dev = state->dev;
> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *cstate;
> +	struct drm_plane *plane;
> +	struct drm_plane_state *pstate;
> +
> +	/*
> +	 * Calculate watermark configuration details now that derived
> +	 * plane/crtc state is all properly updated.
> +	 */
> +	drm_for_each_crtc(crtc, dev) {
> +		cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
> +			crtc->state;
> +

Did you intend to check crtc->active here?

> +		intel_state->wm_config.num_pipes_active++;
> +	}
> +	drm_for_each_legacy_plane(plane, dev) {
> +		pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
> +			plane->state;
> +
> +		if (!to_intel_plane_state(pstate)->visible)
> +			continue;

If I understand correctly, it is possible for a plane on an inactive crtc to have visible = true. In
that case, the result here would be different than the function this replaces, which counts only
planes on active crtcs.


Ander

> +
> +		intel_state->wm_config.sprites_enabled = true;
> +		if (pstate->crtc_w != pstate->src_w >> 16 ||
> +		    pstate->crtc_h != pstate->src_h >> 16)
> +			intel_state->wm_config.sprites_scaled = true;
> +	}
> +}
> +
>  /**
>   * intel_atomic_check - validate state object
>   * @dev: drm device
> @@ -13013,6 +13051,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  static int intel_atomic_check(struct drm_device *dev,
>  			      struct drm_atomic_state *state)
>  {
> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *crtc_state;
>  	int ret, i;
> @@ -13076,10 +13115,15 @@ static int intel_atomic_check(struct drm_device *dev,
>  		if (ret)
>  			return ret;
>  	} else
> -		to_intel_atomic_state(state)->cdclk =
> -			to_i915(state->dev)->cdclk_freq;
> +		intel_state->cdclk = to_i915(state->dev)->cdclk_freq;
>  
> -	return drm_atomic_helper_check_planes(state->dev, state);
> +	ret = drm_atomic_helper_check_planes(state->dev, state);
> +	if (ret)
> +		return ret;
> +
> +	calc_watermark_data(state);
> +
> +	return 0;
>  }
>  
>  /**
> @@ -13119,6 +13163,7 @@ static int intel_atomic_commit(struct drm_device *dev,
>  		return ret;
>  
>  	drm_atomic_helper_swap_state(dev, state);
> +	dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
>  
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>  		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index f9cac4b..6ac1010c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -239,6 +239,7 @@ struct intel_atomic_state {
>  	unsigned int cdclk;
>  	bool dpll_set;
>  	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
> +	struct intel_wm_config wm_config;
>  };
>  
>  struct intel_plane_state {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index bc29260..b32d6b0 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1786,13 +1786,6 @@ struct ilk_wm_maximums {
>  	uint16_t fbc;
>  };
>  
> -/* used in computing the new watermarks state */
> -struct intel_wm_config {
> -	unsigned int num_pipes_active;
> -	bool sprites_enabled;
> -	bool sprites_scaled;
> -};
> -
>  /*
>   * For both WM_PIPE and WM_LP.
>   * mem_value must be in 0.1us units.
> @@ -2322,26 +2315,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
>  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
>  }
>  
> -static void ilk_compute_wm_config(struct drm_device *dev,
> -				  struct intel_wm_config *config)
> -{
> -	struct intel_crtc *intel_crtc;
> -
> -	/* Compute the currently _active_ config */
> -	for_each_intel_crtc(dev, intel_crtc) {
> -		const struct intel_crtc_state *cstate =
> -			to_intel_crtc_state(intel_crtc->base.state);
> -		const struct intel_pipe_wm *wm = &cstate->wm.active.ilk;
> -
> -		if (!wm->pipe_enabled)
> -			continue;
> -
> -		config->sprites_enabled |= wm->sprites_enabled;
> -		config->sprites_scaled |= wm->sprites_scaled;
> -		config->num_pipes_active++;
> -	}
> -}
> -
>  /* Compute new watermarks for the pipe */
>  static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  			       struct drm_atomic_state *state)
> @@ -2983,11 +2956,12 @@ skl_get_total_relative_data_rate(const struct intel_crtc *intel_crtc)
>  
>  static void
>  skl_allocate_pipe_ddb(struct drm_crtc *crtc,
> -		      const struct intel_wm_config *config,
>  		      const struct intel_crtc_state *cstate,
>  		      struct skl_ddb_allocation *ddb /* out */)
>  {
>  	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_wm_config *config = &dev_priv->wm.config;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_plane *intel_plane;
>  	enum pipe pipe = intel_crtc->pipe;
> @@ -3157,15 +3131,6 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation 
> *new_ddb,
>  	return false;
>  }
>  
> -static void skl_compute_wm_global_parameters(struct drm_device *dev,
> -					     struct intel_wm_config *config)
> -{
> -	struct drm_crtc *crtc;
> -
> -	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> -		config->num_pipes_active += to_intel_crtc(crtc)->active;
> -}
> -
>  static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  				 struct intel_crtc *intel_crtc,
>  				 struct intel_plane *intel_plane,
> @@ -3571,13 +3536,12 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
>  }
>  
>  static bool skl_update_pipe_wm(struct drm_crtc *crtc,
> -			       struct intel_wm_config *config,
>  			       struct skl_ddb_allocation *ddb, /* out */
>  			       struct skl_pipe_wm *pipe_wm /* out */)
>  {
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
>  
> -	skl_allocate_pipe_ddb(crtc, config, cstate, ddb);
> +	skl_allocate_pipe_ddb(crtc, cstate, ddb);
>  	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
>  
>  	if (!memcmp(&cstate->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
> @@ -3590,7 +3554,6 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  
>  static void skl_update_other_pipe_wm(struct drm_device *dev,
>  				     struct drm_crtc *crtc,
> -				     struct intel_wm_config *config,
>  				     struct skl_wm_values *r)
>  {
>  	struct intel_crtc *intel_crtc;
> @@ -3620,7 +3583,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
>  		if (!intel_crtc->active)
>  			continue;
>  
> -		wm_changed = skl_update_pipe_wm(&intel_crtc->base, config,
> +		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
>  						&r->ddb, &pipe_wm);
>  
>  		/*
> @@ -3642,19 +3605,16 @@ static void skl_update_wm(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct skl_wm_values *results = &dev_priv->wm.skl_results;
>  	struct skl_pipe_wm pipe_wm = {};
> -	struct intel_wm_config config = {};
>  
>  	memset(results, 0, sizeof(*results));
>  
> -	skl_compute_wm_global_parameters(dev, &config);
> -
> -	if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
> +	if (!skl_update_pipe_wm(crtc, &results->ddb, &pipe_wm))
>  		return;
>  
>  	skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
>  	results->dirty[intel_crtc->pipe] = true;
>  
> -	skl_update_other_pipe_wm(dev, crtc, &config, results);
> +	skl_update_other_pipe_wm(dev, crtc, results);
>  	skl_write_wm_values(dev_priv, results);
>  	skl_flush_wm_values(dev_priv, results);
>  
> @@ -3667,20 +3627,18 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
>  	struct drm_device *dev = dev_priv->dev;
>  	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
>  	struct ilk_wm_maximums max;
> -	struct intel_wm_config config = {};
> +	struct intel_wm_config *config = &dev_priv->wm.config;
>  	struct ilk_wm_values results = {};
>  	enum intel_ddb_partitioning partitioning;
>  
> -	ilk_compute_wm_config(dev, &config);
> -
> -	ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max);
> -	ilk_wm_merge(dev, &config, &max, &lp_wm_1_2);
> +	ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_1_2, &max);
> +	ilk_wm_merge(dev, config, &max, &lp_wm_1_2);
>  
>  	/* 5/6 split only in single pipe config on IVB+ */
>  	if (INTEL_INFO(dev)->gen >= 7 &&
> -	    config.num_pipes_active == 1 && config.sprites_enabled) {
> -		ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max);
> -		ilk_wm_merge(dev, &config, &max, &lp_wm_5_6);
> +	    config->num_pipes_active == 1 && config->sprites_enabled) {
> +		ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_5_6, &max);
> +		ilk_wm_merge(dev, config, &max, &lp_wm_5_6);
>  
>  		best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6);
>  	} else {
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-08-26 15:51       ` Ville Syrjälä
@ 2015-08-28 23:57         ` Matt Roper
  2015-08-28 23:57           ` [RFC 2/3] drm/i915: Calculate an intermediate plane/crtc atomic state for modesets Matt Roper
                             ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-28 23:57 UTC (permalink / raw)
  To: intel-gfx

Way back at the beginning of i915's atomic conversion I added
intel_crtc->atomic as a temporary dumping ground for "stuff to do
outside vblank evasion" flags since CRTC states weren't properly wired
up and tracked at that time.  We've had proper CRTC state tracking for a
while now, so there's really no reason for this hack to continue to
exist.  Moving forward we want to store intermediate crtc/plane state
data for modesets in addition to the final state, so moving these fields
into the proper state object allows us to properly compute them for both
the intermediate and final state.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  | 16 ++++++-
 drivers/gpu/drm/i915/intel_display.c | 83 ++++++++++++++++++------------------
 drivers/gpu/drm/i915/intel_drv.h     | 41 +++++++-----------
 3 files changed, 73 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 9336e80..3ffc385 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -101,6 +101,20 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 
 	crtc_state->base.crtc = crtc;
 
+	crtc_state->wait_for_flips = false;
+	crtc_state->disable_fbc = false;
+	crtc_state->disable_ips = false;
+	crtc_state->disable_cxsr = false;
+	crtc_state->pre_disable_primary = false;
+	crtc_state->update_wm_pre = false;
+	crtc_state->update_wm_post = false;
+	crtc_state->disabled_planes = 0;
+	crtc_state->fb_bits = 0;
+	crtc_state->wait_vblank = false;
+	crtc_state->update_fbc = false;
+	crtc_state->post_enable_primary = false;
+	crtc_state->update_sprite_watermarks = 0;
+
 	return &crtc_state->base;
 }
 
@@ -212,7 +226,7 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 				 * minimum required validation.
 				 */
 				if (plane->type == DRM_PLANE_TYPE_PRIMARY)
-					intel_crtc->atomic.wait_for_flips = true;
+					crtc_state->wait_for_flips = true;
 				crtc_state->base.planes_changed = true;
 			}
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f604ce1..68b5f2a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4749,44 +4749,42 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 
 static void intel_post_plane_update(struct intel_crtc *crtc)
 {
-	struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->base.state);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_plane *plane;
 
-	if (atomic->wait_vblank)
+	if (cstate->wait_vblank)
 		intel_wait_for_vblank(dev, crtc->pipe);
 
-	intel_frontbuffer_flip(dev, atomic->fb_bits);
+	intel_frontbuffer_flip(dev, cstate->fb_bits);
 
-	if (atomic->disable_cxsr)
+	if (cstate->disable_cxsr)
 		crtc->wm.cxsr_allowed = true;
 
-	if (crtc->atomic.update_wm_post)
+	if (cstate->update_wm_post)
 		intel_update_watermarks(&crtc->base);
 
-	if (atomic->update_fbc)
+	if (cstate->update_fbc)
 		intel_fbc_update(dev_priv);
 
-	if (atomic->post_enable_primary)
+	if (cstate->post_enable_primary)
 		intel_post_enable_primary(&crtc->base);
 
-	drm_for_each_plane_mask(plane, dev, atomic->update_sprite_watermarks)
+	drm_for_each_plane_mask(plane, dev, cstate->update_sprite_watermarks)
 		intel_update_sprite_watermarks(plane, &crtc->base,
 					       0, 0, 0, false, false);
-
-	memset(atomic, 0, sizeof(*atomic));
 }
 
 static void intel_pre_plane_update(struct intel_crtc *crtc)
 {
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->base.state);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
 	struct drm_plane *p;
 
 	/* Track fb's for any planes being disabled */
-	drm_for_each_plane_mask(p, dev, atomic->disabled_planes) {
+	drm_for_each_plane_mask(p, dev, cstate->disabled_planes) {
 		struct intel_plane *plane = to_intel_plane(p);
 
 		mutex_lock(&dev->struct_mutex);
@@ -4795,19 +4793,19 @@ static void intel_pre_plane_update(struct intel_crtc *crtc)
 		mutex_unlock(&dev->struct_mutex);
 	}
 
-	if (atomic->wait_for_flips)
+	if (cstate->wait_for_flips)
 		intel_crtc_wait_for_pending_flips(&crtc->base);
 
-	if (atomic->disable_fbc)
+	if (cstate->disable_fbc)
 		intel_fbc_disable_crtc(crtc);
 
-	if (crtc->atomic.disable_ips)
+	if (cstate->disable_ips)
 		hsw_disable_ips(crtc);
 
-	if (atomic->pre_disable_primary)
+	if (cstate->pre_disable_primary)
 		intel_pre_disable_primary(&crtc->base);
 
-	if (atomic->disable_cxsr) {
+	if (cstate->disable_cxsr) {
 		crtc->wm.cxsr_allowed = false;
 		intel_set_memory_cxsr(dev_priv, false);
 	}
@@ -11553,6 +11551,8 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 {
 	struct drm_crtc *crtc = crtc_state->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *intel_crtc_state =
+		to_intel_crtc_state(crtc_state);
 	struct drm_plane *plane = plane_state->plane;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -11567,10 +11567,10 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 	bool turn_off, turn_on, visible, was_visible;
 	struct drm_framebuffer *fb = plane_state->fb;
 
-	if (crtc_state && INTEL_INFO(dev)->gen >= 9 &&
+	if (INTEL_INFO(dev)->gen >= 9 &&
 	    plane->type != DRM_PLANE_TYPE_CURSOR) {
 		ret = skl_update_scaler_plane(
-			to_intel_crtc_state(crtc_state),
+			intel_crtc_state,
 			to_intel_plane_state(plane_state));
 		if (ret)
 			return ret;
@@ -11582,7 +11582,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 	 * get called by the plane helpers.
 	 */
 	if (old_plane_state->base.fb && !fb)
-		intel_crtc->atomic.disabled_planes |= 1 << i;
+		intel_crtc_state->disabled_planes |= 1 << i;
 
 	was_visible = old_plane_state->visible;
 	visible = to_intel_plane_state(plane_state)->visible;
@@ -11607,35 +11607,35 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 			 turn_off, turn_on, mode_changed);
 
 	if (turn_on) {
-		intel_crtc->atomic.update_wm_pre = true;
+		intel_crtc_state->update_wm_pre = true;
 		/* must disable cxsr around plane enable/disable */
 		if (plane->type != DRM_PLANE_TYPE_CURSOR) {
-			intel_crtc->atomic.disable_cxsr = true;
+			intel_crtc_state->disable_cxsr = true;
 			/* to potentially re-enable cxsr */
-			intel_crtc->atomic.wait_vblank = true;
-			intel_crtc->atomic.update_wm_post = true;
+			intel_crtc_state->wait_vblank = true;
+			intel_crtc_state->update_wm_post = true;
 		}
 	} else if (turn_off) {
-		intel_crtc->atomic.update_wm_post = true;
+		intel_crtc_state->update_wm_post = true;
 		/* must disable cxsr around plane enable/disable */
 		if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 			if (is_crtc_enabled)
-				intel_crtc->atomic.wait_vblank = true;
-			intel_crtc->atomic.disable_cxsr = true;
+				intel_crtc_state->wait_vblank = true;
+			intel_crtc_state->disable_cxsr = true;
 		}
 	} else if (intel_wm_need_update(plane, plane_state)) {
-		intel_crtc->atomic.update_wm_pre = true;
+		intel_crtc_state->update_wm_pre = true;
 	}
 
 	if (visible)
-		intel_crtc->atomic.fb_bits |=
+		intel_crtc_state->fb_bits |=
 			to_intel_plane(plane)->frontbuffer_bit;
 
 	switch (plane->type) {
 	case DRM_PLANE_TYPE_PRIMARY:
-		intel_crtc->atomic.wait_for_flips = true;
-		intel_crtc->atomic.pre_disable_primary = turn_off;
-		intel_crtc->atomic.post_enable_primary = turn_on;
+		intel_crtc_state->wait_for_flips = true;
+		intel_crtc_state->pre_disable_primary = turn_off;
+		intel_crtc_state->post_enable_primary = turn_on;
 
 		if (turn_off) {
 			/*
@@ -11646,9 +11646,9 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 			 * update_primary_plane function IPS needs to be
 			 * disable.
 			 */
-			intel_crtc->atomic.disable_ips = true;
+			intel_crtc_state->disable_ips = true;
 
-			intel_crtc->atomic.disable_fbc = true;
+			intel_crtc_state->disable_fbc = true;
 		}
 
 		/*
@@ -11666,7 +11666,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 		    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
 		    dev_priv->fbc.crtc == intel_crtc &&
 		    plane_state->rotation != BIT(DRM_ROTATE_0))
-			intel_crtc->atomic.disable_fbc = true;
+			intel_crtc_state->disable_fbc = true;
 
 		/*
 		 * BDW signals flip done immediately if the plane
@@ -11674,16 +11674,16 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 		 * armed to occur at the next vblank :(
 		 */
 		if (turn_on && IS_BROADWELL(dev))
-			intel_crtc->atomic.wait_vblank = true;
+			intel_crtc_state->wait_vblank = true;
 
-		intel_crtc->atomic.update_fbc |= visible || mode_changed;
+		intel_crtc_state->update_fbc |= visible || mode_changed;
 		break;
 	case DRM_PLANE_TYPE_CURSOR:
 		break;
 	case DRM_PLANE_TYPE_OVERLAY:
 		if (turn_off && !mode_changed) {
-			intel_crtc->atomic.wait_vblank = true;
-			intel_crtc->atomic.update_sprite_watermarks |=
+			intel_crtc_state->wait_vblank = true;
+			intel_crtc_state->update_sprite_watermarks |=
 				1 << i;
 		}
 	}
@@ -11758,7 +11758,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	if (mode_changed && !crtc_state->active)
-		intel_crtc->atomic.update_wm_post = true;
+		pipe_config->update_wm_post = true;
 
 	if (mode_changed && crtc_state->enable &&
 	    dev_priv->display.crtc_compute_clock &&
@@ -13473,8 +13473,9 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
-	if (intel_crtc->atomic.update_wm_pre)
+	if (cstate->update_wm_pre)
 		intel_update_watermarks(crtc);
 
 	/* Perform vblank evasion around commit operation */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 81b7d77..fd09087 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -455,6 +455,22 @@ struct intel_crtc_state {
 
 	/* w/a for waiting 2 vblanks during crtc enable */
 	enum pipe hsw_workaround_pipe;
+
+	/* Sleepable operations to perform before commit */
+	bool wait_for_flips;
+	bool disable_fbc;
+	bool disable_ips;
+	bool disable_cxsr;
+	bool pre_disable_primary;
+	bool update_wm_pre, update_wm_post;
+	unsigned disabled_planes;
+
+	/* Sleepable operations to perform after commit */
+	unsigned fb_bits;
+	bool wait_vblank;
+	bool update_fbc;
+	bool post_enable_primary;
+	unsigned update_sprite_watermarks;
 };
 
 struct vlv_wm_state {
@@ -488,30 +504,6 @@ struct skl_pipe_wm {
 	uint32_t linetime;
 };
 
-/*
- * Tracking of operations that need to be performed at the beginning/end of an
- * atomic commit, outside the atomic section where interrupts are disabled.
- * These are generally operations that grab mutexes or might otherwise sleep
- * and thus can't be run with interrupts disabled.
- */
-struct intel_crtc_atomic_commit {
-	/* Sleepable operations to perform before commit */
-	bool wait_for_flips;
-	bool disable_fbc;
-	bool disable_ips;
-	bool disable_cxsr;
-	bool pre_disable_primary;
-	bool update_wm_pre, update_wm_post;
-	unsigned disabled_planes;
-
-	/* Sleepable operations to perform after commit */
-	unsigned fb_bits;
-	bool wait_vblank;
-	bool update_fbc;
-	bool post_enable_primary;
-	unsigned update_sprite_watermarks;
-};
-
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -563,7 +555,6 @@ struct intel_crtc {
 	int scanline_offset;
 
 	unsigned start_vbl_count;
-	struct intel_crtc_atomic_commit atomic;
 
 	/* scalers available on this crtc */
 	int num_scalers;
-- 
2.1.4

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

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

* [RFC 2/3] drm/i915: Calculate an intermediate plane/crtc atomic state for modesets
  2015-08-28 23:57         ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Matt Roper
@ 2015-08-28 23:57           ` Matt Roper
  2015-08-28 23:57           ` [RFC 3/3] drm/i915: Update modeset programming to use intermediate state Matt Roper
  2015-09-01  5:24           ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Maarten Lankhorst
  2 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-28 23:57 UTC (permalink / raw)
  To: intel-gfx

To simplify the modeset process for atomic, start calculating an
"intermediate" state for any CRTC's which undergo a modeset (or get
permanently disabled).  This state represents the status of the CRTC and
planes at the point in which the CRTC's have been disabled; i.e.,
intermediate_state->active = false, even if the CRTC will be running
again once the modeset is complete.  This will allow us to calculate
proper derived state fields for this point in the modeset process which
should in turn should help us properly perform tasks like watermark
calculation.

For review simplicity, this patch simply allocates and calculates the
intermediate state objects, but doesn't actually do anything with them.
The next patch will start actually using this intermediate state data.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  | 152 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |   3 +-
 drivers/gpu/drm/i915/intel_drv.h     |  13 +++
 3 files changed, 167 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3ffc385..26a5c2a 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -320,12 +320,164 @@ intel_atomic_state_alloc(struct drm_device *dev)
 		return NULL;
 	}
 
+	state->int_plane_states = kcalloc(dev->mode_config.num_total_plane,
+					  sizeof(*state->int_plane_states),
+					  GFP_KERNEL);
+	state->int_crtc_states = kcalloc(dev->mode_config.num_crtc,
+					  sizeof(*state->int_crtc_states),
+					  GFP_KERNEL);
+	if (!state->int_plane_states || !state->int_crtc_states)
+		goto fail;
+
 	return &state->base;
+
+fail:
+	kfree(state->int_plane_states);
+	kfree(state->int_crtc_states);
+	drm_atomic_state_default_release(&state->base);
+	return NULL;
+}
+
+void
+intel_atomic_state_free(struct drm_atomic_state *s)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(s);
+
+	if (WARN_ON(!s))
+		return;
+
+	kfree(state->int_plane_states);
+	kfree(state->int_crtc_states);
+	drm_atomic_state_default_release(s);
 }
 
 void intel_atomic_state_clear(struct drm_atomic_state *s)
 {
 	struct intel_atomic_state *state = to_intel_atomic_state(s);
+	struct drm_mode_config *config = &s->dev->mode_config;
+	int i;
+
+	for (i = 0; i < config->num_crtc; i++) {
+		struct drm_crtc_state *cstate = state->int_crtc_states[i];
+		struct drm_crtc *crtc = s->crtcs[i];
+
+		if (!cstate)
+			continue;
+
+		crtc->funcs->atomic_destroy_state(crtc, cstate);
+		state->int_crtc_states[i] = NULL;
+	}
+
+	for (i = 0; i < config->num_total_plane; i++) {
+		struct drm_plane_state *pstate = state->int_plane_states[i];
+		struct drm_plane *plane = s->planes[i];
+
+		if (!pstate)
+			continue;
+
+		plane->funcs->atomic_destroy_state(plane, pstate);
+		state->int_plane_states[i] = NULL;
+	}
+
 	drm_atomic_state_default_clear(&state->base);
 	state->dpll_set = false;
 }
+
+/**
+ * intel_atomic_check_planes - validate state object for planes changes
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * An Intel-specific replacement for drm_atomic_helper_check_planes().  In
+ * addition to calling the ->atomic_check() entrypoints for all plane/crtc
+ * states present in the atomic transaction, it also creates an additional set
+ * of plane/crtc state objects that correspond to the 'intermediate' states for
+ * any planes/crtc's that undergo a modeset or disable as part of this
+ * transaction.  These states will differ from the main states in that they
+ * show the CRTC as disabled, so all derived state shall be calculated
+ * accordingly.
+ */
+int
+intel_atomic_check_planes(struct drm_device *dev,
+			  struct drm_atomic_state *state)
+{
+	struct intel_atomic_state *istate = to_intel_atomic_state(state);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *cstate;
+	struct drm_plane *plane;
+	struct drm_plane_state *pstate;
+	struct drm_crtc_state **tmp_cstates;
+	struct drm_plane_state **tmp_pstates;
+	unsigned needs_ms = 0;
+	int i, ret;
+
+	/*
+	 * Start by checking calculating/checking the final state as usual;
+	 * if that doesn't work, then there's no point in worrying about
+	 * intermediate states.
+	 */
+	ret = drm_atomic_helper_check_planes(dev, state);
+	if (ret)
+		return ret;
+
+	/*
+	 * End state looks okay.  Create intermediate states for any CRTC's
+	 * that undergo a modeset/disable; the intermediate state corresponds
+	 * to the 'disable' part of the modeset, before anything gets turned
+	 * back on.
+	 */
+	for_each_crtc_in_state(state, crtc, cstate, i) {
+		if (!drm_atomic_crtc_needs_modeset(cstate))
+			continue;
+
+		needs_ms |= drm_crtc_mask(crtc);
+
+		istate->int_crtc_states[i] = intel_crtc_duplicate_state(crtc);
+		if (!istate->int_crtc_states[i])
+			return -ENOMEM;
+
+		istate->int_crtc_states[i]->state = state;
+
+		/*
+		 * For CRTC's undergoing a modeset (i.e., ultimately to be
+		 * re-enabled), this is the key difference from the final state
+		 * and will affect how the derived parts of the state object
+		 * are calculated.
+		 */
+		istate->int_crtc_states[i]->active = false;
+	}
+
+	if (!needs_ms)
+		return 0;
+
+	/*
+	 * We also need intermediate states for any planes that will be active
+	 * on a CRTC in the list above since their derived state will also
+	 * differ at the intermediate point.
+	 */
+	for_each_plane_in_state(state, plane, pstate, i) {
+		if (!pstate->crtc || !(needs_ms & drm_crtc_mask(pstate->crtc)))
+			continue;
+
+		istate->int_plane_states[i] = intel_plane_duplicate_state(plane);
+		if (!istate->int_plane_states[i])
+			return -ENOMEM;
+
+		istate->int_plane_states[i]->state = state;
+	}
+
+	/*
+	 * Temporarily swap our plane/crtc state arrays into the base state
+	 * object and call the helper again to calculate the derived state
+	 * (and check the intermediate state for validity).
+	 */
+	tmp_cstates = state->crtc_states;
+	tmp_pstates = state->plane_states;
+	state->crtc_states = istate->int_crtc_states;
+	state->plane_states = istate->int_plane_states;
+	ret = drm_atomic_helper_check_planes(dev, state);
+	state->crtc_states = tmp_cstates;
+	state->plane_states = tmp_pstates;
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 68b5f2a..76f3727 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13052,7 +13052,7 @@ static int intel_atomic_check(struct drm_device *dev,
 		to_intel_atomic_state(state)->cdclk =
 			to_i915(state->dev)->cdclk_freq;
 
-	return drm_atomic_helper_check_planes(state->dev, state);
+	return intel_atomic_check_planes(state->dev, state);
 }
 
 /**
@@ -14332,6 +14332,7 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
 	.atomic_check = intel_atomic_check,
 	.atomic_commit = intel_atomic_commit,
 	.atomic_state_alloc = intel_atomic_state_alloc,
+	.atomic_state_free = intel_atomic_state_free,
 	.atomic_state_clear = intel_atomic_state_clear,
 };
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fd09087..0113c20 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -239,6 +239,16 @@ struct intel_atomic_state {
 	unsigned int cdclk;
 	bool dpll_set;
 	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+
+	/*
+	 * Intermediate state arrays; the states here should be identical
+	 * to the base object's states for CRTC's that are not involved in a
+	 * modeset/disable.  CRTC's that do require a modeset/disable will
+	 * appear as disabled here (and the relevant derived state should
+	 * be updated accordingly).
+	 */
+	struct drm_plane_state **int_plane_states;
+	struct drm_crtc_state **int_crtc_states;
 };
 
 struct intel_plane_state {
@@ -1396,6 +1406,7 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
 void intel_crtc_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state);
 struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
+void intel_atomic_state_free(struct drm_atomic_state *s);
 void intel_atomic_state_clear(struct drm_atomic_state *);
 struct intel_shared_dpll_config *
 intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s);
@@ -1414,6 +1425,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 int intel_atomic_setup_scalers(struct drm_device *dev,
 	struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state);
+int intel_atomic_check_planes(struct drm_device *dev,
+			      struct drm_atomic_state *state);
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-- 
2.1.4

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

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

* [RFC 3/3] drm/i915: Update modeset programming to use intermediate state
  2015-08-28 23:57         ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Matt Roper
  2015-08-28 23:57           ` [RFC 2/3] drm/i915: Calculate an intermediate plane/crtc atomic state for modesets Matt Roper
@ 2015-08-28 23:57           ` Matt Roper
  2015-09-01  5:24           ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Maarten Lankhorst
  2 siblings, 0 replies; 42+ messages in thread
From: Matt Roper @ 2015-08-28 23:57 UTC (permalink / raw)
  To: intel-gfx

As suggested by Ville, the general flow should now roughly follow:

        // whatever the user wanted
        compute_final_atomic_state()

        // include all crtcs in the intermediate state which are
        // getting disabled (even temporarily to perform a modeset)
        compute_intermediate_atomic_state()

        ret = check_state_change(old, intermediate)
        ret = check_state_change(intermediate, new)

        // commit all planes in one go to make them pop out as
        // atomically as possible
        for_each_crtc_in(intermediate) {
                commit_planes()
        }

        for_each_crtc_in(intermediate) {
                disable_crtc()
        }

        for_each_crtc_in(new) {
                if (!currently_active)
                        crtc_enable()
        }

        // commit all planes in one go to make them pop in as atomically
        // as possible
        for_each_crtc_in(new) {
                commit_planes()
        }

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
Ville, is this what you had in mind for the intermediate states for modeset?  I
think there might still be a bug or two here that I need to track down, but
figured I should post this now to make sure this matches what you were asking for.

 drivers/gpu/drm/i915/intel_display.c | 63 +++++++++++++++++++++++++-----------
 1 file changed, 44 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 76f3727..cbc2c69 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4747,10 +4747,11 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 	hsw_disable_ips(intel_crtc);
 }
 
-static void intel_post_plane_update(struct intel_crtc *crtc)
+static void intel_post_plane_update(struct drm_crtc_state *s)
 {
-	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->base.state);
-	struct drm_device *dev = crtc->base.dev;
+	struct intel_crtc_state *cstate = to_intel_crtc_state(s);
+	struct intel_crtc *crtc = to_intel_crtc(s->crtc);
+	struct drm_device *dev = s->crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_plane *plane;
 
@@ -4776,10 +4777,11 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
 					       0, 0, 0, false, false);
 }
 
-static void intel_pre_plane_update(struct intel_crtc *crtc)
+static void intel_pre_plane_update(struct drm_crtc_state *s)
 {
-	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->base.state);
-	struct drm_device *dev = crtc->base.dev;
+	struct intel_crtc_state *cstate = to_intel_crtc_state(s);
+	struct intel_crtc *crtc = to_intel_crtc(s->crtc);
+	struct drm_device *dev = s->crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_plane *p;
 
@@ -13076,8 +13078,9 @@ static int intel_atomic_commit(struct drm_device *dev,
 			       bool async)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_atomic_state *istate = to_intel_atomic_state(state);
 	struct drm_crtc *crtc;
-	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_state *old_crtc_state;
 	int ret = 0;
 	int i;
 	bool any_ms = false;
@@ -13091,19 +13094,36 @@ static int intel_atomic_commit(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	/*
+	 * Commit final state to the underlying crtc/plane objects; the final
+	 * state should now be accessed via crtc->state, plane->state, etc.
+	 * However the intermediate state continues to reside in the top-level
+	 * state structure (istate->int_{crtc,plane}_states[]).
+	 */
 	drm_atomic_helper_swap_state(dev, state);
 
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	/*
+	 * Commit all planes in one go to make them pop out as atomically
+	 * as possible.
+	 */
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		struct drm_crtc_state *int_cstate;
 
 		if (!needs_modeset(crtc->state))
 			continue;
+		if (WARN_ON(!(int_cstate = istate->int_crtc_states[i])))
+			continue;
 
 		any_ms = true;
-		intel_pre_plane_update(intel_crtc);
+		intel_pre_plane_update(int_cstate);
+		drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
+		intel_post_plane_update(int_cstate);
+	}
 
-		if (crtc_state->active) {
-			intel_crtc_disable_planes(crtc, crtc_state->plane_mask);
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		if (needs_modeset(crtc->state) && old_crtc_state->active) {
 			dev_priv->display.crtc_disable(crtc);
 			intel_crtc->active = false;
 			intel_disable_shared_dpll(intel_crtc);
@@ -13121,21 +13141,26 @@ static int intel_atomic_commit(struct drm_device *dev,
 		modeset_update_crtc_power_domains(state);
 	}
 
-	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	/* Now enable the clocks, pipe, and connectors that we set up. */
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
 		bool modeset = needs_modeset(crtc->state);
 
 		if (modeset && crtc->state->active) {
 			update_scanline_offset(to_intel_crtc(crtc));
 			dev_priv->display.crtc_enable(crtc);
 		}
+	}
 
-		if (!modeset)
-			intel_pre_plane_update(intel_crtc);
+	/*
+	 * Commit all planes in one go to make them pop in as atomically as
+	 * possible.
+	 */
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		old_crtc_state = istate->int_crtc_states[i] ?: old_crtc_state;
 
-		drm_atomic_helper_commit_planes_on_crtc(crtc_state);
-		intel_post_plane_update(intel_crtc);
+		intel_pre_plane_update(crtc->state);
+		drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
+		intel_post_plane_update(crtc->state);
 	}
 
 	/* FIXME: add subpixel order */
-- 
2.1.4

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

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

* Re: [PATCH 11/13] drm/i915: Add two-stage ILK-style watermark programming (v3)
  2015-08-21  1:12 ` [PATCH 11/13] drm/i915: Add two-stage ILK-style watermark programming (v3) Matt Roper
@ 2015-08-31 14:36   ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 42+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-08-31 14:36 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

On Thu, 2015-08-20 at 18:12 -0700, Matt Roper wrote:
> In addition to calculating final watermarks, let's also pre-calculate a
> set of intermediate watermark values at atomic check time.  These
> intermediate watermarks are a combination of the watermarks for the old
> state and the new state; they should satisfy the requirements of both
> states which means they can be programmed immediately when we commit the
> atomic state (without waiting for a vblank).  Once the vblank does
> happen, we can then re-program watermarks to the more optimal final
> value.
> 
> v2: Significant rebasing/rewriting.
> 
> v3:
>  - Move 'need_postvbl_update' flag to CRTC state (Daniel)
>  - Don't forget to check intermediate watermark values for validity
>    (Maarten)
>  - Don't due async watermark optimization; just do it at the end of the
>    atomic transaction, after waiting for vblanks.  We do want it to be
>    async eventually, but adding that now will cause more trouble for
>    Maarten's in-progress work.  (Maarten)
>  - Don't allocate space in crtc_state for intermediate watermarks on
>    platforms that don't need it (gen9+).
>  - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
>    now that ilk_update_wm is gone.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   5 ++
>  drivers/gpu/drm/i915/intel_display.c |  77 ++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_drv.h     |  33 ++++++--
>  drivers/gpu/drm/i915/intel_pm.c      | 144 ++++++++++++++++++++++++-----------
>  4 files changed, 208 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index ac13cd7..be42dd8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -622,6 +622,11 @@ struct drm_i915_display_funcs {
>  			  struct dpll *best_clock);
>  	int (*compute_pipe_wm)(struct drm_crtc *crtc,
>  			       struct drm_atomic_state *state);
> +	int (*compute_intermediate_wm)(struct drm_device *dev,
> +				       struct intel_crtc_state *newstate,
> +				       const struct intel_crtc_state *oldstate);
> +	void (*program_watermarks)(struct drm_i915_private *dev_priv);
> +	void (*optimize_watermarks)(struct intel_crtc_state *cstate);
>  	void (*update_wm)(struct drm_crtc *crtc);
>  	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
>  	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8e9d87a..f929676 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11634,6 +11634,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
>  		}
>  	} else if (intel_wm_need_update(plane, plane_state)) {
>  		intel_crtc->atomic.update_wm_pre = true;
> +
> +		/* Pre-gen9 platforms need two-step watermark updates */
> +		if (INTEL_INFO(dev)->gen < 9 &&
> +		    dev_priv->display.program_watermarks)
> +			cstate->wm.need_postvbl_update = true;
>  	}
>  
>  	if (visible)
> @@ -11769,6 +11774,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *pipe_config =
>  		to_intel_crtc_state(crtc_state);
> +	struct intel_crtc_state *old_pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	struct drm_atomic_state *state = crtc_state->state;
>  	int ret;
>  	bool mode_changed = needs_modeset(crtc_state);
> @@ -11793,8 +11800,28 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  	ret = 0;
>  	if (dev_priv->display.compute_pipe_wm) {
>  		ret = dev_priv->display.compute_pipe_wm(crtc, state);
> -		if (ret)
> +		if (ret) {
> +			DRM_DEBUG_KMS("Target pipe watermarks are invalid\n");
> +			return ret;
> +		}
> +	}
> +
> +	if (dev_priv->display.compute_intermediate_wm) {
> +		if (WARN_ON(!dev_priv->display.compute_pipe_wm))
> +			return 0;
> +
> +		/*
> +		 * Calculate 'intermediate' watermarks that satisfy both the
> +		 * old state and the new state.  We can program these
> +		 * immediately.
> +		 */
> +		ret = dev_priv->display.compute_intermediate_wm(crtc->dev,
> +								pipe_config,
> +								old_pipe_config);
> +		if (ret) {
> +			DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n");
>  			return ret;
> +		}
>  	}
>  
>  	if (INTEL_INFO(dev)->gen >= 9) {
> @@ -13149,6 +13176,7 @@ static int intel_atomic_commit(struct drm_device *dev,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *crtc_state;
> +	struct intel_crtc_state *intel_cstate;
>  	int ret = 0;
>  	int i;
>  	bool any_ms = false;
> @@ -13213,6 +13241,21 @@ static int intel_atomic_commit(struct drm_device *dev,
>  	/* FIXME: add subpixel order */
>  
>  	drm_atomic_helper_wait_for_vblanks(dev, state);
> +
> +	/*
> +	 * Now that the vblank has passed, we can go ahead and program the
> +	 * optimal watermarks on platforms that need two-step watermark
> +	 * programming.
> +	 *
> +	 * TODO: Move this (and other cleanup) to an async worker eventually.
> +	 */
> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		intel_cstate = to_intel_crtc_state(crtc->state);
> +
> +		if (intel_cstate->wm.need_postvbl_update)
> +			dev_priv->display.optimize_watermarks(intel_cstate);
> +	}
> +
>  	drm_atomic_helper_cleanup_planes(dev, state);
>  
>  	if (any_ms)
> @@ -13544,10 +13587,40 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
>  				    struct drm_crtc_state *old_crtc_state)
>  {
>  	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
> -	if (intel_crtc->atomic.update_wm_pre)
> +	/*
> +	 * IVB workaround: must disable low power watermarks for at least
> +	 * one frame before enabling scaling.  LP watermarks can be re-enabled
> +	 * when scaling is disabled.
> +	 *
> +	 * WaCxSRDisabledForSpriteScaling:ivb
> +	 */
> +	if (to_intel_crtc_state(crtc->state)->disable_lp_wm) {
> +		ilk_disable_lp_wm(crtc->dev);
> +		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
> +	}
> +
> +	/*
> +	 * For platforms that support atomic watermarks, program the 'active'
> +	 * watermarks immediately.  On pre-gen9 platforms, these will be the
> +	 * intermediate values that are safe for both pre- and post- vblank;
> +	 * when vblank happens, the 'active' values will be set to the final
> +	 * 'target' values and we'll do this again to get the optimal
> +	 * watermarks.  For gen9+ platforms, the values we program here will be
> +	 * the final target values which will get automatically latched at
> +	 * vblank time; no further programming will be necessary.
> +	 *
> +	 * If a platform hasn't been transitioned to atomic watermarks yet,
> +	 * we'll continue to update watermarks the old way, if flags tell
> +	 * us to.
> +	 */
> +	if (dev_priv->display.program_watermarks != NULL) {
> +		dev_priv->display.program_watermarks(dev_priv);
> +	} else if (intel_crtc->atomic.update_wm_pre) {
>  		intel_update_watermarks(crtc);
> +	}
>  
>  	/* Perform vblank evasion around commit operation */
>  	if (crtc->state->active)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 6ac1010c..6a73a53 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -476,14 +476,34 @@ struct intel_crtc_state {
>  	bool disable_lp_wm;
>  
>  	struct {
> -		/*
> -		 * final watermarks, programmed post-vblank when this state
> -		 * is committed
> -		 */
>  		union {
> -			struct intel_pipe_wm ilk;
> +			struct {
> +				/*
> +				 * Final, target watermarks for state; this
> +				 * might not have been programmed yet if a
> +				 * vblank hasn't happened since this state
> +				 * was committed.
> +				 */
> +				struct intel_pipe_wm target;
> +
> +				/*
> +				 * currently programmed watermark; this will be
> +				 * the intermediate values before vblank then
> +				 * switch to match 'target' after vblank fires
> +				 */
> +				struct intel_pipe_wm active;
> +			} ilk;
> +
>  			struct skl_pipe_wm skl;
> -		} active;
> +		};
> +
> +		/*
> +		 * Platforms with two-step watermark programming will need to
> +		 * update watermark programming post-vblank to switch from the
> +		 * safe intermediate watermarks to the optimal final
> +		 * watermarks.
> +		 */
> +		bool need_postvbl_update;
>  	} wm;
>  };
>  
> @@ -1385,6 +1405,7 @@ void skl_wm_get_hw_state(struct drm_device *dev);
>  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
>  			  struct skl_ddb_allocation *ddb /* out */);
>  uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
> +bool ilk_disable_lp_wm(struct drm_device *dev);
>  
>  /* intel_sdvo.c */
>  bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index b32d6b0..e0a4c4d 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2315,6 +2315,29 @@ static void skl_setup_wm_latency(struct drm_device *dev)
>  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
>  }
>  
> +static bool ilk_validate_pipe_wm(struct drm_device *dev,
> +				 struct intel_pipe_wm *pipe_wm)
> +{
> +	/* LP0 watermark maximums depend on this pipe alone */
> +	const struct intel_wm_config config = {
> +		.num_pipes_active = 1,
> +		.sprites_enabled = pipe_wm->sprites_enabled,
> +		.sprites_scaled = pipe_wm->sprites_scaled,
> +	};
> +	struct ilk_wm_maximums max;
> +
> +	/* LP0 watermarks always use 1/2 DDB partitioning */
> +	ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
> +
> +	/* At least LP0 must be valid */
> +	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) {
> +		DRM_DEBUG_KMS("LP0 watermark invalid\n");
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  /* Compute new watermarks for the pipe */
>  static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  			       struct drm_atomic_state *state)
> @@ -2331,10 +2354,6 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  	struct intel_plane_state *sprstate = NULL;
>  	struct intel_plane_state *curstate = NULL;
>  	int level, max_level = ilk_wm_max_level(dev);
> -	/* LP0 watermark maximums depend on this pipe alone */
> -	struct intel_wm_config config = {
> -		.num_pipes_active = 1,
> -	};
>  	struct ilk_wm_maximums max;
>  
>  	cs = drm_atomic_get_crtc_state(state, crtc);
> @@ -2343,7 +2362,7 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  	else
>  		cstate = to_intel_crtc_state(cs);
>  
> -	pipe_wm = &cstate->wm.active.ilk;
> +	pipe_wm = &cstate->wm.ilk.target;
>  
>  	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
>  		ps = drm_atomic_get_plane_state(state,
> @@ -2359,21 +2378,18 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  			curstate = to_intel_plane_state(ps);
>  	}
>  
> -	config.sprites_enabled = sprstate->visible;
> -	config.sprites_scaled =
> +	pipe_wm->pipe_enabled = cstate->base.active;
> +	pipe_wm->sprites_enabled = sprstate->visible;
> +	pipe_wm->sprites_scaled =
>  		drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
>  		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16;
>  
> -	pipe_wm->pipe_enabled = cstate->base.active;
> -	pipe_wm->sprites_enabled = config.sprites_enabled;
> -	pipe_wm->sprites_scaled = config.sprites_scaled;
> -
>  	/* ILK/SNB: LP2+ watermarks only w/o sprites */
>  	if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
>  		max_level = 1;
>  
>  	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
> -	if (config.sprites_scaled)
> +	if (pipe_wm->sprites_scaled)
>  		max_level = 0;
>  
>  	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
> @@ -2382,12 +2398,8 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
>  
> -	/* LP0 watermarks always use 1/2 DDB partitioning */
> -	ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
> -
> -	/* At least LP0 must be valid */
> -	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
> -		return -EINVAL;
> +	if (!ilk_validate_pipe_wm(dev, pipe_wm))
> +		return false;
>  
>  	ilk_compute_wm_reg_maximums(dev, 1, &max);
>  
> @@ -2412,6 +2424,60 @@ static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
>  }
>  
>  /*
> + * Build a set of 'intermediate' watermark values that satisfy both the old
> + * state and the new state.  These can be programmed to the hardware
> + * immediately.
> + */
> +static int ilk_compute_intermediate_wm(struct drm_device *dev,
> +				       struct intel_crtc_state *newstate,
> +				       const struct intel_crtc_state *oldstate)
> +{
> +	struct intel_pipe_wm *a = &newstate->wm.ilk.active;

Shouldn't this be ilk.target?

Also, I get a black screen with this patch on my HSW laptop. On boot, the level 0 wm has spr_val set
to 56, but the the hw state readout code doesn't set sprites_enabled properly. When the merged
active and target watermarks are checked for validity, the max value allowed for spr_val is 0
because sprites_enabled is 0, and that causes every modeset to fail.

Ander

> +	const struct intel_pipe_wm *b = &oldstate->wm.ilk.active;
> +	int level, max_level = ilk_wm_max_level(dev);
> +
> +	/*
> +	 * Start with the final, target watermarks, then combine with the
> +	 * current state's watermarks to get values that are safe both
> +	 * before and after the vblank.
> +	 */
> +	*a = newstate->wm.ilk.target;
> +	a->pipe_enabled |= b->pipe_enabled;
> +	a->sprites_enabled |= b->sprites_enabled;
> +	a->sprites_scaled |= b->sprites_scaled;
> +
> +	for (level = 0; level <= max_level; level++) {
> +		struct intel_wm_level *a_wm = &a->wm[level];
> +		const struct intel_wm_level *b_wm = &b->wm[level];
> +
> +		a_wm->enable &= b_wm->enable;
> +		a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val);
> +		a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val);
> +		a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val);
> +		a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val);
> +	}
> +
> +	/*
> +	 * We need to make sure that these merged watermark values are
> +	 * actually a valid configuration themselves.  If they're not,
> +	 * there's no safe way to transition from the old state to
> +	 * the new state, so we need to fail the atomic transaction.
> +	 */
> +	if (!ilk_validate_pipe_wm(dev, a))
> +		return -EINVAL;
> +
> +	/*
> +	 * If our intermediate WM are identical to the final WM, then we can
> +	 * omit the post-vblank programming.
> +	 */
> +	if (!memcmp(&newstate->wm.ilk.active, &newstate->wm.ilk.target,
> +		    sizeof *a))
> +		newstate->wm.need_postvbl_update = false;
> +
> +	return 0;
> +}
> +
> +/*
>   * Merge the watermarks from all active pipes for a specific level.
>   */
>  static void ilk_merge_wm_level(struct drm_device *dev,
> @@ -2425,7 +2491,7 @@ static void ilk_merge_wm_level(struct drm_device *dev,
>  	for_each_intel_crtc(dev, intel_crtc) {
>  		const struct intel_crtc_state *cstate =
>  			to_intel_crtc_state(intel_crtc->base.state);
> -		const struct intel_pipe_wm *active = &cstate->wm.active.ilk;
> +		const struct intel_pipe_wm *active = &cstate->wm.ilk.active;
>  		const struct intel_wm_level *wm = &active->wm[level];
>  
>  		if (!active->pipe_enabled)
> @@ -2576,12 +2642,12 @@ static void ilk_compute_wm_results(struct drm_device *dev,
>  		const struct intel_crtc_state *cstate =
>  			to_intel_crtc_state(intel_crtc->base.state);
>  		enum pipe pipe = intel_crtc->pipe;
> -		const struct intel_wm_level *r = &cstate->wm.active.ilk.wm[0];
> +		const struct intel_wm_level *r = &cstate->wm.ilk.active.wm[0];
>  
>  		if (WARN_ON(!r->enable))
>  			continue;
>  
> -		results->wm_linetime[pipe] = cstate->wm.active.ilk.linetime;
> +		results->wm_linetime[pipe] = cstate->wm.ilk.active.linetime;
>  
>  		results->wm_pipe[pipe] =
>  			(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
> @@ -2788,7 +2854,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
>  	dev_priv->wm.hw = *results;
>  }
>  
> -static bool ilk_disable_lp_wm(struct drm_device *dev)
> +bool ilk_disable_lp_wm(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> @@ -3544,10 +3610,10 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  	skl_allocate_pipe_ddb(crtc, cstate, ddb);
>  	skl_compute_pipe_wm(crtc, ddb, cstate, pipe_wm);
>  
> -	if (!memcmp(&cstate->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
> +	if (!memcmp(&cstate->wm.skl, pipe_wm, sizeof(*pipe_wm)))
>  		return false;
>  
> -	cstate->wm.active.skl = *pipe_wm;
> +	cstate->wm.skl = *pipe_wm;
>  
>  	return true;
>  }
> @@ -3653,24 +3719,11 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
>  	ilk_write_wm_values(dev_priv, &results);
>  }
>  
> -static void ilk_update_wm(struct drm_crtc *crtc)
> +static void ilk_optimize_watermarks(struct intel_crtc_state *cstate)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> -
> -	/*
> -	 * IVB workaround: must disable low power watermarks for at least
> -	 * one frame before enabling scaling.  LP watermarks can be re-enabled
> -	 * when scaling is disabled.
> -	 *
> -	 * WaCxSRDisabledForSpriteScaling:ivb
> -	 */
> -	if (cstate->disable_lp_wm) {
> -		ilk_disable_lp_wm(crtc->dev);
> -		intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
> -	}
> +	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
>  
> +	cstate->wm.ilk.active = cstate->wm.ilk.target;
>  	ilk_program_watermarks(dev_priv);
>  }
>  
> @@ -3725,7 +3778,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> -	struct skl_pipe_wm *active = &cstate->wm.active.skl;
> +	struct skl_pipe_wm *active = &cstate->wm.skl;
>  	enum pipe pipe = intel_crtc->pipe;
>  	int level, i, max_level;
>  	uint32_t temp;
> @@ -3789,7 +3842,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  	struct ilk_wm_values *hw = &dev_priv->wm.hw;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
> -	struct intel_pipe_wm *active = &cstate->wm.active.ilk;
> +	struct intel_pipe_wm *active = &cstate->wm.ilk.active;
>  	enum pipe pipe = intel_crtc->pipe;
>  	static const unsigned int wm0_pipe_reg[] = {
>  		[PIPE_A] = WM0_PIPEA_ILK,
> @@ -3828,6 +3881,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  		for (level = 0; level <= max_level; level++)
>  			active->wm[level].enable = true;
>  	}
> +
> +	cstate->wm.ilk.target = *active;
>  }
>  
>  #define _FW_WM(value, plane) \
> @@ -6949,8 +7004,11 @@ void intel_init_pm(struct drm_device *dev)
>  		     dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) ||
>  		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
>  		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
> -			dev_priv->display.update_wm = ilk_update_wm;
>  			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
> +			dev_priv->display.compute_intermediate_wm =
> +				ilk_compute_intermediate_wm;
> +			dev_priv->display.program_watermarks = ilk_program_watermarks;
> +			dev_priv->display.optimize_watermarks = ilk_optimize_watermarks;
>  		} else {
>  			DRM_DEBUG_KMS("Failed to read display plane latency. "
>  				      "Disable CxSR\n");
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-08-28 23:57         ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Matt Roper
  2015-08-28 23:57           ` [RFC 2/3] drm/i915: Calculate an intermediate plane/crtc atomic state for modesets Matt Roper
  2015-08-28 23:57           ` [RFC 3/3] drm/i915: Update modeset programming to use intermediate state Matt Roper
@ 2015-09-01  5:24           ` Maarten Lankhorst
  2015-09-01 15:30             ` Matt Roper
  2 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2015-09-01  5:24 UTC (permalink / raw)
  To: Matt Roper, intel-gfx

Op 29-08-15 om 01:57 schreef Matt Roper:
> Way back at the beginning of i915's atomic conversion I added
> intel_crtc->atomic as a temporary dumping ground for "stuff to do
> outside vblank evasion" flags since CRTC states weren't properly wired
> up and tracked at that time.  We've had proper CRTC state tracking for a
> while now, so there's really no reason for this hack to continue to
> exist.  Moving forward we want to store intermediate crtc/plane state
> data for modesets in addition to the final state, so moving these fields
> into the proper state object allows us to properly compute them for both
> the intermediate and final state.
>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
Can I shoot this patch down? It's better to add a field 'wm_changed' to the crtc_state,
which gets reset to false for each crtc_state duplication. It's needed for checking if a cs pageflip
can be done for atomic. It would remove the duplication of some checks there.

The other atomic state members will die soon. I already have some patches to achieve that. :)

I'm not sure if an intermediate state is a good idea. Any code that disables a crtc should only be
looking at the old state. pre_plane_update runs all stuff in preparation for disabling planes,
while post_plane_update runs everything needed for enabling planes. So no need to split it up
I think, maybe put in some intermediate watermarks in intel_atomic_state, but no need for a full
crtc_state.

After a modeset disable you should be able to put in any wm value in .crtc_enable because no plane
will be active.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check
  2015-08-28 13:42   ` Ander Conselvan De Oliveira
@ 2015-09-01  5:32     ` Maarten Lankhorst
  0 siblings, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2015-09-01  5:32 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira, Matt Roper, intel-gfx

Op 28-08-15 om 15:42 schreef Ander Conselvan De Oliveira:
> On Thu, 2015-08-20 at 18:12 -0700, Matt Roper wrote:
>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h      | 10 ++++++
>>  drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++--
>>  drivers/gpu/drm/i915/intel_drv.h     |  1 +
>>  drivers/gpu/drm/i915/intel_pm.c      | 66 +++++++-----------------------------
>>  4 files changed, 71 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index c91bab9..ac13cd7 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1686,6 +1686,13 @@ struct i915_execbuffer_params {
>>  	struct drm_i915_gem_request     *request;
>>  };
>>  
>> +/* used in computing the new watermarks state */
>> +struct intel_wm_config {
>> +	unsigned int num_pipes_active;
>> +	bool sprites_enabled;
>> +	bool sprites_scaled;
>> +};
>> +
>>  struct drm_i915_private {
>>  	struct drm_device *dev;
>>  	struct kmem_cache *objects;
>> @@ -1903,6 +1910,9 @@ struct drm_i915_private {
>>  		 */
>>  		uint16_t skl_latency[8];
>>  
>> +		/* Committed wm config */
>> +		struct intel_wm_config config;
>> +
>>  		/*
>>  		 * The skl_wm_values structure is a bit too big for stack
>>  		 * allocation, so we keep the staging struct where we store
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index c40f025..8e9d87a 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -13005,6 +13005,44 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>>  	return 0;
>>  }
>>  
>> +/*
>> + * Handle calculation of various watermark data at the end of the atomic check
>> + * phase.  The code here should be run after the per-crtc and per-plane 'check'
>> + * handlers to ensure that all derived state has been updated.
>> + */
>> +static void calc_watermark_data(struct drm_atomic_state *state)
>> +{
>> +	struct drm_device *dev = state->dev;
>> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>> +	struct drm_crtc *crtc;
>> +	struct drm_crtc_state *cstate;
>> +	struct drm_plane *plane;
>> +	struct drm_plane_state *pstate;
>> +
>> +	/*
>> +	 * Calculate watermark configuration details now that derived
>> +	 * plane/crtc state is all properly updated.
>> +	 */
>> +	drm_for_each_crtc(crtc, dev) {
>> +		cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
>> +			crtc->state;
>> +
> Did you intend to check crtc->active here?
>
>> +		intel_state->wm_config.num_pipes_active++;
>> +	}
>> +	drm_for_each_legacy_plane(plane, dev) {
>> +		pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
>> +			plane->state;
>> +
>> +		if (!to_intel_plane_state(pstate)->visible)
>> +			continue;
> If I understand correctly, it is possible for a plane on an inactive crtc to have visible = true. In
> that case, the result here would be different than the function this replaces, which counts only
> planes on active crtcs.
>
Now that i915's atomic visibility is updated correctly in almost all cases except initial readout perhaps. :-)

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

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-01  5:24           ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Maarten Lankhorst
@ 2015-09-01 15:30             ` Matt Roper
  2015-09-01 15:48               ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Matt Roper @ 2015-09-01 15:30 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, Ville Syrjälä

On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
> Op 29-08-15 om 01:57 schreef Matt Roper:
> > Way back at the beginning of i915's atomic conversion I added
> > intel_crtc->atomic as a temporary dumping ground for "stuff to do
> > outside vblank evasion" flags since CRTC states weren't properly wired
> > up and tracked at that time.  We've had proper CRTC state tracking for a
> > while now, so there's really no reason for this hack to continue to
> > exist.  Moving forward we want to store intermediate crtc/plane state
> > data for modesets in addition to the final state, so moving these fields
> > into the proper state object allows us to properly compute them for both
> > the intermediate and final state.
> >
> > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> > ---
> Can I shoot this patch down? It's better to add a field 'wm_changed'
> to the crtc_state, which gets reset to false for each crtc_state
> duplication. It's needed for checking if a cs pageflip can be done for
> atomic. It would remove the duplication of some checks there.
> 
> The other atomic state members will die soon. I already have some
> patches to achieve that. :)
> 
> I'm not sure if an intermediate state is a good idea. Any code that
> disables a crtc should only be looking at the old state.
> pre_plane_update runs all stuff in preparation for disabling planes,
> while post_plane_update runs everything needed for enabling planes. So
> no need to split it up I think, maybe put in some intermediate
> watermarks in intel_atomic_state, but no need for a full crtc_state.

Well, the intermediate state stuff was requested by Ville in response to
my watermark series, so I posted these patches as an RFC to make sure I
was understanding what he was looking for properly.

Ville, can you comment?


Matt

> 
> After a modeset disable you should be able to put in any wm value in
> .crtc_enable because no plane will be active.

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-01 15:30             ` Matt Roper
@ 2015-09-01 15:48               ` Ville Syrjälä
  2015-09-02  5:15                 ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2015-09-01 15:48 UTC (permalink / raw)
  To: Matt Roper; +Cc: Ville Syrjälä, intel-gfx

On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
> > Op 29-08-15 om 01:57 schreef Matt Roper:
> > > Way back at the beginning of i915's atomic conversion I added
> > > intel_crtc->atomic as a temporary dumping ground for "stuff to do
> > > outside vblank evasion" flags since CRTC states weren't properly wired
> > > up and tracked at that time.  We've had proper CRTC state tracking for a
> > > while now, so there's really no reason for this hack to continue to
> > > exist.  Moving forward we want to store intermediate crtc/plane state
> > > data for modesets in addition to the final state, so moving these fields
> > > into the proper state object allows us to properly compute them for both
> > > the intermediate and final state.
> > >
> > > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> > > ---
> > Can I shoot this patch down? It's better to add a field 'wm_changed'
> > to the crtc_state, which gets reset to false for each crtc_state
> > duplication. It's needed for checking if a cs pageflip can be done for
> > atomic. It would remove the duplication of some checks there.
> > 
> > The other atomic state members will die soon. I already have some
> > patches to achieve that. :)
> > 
> > I'm not sure if an intermediate state is a good idea. Any code that
> > disables a crtc should only be looking at the old state.
> > pre_plane_update runs all stuff in preparation for disabling planes,
> > while post_plane_update runs everything needed for enabling planes. So
> > no need to split it up I think, maybe put in some intermediate
> > watermarks in intel_atomic_state, but no need for a full crtc_state.
> 
> Well, the intermediate state stuff was requested by Ville in response to
> my watermark series, so I posted these patches as an RFC to make sure I
> was understanding what he was looking for properly.
> 
> Ville, can you comment?

My opinion is that the current "disable is special" way of doing things
is quite horrible. For one it makes it really hard to reason about what
happens to a plane or crtc during the modeset. It's not just off->on,
on->off, or same->same, but can be on->off->on. With the intermediate
state in place, there can only be one transition, so really easy to
think about what's going on.

It'll also mean don't have to sprinkle silly wm update calls all over
the modeset path. They will just get updated in response to the plane
state changes. Same for IPS/FBC etc.

> 
> 
> Matt
> 
> > 
> > After a modeset disable you should be able to put in any wm value in
> > .crtc_enable because no plane will be active.
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-01 15:48               ` Ville Syrjälä
@ 2015-09-02  5:15                 ` Maarten Lankhorst
  2015-09-02 10:35                   ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2015-09-02  5:15 UTC (permalink / raw)
  To: Ville Syrjälä, Matt Roper; +Cc: intel-gfx, Ville Syrjälä

Op 01-09-15 om 17:48 schreef Ville Syrjälä:
> On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
>> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
>>> Op 29-08-15 om 01:57 schreef Matt Roper:
>>>> Way back at the beginning of i915's atomic conversion I added
>>>> intel_crtc->atomic as a temporary dumping ground for "stuff to do
>>>> outside vblank evasion" flags since CRTC states weren't properly wired
>>>> up and tracked at that time.  We've had proper CRTC state tracking for a
>>>> while now, so there's really no reason for this hack to continue to
>>>> exist.  Moving forward we want to store intermediate crtc/plane state
>>>> data for modesets in addition to the final state, so moving these fields
>>>> into the proper state object allows us to properly compute them for both
>>>> the intermediate and final state.
>>>>
>>>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
>>>> ---
>>> Can I shoot this patch down? It's better to add a field 'wm_changed'
>>> to the crtc_state, which gets reset to false for each crtc_state
>>> duplication. It's needed for checking if a cs pageflip can be done for
>>> atomic. It would remove the duplication of some checks there.
>>>
>>> The other atomic state members will die soon. I already have some
>>> patches to achieve that. :)
>>>
>>> I'm not sure if an intermediate state is a good idea. Any code that
>>> disables a crtc should only be looking at the old state.
>>> pre_plane_update runs all stuff in preparation for disabling planes,
>>> while post_plane_update runs everything needed for enabling planes. So
>>> no need to split it up I think, maybe put in some intermediate
>>> watermarks in intel_atomic_state, but no need for a full crtc_state.
>> Well, the intermediate state stuff was requested by Ville in response to
>> my watermark series, so I posted these patches as an RFC to make sure I
>> was understanding what he was looking for properly.
>>
>> Ville, can you comment?
> My opinion is that the current "disable is special" way of doing things
> is quite horrible. For one it makes it really hard to reason about what
> happens to a plane or crtc during the modeset. It's not just off->on,
> on->off, or same->same, but can be on->off->on. With the intermediate
> state in place, there can only be one transition, so really easy to
> think about what's going on.
pre_plane_update deals with all stuff related to disabling planes, while post_plane_update deals with changes after enabling.

If the crtc goes from on -> off only you could just hammer in the final values after the disable.

While for off->on or on->off->on you can put in the final values in .crtc_enable before lighting the pipe. I don't see why wm's would need more transitions.
> It'll also mean don't have to sprinkle silly wm update calls all over
> the modeset path. They will just get updated in response to the plane
> state changes. Same for IPS/FBC etc.
IPS and FBC are already calculated correctly in response to modesets.

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

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-02  5:15                 ` Maarten Lankhorst
@ 2015-09-02 10:35                   ` Ville Syrjälä
  2015-09-02 11:08                     ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2015-09-02 10:35 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ville Syrjälä, intel-gfx

On Wed, Sep 02, 2015 at 07:15:25AM +0200, Maarten Lankhorst wrote:
> Op 01-09-15 om 17:48 schreef Ville Syrjälä:
> > On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
> >> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
> >>> Op 29-08-15 om 01:57 schreef Matt Roper:
> >>>> Way back at the beginning of i915's atomic conversion I added
> >>>> intel_crtc->atomic as a temporary dumping ground for "stuff to do
> >>>> outside vblank evasion" flags since CRTC states weren't properly wired
> >>>> up and tracked at that time.  We've had proper CRTC state tracking for a
> >>>> while now, so there's really no reason for this hack to continue to
> >>>> exist.  Moving forward we want to store intermediate crtc/plane state
> >>>> data for modesets in addition to the final state, so moving these fields
> >>>> into the proper state object allows us to properly compute them for both
> >>>> the intermediate and final state.
> >>>>
> >>>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> >>>> ---
> >>> Can I shoot this patch down? It's better to add a field 'wm_changed'
> >>> to the crtc_state, which gets reset to false for each crtc_state
> >>> duplication. It's needed for checking if a cs pageflip can be done for
> >>> atomic. It would remove the duplication of some checks there.
> >>>
> >>> The other atomic state members will die soon. I already have some
> >>> patches to achieve that. :)
> >>>
> >>> I'm not sure if an intermediate state is a good idea. Any code that
> >>> disables a crtc should only be looking at the old state.
> >>> pre_plane_update runs all stuff in preparation for disabling planes,
> >>> while post_plane_update runs everything needed for enabling planes. So
> >>> no need to split it up I think, maybe put in some intermediate
> >>> watermarks in intel_atomic_state, but no need for a full crtc_state.
> >> Well, the intermediate state stuff was requested by Ville in response to
> >> my watermark series, so I posted these patches as an RFC to make sure I
> >> was understanding what he was looking for properly.
> >>
> >> Ville, can you comment?
> > My opinion is that the current "disable is special" way of doing things
> > is quite horrible. For one it makes it really hard to reason about what
> > happens to a plane or crtc during the modeset. It's not just off->on,
> > on->off, or same->same, but can be on->off->on. With the intermediate
> > state in place, there can only be one transition, so really easy to
> > think about what's going on.
> pre_plane_update deals with all stuff related to disabling planes, while post_plane_update deals with changes after enabling.
> 
> If the crtc goes from on -> off only you could just hammer in the final values after the disable.
> 
> While for off->on or on->off->on you can put in the final values in .crtc_enable before lighting the pipe. I don't see why wm's would need more transitions.

One special case after another. Yuck. Not to mention that the plane
disable isn't even atomic in the current code, which can look ugly.

> > It'll also mean don't have to sprinkle silly wm update calls all over
> > the modeset path. They will just get updated in response to the plane
> > state changes. Same for IPS/FBC etc.
> IPS and FBC are already calculated correctly in response to modesets.

Correctly perhaps, but not in an obvious way.

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

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-02 10:35                   ` Ville Syrjälä
@ 2015-09-02 11:08                     ` Maarten Lankhorst
  2015-09-02 11:15                       ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2015-09-02 11:08 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Ville Syrjälä, intel-gfx

Op 02-09-15 om 12:35 schreef Ville Syrjälä:
> On Wed, Sep 02, 2015 at 07:15:25AM +0200, Maarten Lankhorst wrote:
>> Op 01-09-15 om 17:48 schreef Ville Syrjälä:
>>> On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
>>>> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
>>>>> Op 29-08-15 om 01:57 schreef Matt Roper:
>>>>>> Way back at the beginning of i915's atomic conversion I added
>>>>>> intel_crtc->atomic as a temporary dumping ground for "stuff to do
>>>>>> outside vblank evasion" flags since CRTC states weren't properly wired
>>>>>> up and tracked at that time.  We've had proper CRTC state tracking for a
>>>>>> while now, so there's really no reason for this hack to continue to
>>>>>> exist.  Moving forward we want to store intermediate crtc/plane state
>>>>>> data for modesets in addition to the final state, so moving these fields
>>>>>> into the proper state object allows us to properly compute them for both
>>>>>> the intermediate and final state.
>>>>>>
>>>>>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
>>>>>> ---
>>>>> Can I shoot this patch down? It's better to add a field 'wm_changed'
>>>>> to the crtc_state, which gets reset to false for each crtc_state
>>>>> duplication. It's needed for checking if a cs pageflip can be done for
>>>>> atomic. It would remove the duplication of some checks there.
>>>>>
>>>>> The other atomic state members will die soon. I already have some
>>>>> patches to achieve that. :)
>>>>>
>>>>> I'm not sure if an intermediate state is a good idea. Any code that
>>>>> disables a crtc should only be looking at the old state.
>>>>> pre_plane_update runs all stuff in preparation for disabling planes,
>>>>> while post_plane_update runs everything needed for enabling planes. So
>>>>> no need to split it up I think, maybe put in some intermediate
>>>>> watermarks in intel_atomic_state, but no need for a full crtc_state.
>>>> Well, the intermediate state stuff was requested by Ville in response to
>>>> my watermark series, so I posted these patches as an RFC to make sure I
>>>> was understanding what he was looking for properly.
>>>>
>>>> Ville, can you comment?
>>> My opinion is that the current "disable is special" way of doing things
>>> is quite horrible. For one it makes it really hard to reason about what
>>> happens to a plane or crtc during the modeset. It's not just off->on,
>>> on->off, or same->same, but can be on->off->on. With the intermediate
>>> state in place, there can only be one transition, so really easy to
>>> think about what's going on.
>> pre_plane_update deals with all stuff related to disabling planes, while post_plane_update deals with changes after enabling.
>>
>> If the crtc goes from on -> off only you could just hammer in the final values after the disable.
>>
>> While for off->on or on->off->on you can put in the final values in .crtc_enable before lighting the pipe. I don't see why wm's would need more transitions.
> One special case after another. Yuck. Not to mention that the plane
> disable isn't even atomic in the current code, which can look ugly.
That's easily fixed by adding a pipe_update_start/end pair.
>>> It'll also mean don't have to sprinkle silly wm update calls all over
>>> the modeset path. They will just get updated in response to the plane
>>> state changes. Same for IPS/FBC etc.
>> IPS and FBC are already calculated correctly in response to modesets.
> Correctly perhaps, but not in an obvious way.
It will become more obvious again when pre_plane_update and post_plane_update are loops
instead of being precalculated from intel_plane_atomic_calc_changes.

But if you can precalculate fb_bits and know of wm changed post commit then post_plane_update
only cares about primary plane state.

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

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-02 11:08                     ` Maarten Lankhorst
@ 2015-09-02 11:15                       ` Ville Syrjälä
  2015-09-02 14:22                         ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2015-09-02 11:15 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Wed, Sep 02, 2015 at 01:08:31PM +0200, Maarten Lankhorst wrote:
> Op 02-09-15 om 12:35 schreef Ville Syrjälä:
> > On Wed, Sep 02, 2015 at 07:15:25AM +0200, Maarten Lankhorst wrote:
> >> Op 01-09-15 om 17:48 schreef Ville Syrjälä:
> >>> On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
> >>>> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
> >>>>> Op 29-08-15 om 01:57 schreef Matt Roper:
> >>>>>> Way back at the beginning of i915's atomic conversion I added
> >>>>>> intel_crtc->atomic as a temporary dumping ground for "stuff to do
> >>>>>> outside vblank evasion" flags since CRTC states weren't properly wired
> >>>>>> up and tracked at that time.  We've had proper CRTC state tracking for a
> >>>>>> while now, so there's really no reason for this hack to continue to
> >>>>>> exist.  Moving forward we want to store intermediate crtc/plane state
> >>>>>> data for modesets in addition to the final state, so moving these fields
> >>>>>> into the proper state object allows us to properly compute them for both
> >>>>>> the intermediate and final state.
> >>>>>>
> >>>>>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> >>>>>> ---
> >>>>> Can I shoot this patch down? It's better to add a field 'wm_changed'
> >>>>> to the crtc_state, which gets reset to false for each crtc_state
> >>>>> duplication. It's needed for checking if a cs pageflip can be done for
> >>>>> atomic. It would remove the duplication of some checks there.
> >>>>>
> >>>>> The other atomic state members will die soon. I already have some
> >>>>> patches to achieve that. :)
> >>>>>
> >>>>> I'm not sure if an intermediate state is a good idea. Any code that
> >>>>> disables a crtc should only be looking at the old state.
> >>>>> pre_plane_update runs all stuff in preparation for disabling planes,
> >>>>> while post_plane_update runs everything needed for enabling planes. So
> >>>>> no need to split it up I think, maybe put in some intermediate
> >>>>> watermarks in intel_atomic_state, but no need for a full crtc_state.
> >>>> Well, the intermediate state stuff was requested by Ville in response to
> >>>> my watermark series, so I posted these patches as an RFC to make sure I
> >>>> was understanding what he was looking for properly.
> >>>>
> >>>> Ville, can you comment?
> >>> My opinion is that the current "disable is special" way of doing things
> >>> is quite horrible. For one it makes it really hard to reason about what
> >>> happens to a plane or crtc during the modeset. It's not just off->on,
> >>> on->off, or same->same, but can be on->off->on. With the intermediate
> >>> state in place, there can only be one transition, so really easy to
> >>> think about what's going on.
> >> pre_plane_update deals with all stuff related to disabling planes, while post_plane_update deals with changes after enabling.
> >>
> >> If the crtc goes from on -> off only you could just hammer in the final values after the disable.
> >>
> >> While for off->on or on->off->on you can put in the final values in .crtc_enable before lighting the pipe. I don't see why wm's would need more transitions.
> > One special case after another. Yuck. Not to mention that the plane
> > disable isn't even atomic in the current code, which can look ugly.
> That's easily fixed by adding a pipe_update_start/end pair.
> >>> It'll also mean don't have to sprinkle silly wm update calls all over
> >>> the modeset path. They will just get updated in response to the plane
> >>> state changes. Same for IPS/FBC etc.
> >> IPS and FBC are already calculated correctly in response to modesets.
> > Correctly perhaps, but not in an obvious way.
> It will become more obvious again when pre_plane_update and post_plane_update are loops
> instead of being precalculated from intel_plane_atomic_calc_changes.

It'll never be obvious as long as the on->off->on case exists.

> 
> But if you can precalculate fb_bits and know of wm changed post commit then post_plane_update
> only cares about primary plane state.
> 
> ~Maarten

-- 
Ville Syrjälä
Intel OTC
---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

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

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-02 11:15                       ` Ville Syrjälä
@ 2015-09-02 14:22                         ` Maarten Lankhorst
  2015-09-02 15:33                           ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2015-09-02 14:22 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 02-09-15 om 13:15 schreef Ville Syrjälä:
> On Wed, Sep 02, 2015 at 01:08:31PM +0200, Maarten Lankhorst wrote:
>> Op 02-09-15 om 12:35 schreef Ville Syrjälä:
>>> On Wed, Sep 02, 2015 at 07:15:25AM +0200, Maarten Lankhorst wrote:
>>>> Op 01-09-15 om 17:48 schreef Ville Syrjälä:
>>>>> On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
>>>>>> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
>>>>>>> Op 29-08-15 om 01:57 schreef Matt Roper:
>>>>>>>> Way back at the beginning of i915's atomic conversion I added
>>>>>>>> intel_crtc->atomic as a temporary dumping ground for "stuff to do
>>>>>>>> outside vblank evasion" flags since CRTC states weren't properly wired
>>>>>>>> up and tracked at that time.  We've had proper CRTC state tracking for a
>>>>>>>> while now, so there's really no reason for this hack to continue to
>>>>>>>> exist.  Moving forward we want to store intermediate crtc/plane state
>>>>>>>> data for modesets in addition to the final state, so moving these fields
>>>>>>>> into the proper state object allows us to properly compute them for both
>>>>>>>> the intermediate and final state.
>>>>>>>>
>>>>>>>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
>>>>>>>> ---
>>>>>>> Can I shoot this patch down? It's better to add a field 'wm_changed'
>>>>>>> to the crtc_state, which gets reset to false for each crtc_state
>>>>>>> duplication. It's needed for checking if a cs pageflip can be done for
>>>>>>> atomic. It would remove the duplication of some checks there.
>>>>>>>
>>>>>>> The other atomic state members will die soon. I already have some
>>>>>>> patches to achieve that. :)
>>>>>>>
>>>>>>> I'm not sure if an intermediate state is a good idea. Any code that
>>>>>>> disables a crtc should only be looking at the old state.
>>>>>>> pre_plane_update runs all stuff in preparation for disabling planes,
>>>>>>> while post_plane_update runs everything needed for enabling planes. So
>>>>>>> no need to split it up I think, maybe put in some intermediate
>>>>>>> watermarks in intel_atomic_state, but no need for a full crtc_state.
>>>>>> Well, the intermediate state stuff was requested by Ville in response to
>>>>>> my watermark series, so I posted these patches as an RFC to make sure I
>>>>>> was understanding what he was looking for properly.
>>>>>>
>>>>>> Ville, can you comment?
>>>>> My opinion is that the current "disable is special" way of doing things
>>>>> is quite horrible. For one it makes it really hard to reason about what
>>>>> happens to a plane or crtc during the modeset. It's not just off->on,
>>>>> on->off, or same->same, but can be on->off->on. With the intermediate
>>>>> state in place, there can only be one transition, so really easy to
>>>>> think about what's going on.
>>>> pre_plane_update deals with all stuff related to disabling planes, while post_plane_update deals with changes after enabling.
>>>>
>>>> If the crtc goes from on -> off only you could just hammer in the final values after the disable.
>>>>
>>>> While for off->on or on->off->on you can put in the final values in .crtc_enable before lighting the pipe. I don't see why wm's would need more transitions.
>>> One special case after another. Yuck. Not to mention that the plane
>>> disable isn't even atomic in the current code, which can look ugly.
>> That's easily fixed by adding a pipe_update_start/end pair.
>>>>> It'll also mean don't have to sprinkle silly wm update calls all over
>>>>> the modeset path. They will just get updated in response to the plane
>>>>> state changes. Same for IPS/FBC etc.
>>>> IPS and FBC are already calculated correctly in response to modesets.
>>> Correctly perhaps, but not in an obvious way.
>> It will become more obvious again when pre_plane_update and post_plane_update are loops
>> instead of being precalculated from intel_plane_atomic_calc_changes.
> It'll never be obvious as long as the on->off->on case exists.
>
But On -> off will always be a special case because any enable might depend on the disable, for example taking over the pll or cdclk changes.
It can never be the same, so why pretend it is?
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state
  2015-09-02 14:22                         ` Maarten Lankhorst
@ 2015-09-02 15:33                           ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2015-09-02 15:33 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, Ville Syrjälä

On Wed, Sep 02, 2015 at 04:22:56PM +0200, Maarten Lankhorst wrote:
> Op 02-09-15 om 13:15 schreef Ville Syrjälä:
> > On Wed, Sep 02, 2015 at 01:08:31PM +0200, Maarten Lankhorst wrote:
> >> Op 02-09-15 om 12:35 schreef Ville Syrjälä:
> >>> On Wed, Sep 02, 2015 at 07:15:25AM +0200, Maarten Lankhorst wrote:
> >>>> Op 01-09-15 om 17:48 schreef Ville Syrjälä:
> >>>>> On Tue, Sep 01, 2015 at 08:30:05AM -0700, Matt Roper wrote:
> >>>>>> On Tue, Sep 01, 2015 at 07:24:19AM +0200, Maarten Lankhorst wrote:
> >>>>>>> Op 29-08-15 om 01:57 schreef Matt Roper:
> >>>>>>>> Way back at the beginning of i915's atomic conversion I added
> >>>>>>>> intel_crtc->atomic as a temporary dumping ground for "stuff to do
> >>>>>>>> outside vblank evasion" flags since CRTC states weren't properly wired
> >>>>>>>> up and tracked at that time.  We've had proper CRTC state tracking for a
> >>>>>>>> while now, so there's really no reason for this hack to continue to
> >>>>>>>> exist.  Moving forward we want to store intermediate crtc/plane state
> >>>>>>>> data for modesets in addition to the final state, so moving these fields
> >>>>>>>> into the proper state object allows us to properly compute them for both
> >>>>>>>> the intermediate and final state.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> >>>>>>>> ---
> >>>>>>> Can I shoot this patch down? It's better to add a field 'wm_changed'
> >>>>>>> to the crtc_state, which gets reset to false for each crtc_state
> >>>>>>> duplication. It's needed for checking if a cs pageflip can be done for
> >>>>>>> atomic. It would remove the duplication of some checks there.
> >>>>>>>
> >>>>>>> The other atomic state members will die soon. I already have some
> >>>>>>> patches to achieve that. :)
> >>>>>>>
> >>>>>>> I'm not sure if an intermediate state is a good idea. Any code that
> >>>>>>> disables a crtc should only be looking at the old state.
> >>>>>>> pre_plane_update runs all stuff in preparation for disabling planes,
> >>>>>>> while post_plane_update runs everything needed for enabling planes. So
> >>>>>>> no need to split it up I think, maybe put in some intermediate
> >>>>>>> watermarks in intel_atomic_state, but no need for a full crtc_state.
> >>>>>> Well, the intermediate state stuff was requested by Ville in response to
> >>>>>> my watermark series, so I posted these patches as an RFC to make sure I
> >>>>>> was understanding what he was looking for properly.
> >>>>>>
> >>>>>> Ville, can you comment?
> >>>>> My opinion is that the current "disable is special" way of doing things
> >>>>> is quite horrible. For one it makes it really hard to reason about what
> >>>>> happens to a plane or crtc during the modeset. It's not just off->on,
> >>>>> on->off, or same->same, but can be on->off->on. With the intermediate
> >>>>> state in place, there can only be one transition, so really easy to
> >>>>> think about what's going on.
> >>>> pre_plane_update deals with all stuff related to disabling planes, while post_plane_update deals with changes after enabling.
> >>>>
> >>>> If the crtc goes from on -> off only you could just hammer in the final values after the disable.
> >>>>
> >>>> While for off->on or on->off->on you can put in the final values in .crtc_enable before lighting the pipe. I don't see why wm's would need more transitions.
> >>> One special case after another. Yuck. Not to mention that the plane
> >>> disable isn't even atomic in the current code, which can look ugly.
> >> That's easily fixed by adding a pipe_update_start/end pair.
> >>>>> It'll also mean don't have to sprinkle silly wm update calls all over
> >>>>> the modeset path. They will just get updated in response to the plane
> >>>>> state changes. Same for IPS/FBC etc.
> >>>> IPS and FBC are already calculated correctly in response to modesets.
> >>> Correctly perhaps, but not in an obvious way.
> >> It will become more obvious again when pre_plane_update and post_plane_update are loops
> >> instead of being precalculated from intel_plane_atomic_calc_changes.
> > It'll never be obvious as long as the on->off->on case exists.
> >
> But On -> off will always be a special case because any enable might depend on the disable, for example taking over the pll or cdclk changes.
> It can never be the same, so why pretend it is?

I don't understand what you're saying. If we had the intermediate atomic
state, plane code wouldn't need to know at all what's happening to the
pipe. And for pipes there can only be an on->off or off->on transition.

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

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

end of thread, other threads:[~2015-09-02 15:33 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-21  1:11 [PATCH 00/13] Atomic watermark updates (v3) Matt Roper
2015-08-21  1:11 ` [PATCH 01/13] drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code Matt Roper
2015-08-26 12:45   ` Conselvan De Oliveira, Ander
2015-08-26 13:23     ` Ville Syrjälä
2015-08-21  1:11 ` [PATCH 02/13] drm/i915: Eliminate usage of pipe_wm_parameters from ILK-style WM Matt Roper
2015-08-26 12:45   ` Ander Conselvan De Oliveira
2015-08-26 13:39   ` Ville Syrjälä
2015-08-26 15:37     ` Matt Roper
2015-08-26 15:51       ` Ville Syrjälä
2015-08-28 23:57         ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Matt Roper
2015-08-28 23:57           ` [RFC 2/3] drm/i915: Calculate an intermediate plane/crtc atomic state for modesets Matt Roper
2015-08-28 23:57           ` [RFC 3/3] drm/i915: Update modeset programming to use intermediate state Matt Roper
2015-09-01  5:24           ` [RFC 1/3] drm/i915: Roll intel_crtc->atomic into intel_crtc_state Maarten Lankhorst
2015-09-01 15:30             ` Matt Roper
2015-09-01 15:48               ` Ville Syrjälä
2015-09-02  5:15                 ` Maarten Lankhorst
2015-09-02 10:35                   ` Ville Syrjälä
2015-09-02 11:08                     ` Maarten Lankhorst
2015-09-02 11:15                       ` Ville Syrjälä
2015-09-02 14:22                         ` Maarten Lankhorst
2015-09-02 15:33                           ` Ville Syrjälä
2015-08-21  1:11 ` [PATCH 03/13] drm/i915/skl: Simplify wm structures slightly Matt Roper
2015-08-26 13:23   ` Ander Conselvan De Oliveira
2015-08-21  1:11 ` [PATCH 04/13] drm/i915/skl: Eliminate usage of pipe_wm_parameters from SKL-style WM Matt Roper
2015-08-27 12:55   ` Ander Conselvan De Oliveira
2015-08-21  1:11 ` [PATCH 05/13] drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check Matt Roper
2015-08-21  1:11 ` [PATCH 06/13] drm/i915: Drop intel_update_sprite_watermarks Matt Roper
2015-08-21  1:11 ` [PATCH 07/13] drm/i915: Refactor ilk_update_wm (v3) Matt Roper
2015-08-21  1:11 ` [PATCH 08/13] drm/i915: Move active watermarks into CRTC state (v2) Matt Roper
2015-08-26 13:10   ` Ville Syrjälä
2015-08-21  1:12 ` [PATCH 09/13] drm/i915: Calculate ILK-style watermarks during atomic check (v2) Matt Roper
2015-08-28 12:53   ` Ander Conselvan De Oliveira
2015-08-28 12:56   ` Ander Conselvan De Oliveira
2015-08-21  1:12 ` [PATCH 10/13] drm/i915: Calculate watermark configuration during atomic check Matt Roper
2015-08-28 13:42   ` Ander Conselvan De Oliveira
2015-09-01  5:32     ` Maarten Lankhorst
2015-08-21  1:12 ` [PATCH 11/13] drm/i915: Add two-stage ILK-style watermark programming (v3) Matt Roper
2015-08-31 14:36   ` Ander Conselvan De Oliveira
2015-08-21  1:12 ` [PATCH 12/13] drm/i915/skl: Switch to atomic watermark programming Matt Roper
2015-08-21  1:12 ` [PATCH 13/13] drm/i915/skl: Clarify pending vs hw watermark values Matt Roper
2015-08-26  4:33 ` [PATCH 00/13] Atomic watermark updates (v3) Hindman, Gavin
2015-08-26 18:07   ` Matt Roper

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.