All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully
@ 2018-11-01 15:05 Ville Syrjala
  2018-11-01 15:05 ` [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs Ville Syrjala
                   ` (19 more replies)
  0 siblings, 20 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

First a bunch of cleanups and reordering of the plane register
update sequence to make it potentially more atomic, then we
move the SKL+ plane wm/ddb programming into the plane
update/disable hooks, and finally we change the order in which
the planes gets updated to avoid accidental ddb overlaps in
case a vblank sneaks in while we're reprogramming the planes
(as that could even cause a system hang). There are a few
updates to the watermark code as well that started to bug me
while doing this.

Entire thing available here:
git://github.com/vsyrjala/linux.git skl_plane_ddb_wm_update

Ville Syrjälä (14):
  drm/i915: Nuke posting reads from plane update/disable funcs
  drm/i915: Clean up skl_program_scaler()
  drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler()
  drm/i915: Polish the skl+ plane keyval/msk/max register setup
  drm/i915: Clean up skl+ PLANE_POS vs. scaler handling
  drm/i915: Reorganize plane register writes to make them more atomic
  drm/i915: Move single buffered plane register writes to the end
  drm/i915: Generalize skl_ddb_allocation_overlaps()
  drm/i915: Introduce crtc_state->update_planes bitmask
  drm/i915: Pass the new crtc_state to ->disable_plane()
  drm/i915: Fix latency==0 handling for level 0 watermark on skl+
  drm/i915: Remove some useless zeroing on skl+ wm calculations
  drm/i915: Move ddb/wm programming into plane update/disable hooks on
    skl+
  drm/i915: Commit skl+ planes in an order that avoids ddb overlaps

 drivers/gpu/drm/i915/i915_debugfs.c       |  21 +-
 drivers/gpu/drm/i915/i915_drv.h           |   3 -
 drivers/gpu/drm/i915/i915_reg.h           |   2 +-
 drivers/gpu/drm/i915/intel_atomic.c       |   1 +
 drivers/gpu/drm/i915/intel_atomic_plane.c | 102 ++++-
 drivers/gpu/drm/i915/intel_display.c      | 125 +++---
 drivers/gpu/drm/i915/intel_display.h      |  19 +-
 drivers/gpu/drm/i915/intel_drv.h          |  29 +-
 drivers/gpu/drm/i915/intel_pm.c           | 483 ++++++++++------------
 drivers/gpu/drm/i915/intel_sprite.c       | 185 +++++----
 10 files changed, 518 insertions(+), 452 deletions(-)

-- 
2.18.1

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

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

* [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-01 18:08   ` Rodrigo Vivi
  2018-11-01 15:05 ` [PATCH 02/14] drm/i915: Clean up skl_program_scaler() Ville Syrjala
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

No need for the posting reads in the plane update/disable hooks.
If we need a posting read for something then a single one at the
very end would be sufficient. We have that anyway in the form
of eg. scanline/frame counter reads.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  6 ------
 drivers/gpu/drm/i915/intel_sprite.c  | 12 ------------
 2 files changed, 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7e1131d806ae..c5ce3892d583 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3378,7 +3378,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
 			      intel_plane_ggtt_offset(plane_state) +
 			      dspaddr_offset);
 	}
-	POSTING_READ_FW(reg);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -3397,7 +3396,6 @@ static void i9xx_disable_plane(struct intel_plane *plane,
 		I915_WRITE_FW(DSPSURF(i9xx_plane), 0);
 	else
 		I915_WRITE_FW(DSPADDR(i9xx_plane), 0);
-	POSTING_READ_FW(DSPCNTR(i9xx_plane));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -9850,8 +9848,6 @@ static void i845_update_cursor(struct intel_plane *plane,
 		I915_WRITE_FW(CURPOS(PIPE_A), pos);
 	}
 
-	POSTING_READ_FW(CURCNTR(PIPE_A));
-
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -10080,8 +10076,6 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 		I915_WRITE_FW(CURBASE(pipe), base);
 	}
 
-	POSTING_READ_FW(CURBASE(pipe));
-
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 20b5b9ff782f..bd7d988d7512 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -463,7 +463,6 @@ skl_program_plane(struct intel_plane *plane,
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + surf_addr);
-	POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -504,9 +503,7 @@ skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
-
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
-	POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -752,7 +749,6 @@ vlv_update_plane(struct intel_plane *plane,
 	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
 	I915_WRITE_FW(SPSURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
-	POSTING_READ_FW(SPSURF(pipe, plane_id));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -768,9 +764,7 @@ vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
-
 	I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
-	POSTING_READ_FW(SPSURF(pipe, plane_id));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -918,7 +912,6 @@ ivb_update_plane(struct intel_plane *plane,
 	I915_WRITE_FW(SPRCTL(pipe), sprctl);
 	I915_WRITE_FW(SPRSURF(pipe),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
-	POSTING_READ_FW(SPRSURF(pipe));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -936,9 +929,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 	/* Can't leave the scaler enabled... */
 	if (IS_IVYBRIDGE(dev_priv))
 		I915_WRITE_FW(SPRSCALE(pipe), 0);
-
 	I915_WRITE_FW(SPRSURF(pipe), 0);
-	POSTING_READ_FW(SPRSURF(pipe));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -1085,7 +1076,6 @@ g4x_update_plane(struct intel_plane *plane,
 	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
 	I915_WRITE_FW(DVSSURF(pipe),
 		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
-	POSTING_READ_FW(DVSSURF(pipe));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -1102,9 +1092,7 @@ g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 	I915_WRITE_FW(DVSCNTR(pipe), 0);
 	/* Disable the scaler */
 	I915_WRITE_FW(DVSSCALE(pipe), 0);
-
 	I915_WRITE_FW(DVSSURF(pipe), 0);
-	POSTING_READ_FW(DVSSURF(pipe));
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
-- 
2.18.1

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

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

* [PATCH 02/14] drm/i915: Clean up skl_program_scaler()
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
  2018-11-01 15:05 ` [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-01 15:17   ` [PATCH v2 " Ville Syrjala
  2018-11-01 15:05 ` [PATCH 03/14] drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler() Ville Syrjala
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

Remove the "sizes are 0 based" stuff that is not even true for the
scaler.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index bd7d988d7512..a1e215636331 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -310,12 +310,11 @@ skl_plane_max_stride(struct intel_plane *plane,
 }
 
 static void
-skl_program_scaler(struct drm_i915_private *dev_priv,
-		   struct intel_plane *plane,
+skl_program_scaler(struct intel_plane *plane,
 		   const struct intel_crtc_state *crtc_state,
 		   const struct intel_plane_state *plane_state)
 {
-	enum plane_id plane_id = plane->id;
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 	int scaler_id = plane_state->scaler_id;
 	const struct intel_scaler *scaler =
@@ -335,10 +334,6 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
 				      &plane_state->base.dst,
 				      0, INT_MAX);
 
-	/* Sizes are 0 based */
-	crtc_w--;
-	crtc_h--;
-
 	/* TODO: handle sub-pixel coordinates */
 	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
 	    !icl_is_hdr_plane(plane)) {
@@ -358,15 +353,14 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
 	}
 
 	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
-		      PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
+		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
 	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
 	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
 		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
 	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
 		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
 	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
-	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
-		      ((crtc_w + 1) << 16)|(crtc_h + 1));
+	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
 }
 
 static void
@@ -449,11 +443,9 @@ skl_program_plane(struct intel_plane *plane,
 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
 	}
 
-	/* program plane scaler */
 	if (plane_state->scaler_id >= 0) {
 		if (!slave)
-			skl_program_scaler(dev_priv, plane,
-					   crtc_state, plane_state);
+			skl_program_scaler(plane, crtc_state, plane_state);
 
 		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
 	} else {
-- 
2.18.1

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

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

* [PATCH 03/14] drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler()
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
  2018-11-01 15:05 ` [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs Ville Syrjala
  2018-11-01 15:05 ` [PATCH 02/14] drm/i915: Clean up skl_program_scaler() Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-07 18:53   ` Rodrigo Vivi
  2018-11-01 15:05 ` [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup Ville Syrjala
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

If we don't need the PS_PWR_GATE write when programming the
pipe scaler I don't see why we'd need it for plane scalers either.
Just remove it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index a1e215636331..399d44c57a7d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -354,7 +354,6 @@ skl_program_scaler(struct intel_plane *plane,
 
 	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
 		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
-	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
 	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
 		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
 	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
-- 
2.18.1

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

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

* [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (2 preceding siblings ...)
  2018-11-01 15:05 ` [PATCH 03/14] drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler() Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-07 18:41   ` [PATCH v2 " Ville Syrjala
  2018-11-07 19:55   ` [PATCH " Rodrigo Vivi
  2018-11-01 15:05 ` [PATCH 05/14] drm/i915: Clean up skl+ PLANE_POS vs. scaler handling Ville Syrjala
                   ` (15 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

Due to the constant alpha we're going to have to program two of
the the tree keying registers anyway, so might as well always
program all three.

And parametrize the plane constant alpha define while at it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h     |  2 +-
 drivers/gpu/drm/i915/intel_sprite.c | 22 +++++++++-------------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8d089ef848b2..b6ee863b5df2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6545,7 +6545,7 @@ enum {
 #define  PLANE_KEYMSK_ALPHA_ENABLE		(1 << 31)
 #define _PLANE_KEYMAX_1_A			0x701a0
 #define _PLANE_KEYMAX_2_A			0x702a0
-#define  PLANE_KEYMAX_ALPHA_SHIFT		24
+#define  PLANE_KEYMAX_ALPHA(a)			((a) << 24)
 #define _PLANE_AUX_DIST_1_A			0x701c0
 #define _PLANE_AUX_DIST_2_A			0x702c0
 #define _PLANE_AUX_OFFSET_1_A			0x701c4
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 399d44c57a7d..b36238282b4e 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -382,31 +382,27 @@ skl_program_plane(struct intel_plane *plane,
 	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
 	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
 	struct intel_plane *linked = plane_state->linked_plane;
+	u8 alpha = plane_state->base.alpha >> 8;
 	unsigned long irqflags;
-	u32 keymsk = 0, keymax = 0;
+	u32 keymsk, keymax;
 
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
 
+	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
+
+	keymsk = key->channel_mask & 0x3ffffff;
+	if (alpha < 0xff)
+		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
+
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
 			      plane_state->color_ctl);
 
-	if (key->flags) {
-		I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
-
-		keymax |= key->max_value & 0xffffff;
-		keymsk |= key->channel_mask & 0x3ffffff;
-	}
-
-	keymax |= (plane_state->base.alpha >> 8) << PLANE_KEYMAX_ALPHA_SHIFT;
-
-	if (plane_state->base.alpha < 0xff00)
-		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
-
+	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
 	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
 	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
 
-- 
2.18.1

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

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

* [PATCH 05/14] drm/i915: Clean up skl+ PLANE_POS vs. scaler handling
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (3 preceding siblings ...)
  2018-11-01 15:05 ` [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-07 19:56   ` Rodrigo Vivi
  2018-11-01 15:05 ` [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic Ville Syrjala
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

On skl+ the scaler (when enabled) will take care of the plane output
position. Make the code less ugly by just setting crtc_x/y to 0
when the scaler is enabled.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b36238282b4e..8a40879abe30 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -396,6 +396,12 @@ skl_program_plane(struct intel_plane *plane,
 	if (alpha < 0xff)
 		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
 
+	/* The scaler will handle the output position */
+	if (plane_state->scaler_id >= 0) {
+		crtc_x = 0;
+		crtc_y = 0;
+	}
+
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
@@ -438,14 +444,10 @@ skl_program_plane(struct intel_plane *plane,
 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
 	}
 
-	if (plane_state->scaler_id >= 0) {
-		if (!slave)
-			skl_program_scaler(plane, crtc_state, plane_state);
+	if (!slave && plane_state->scaler_id >= 0)
+		skl_program_scaler(plane, crtc_state, plane_state);
 
-		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
-	} else {
-		I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
-	}
+	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
 
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
-- 
2.18.1

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

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

* [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (4 preceding siblings ...)
  2018-11-01 15:05 ` [PATCH 05/14] drm/i915: Clean up skl+ PLANE_POS vs. scaler handling Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-07 18:42   ` [PATCH v2 " Ville Syrjala
  2018-11-07 21:26   ` [PATCH " Rodrigo Vivi
  2018-11-01 15:05 ` [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end Ville Syrjala
                   ` (13 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

Some observations about the plane registers:
- the control register will self-arm if the plane is not already
  enabled, thus we want to write it as close to (or ideally after)
  the surface register
- tileoff/linoff/offset/aux_offset are self-arming as well so we want
  them close to the surface register as well
- color keying registers we maybe self arming before SKL. Not 100%
  sure but we can try to keep them near to the surface register
  as well
- chv pipe b csc register are double buffered but self arming so
  moving them down a bit
- the rest should be mostly armed by the surface register so we can
  safely write them first, and to just for some consistency let's try
  to follow keep them in order based on the register offset

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  40 +++++-----
 drivers/gpu/drm/i915/intel_sprite.c  | 114 +++++++++++++++------------
 2 files changed, 86 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c5ce3892d583..9521cff5fb44 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3328,7 +3328,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
 	u32 linear_offset;
 	u32 dspcntr = plane_state->ctl;
-	i915_reg_t reg = DSPCNTR(i9xx_plane);
 	int x = plane_state->color_plane[0].x;
 	int y = plane_state->color_plane[0].y;
 	unsigned long irqflags;
@@ -3343,41 +3342,45 @@ static void i9xx_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
+
 	if (INTEL_GEN(dev_priv) < 4) {
 		/* pipesrc and dspsize control the size that is scaled from,
 		 * which should always be the user's requested size.
 		 */
+		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
 		I915_WRITE_FW(DSPSIZE(i9xx_plane),
 			      ((crtc_state->pipe_src_h - 1) << 16) |
 			      (crtc_state->pipe_src_w - 1));
-		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
 	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
+		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
 		I915_WRITE_FW(PRIMSIZE(i9xx_plane),
 			      ((crtc_state->pipe_src_h - 1) << 16) |
 			      (crtc_state->pipe_src_w - 1));
-		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
 		I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
 	}
 
-	I915_WRITE_FW(reg, dspcntr);
-
-	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
-		I915_WRITE_FW(DSPSURF(i9xx_plane),
-			      intel_plane_ggtt_offset(plane_state) +
-			      dspaddr_offset);
 		I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
 	} else if (INTEL_GEN(dev_priv) >= 4) {
+		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
+		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
+	}
+
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
+	I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
+	if (INTEL_GEN(dev_priv) >= 4)
 		I915_WRITE_FW(DSPSURF(i9xx_plane),
 			      intel_plane_ggtt_offset(plane_state) +
 			      dspaddr_offset);
-		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
-		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
-	} else {
+	else
 		I915_WRITE_FW(DSPADDR(i9xx_plane),
 			      intel_plane_ggtt_offset(plane_state) +
 			      dspaddr_offset);
-	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -10045,8 +10048,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	 * On some platforms writing CURCNTR first will also
 	 * cause CURPOS to be armed by the CURBASE write.
 	 * Without the CURCNTR write the CURPOS write would
-	 * arm itself. Thus we always start the full update
-	 * with a CURCNTR write.
+	 * arm itself. Thus we always update CURCNTR before
+	 * CURPOS.
 	 *
 	 * On other platforms CURPOS always requires the
 	 * CURBASE write to arm the update. Additonally
@@ -10056,15 +10059,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	 * cursor that doesn't appear to move, or even change
 	 * shape. Thus we always write CURBASE.
 	 *
-	 * CURCNTR and CUR_FBC_CTL are always
-	 * armed by the CURBASE write only.
+	 * The other registers are armed by by the CURBASE write
+	 * except when the plane is getting enabled at which time
+	 * the CURCNTR write arms the update.
 	 */
 	if (plane->cursor.base != base ||
 	    plane->cursor.size != fbc_ctl ||
 	    plane->cursor.cntl != cntl) {
-		I915_WRITE_FW(CURCNTR(pipe), cntl);
 		if (HAS_CUR_FBC(dev_priv))
 			I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
+		I915_WRITE_FW(CURCNTR(pipe), cntl);
 		I915_WRITE_FW(CURPOS(pipe), pos);
 		I915_WRITE_FW(CURBASE(pipe), base);
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 8a40879abe30..455b2d0cbaa6 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -404,24 +404,12 @@ skl_program_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
-	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
-		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
-			      plane_state->color_ctl);
-
-	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
-	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
-	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
-
-	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
 	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
+	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
 	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
 	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
-		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
-
-	if (INTEL_GEN(dev_priv) < 11)
-		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
-			      (plane_state->color_plane[1].y << 16) |
-			       plane_state->color_plane[1].x);
+		      (plane_state->color_plane[1].offset - surf_addr) |
+		      aux_stride);
 
 	if (icl_is_hdr_plane(plane)) {
 		u32 cus_ctl = 0;
@@ -444,15 +432,33 @@ skl_program_plane(struct intel_plane *plane,
 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
 	}
 
-	if (!slave && plane_state->scaler_id >= 0)
-		skl_program_scaler(plane, crtc_state, plane_state);
+	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
+			      plane_state->color_ctl);
 
-	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
+	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
+	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
+
+	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
 
+	if (INTEL_GEN(dev_priv) < 11)
+		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+			      (plane_state->color_plane[1].y << 16) |
+			      plane_state->color_plane[1].x);
+
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + surf_addr);
 
+	if (!slave && plane_state->scaler_id >= 0)
+		skl_program_scaler(plane, crtc_state, plane_state);
+
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -690,7 +696,6 @@ vlv_update_plane(struct intel_plane *plane,
 		 const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	enum plane_id plane_id = plane->id;
 	u32 sprctl = plane_state->ctl;
@@ -715,6 +720,12 @@ vlv_update_plane(struct intel_plane *plane,
 
 	vlv_update_clrc(plane_state);
 
+	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
+		      plane_state->color_plane[0].stride);
+	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
+	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
+
 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
 		chv_update_csc(plane_state);
 
@@ -723,18 +734,15 @@ vlv_update_plane(struct intel_plane *plane,
 		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
 		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
 	}
-	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
-		      plane_state->color_plane[0].stride);
-	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
-
-	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
-		I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
-	else
-		I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
 
-	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
+	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
+	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
 
-	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
 	I915_WRITE_FW(SPSURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
@@ -848,7 +856,6 @@ ivb_update_plane(struct intel_plane *plane,
 		 const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	u32 sprctl = plane_state->ctl, sprscale = 0;
 	u32 sprsurf_offset = plane_state->color_plane[0].offset;
@@ -877,27 +884,32 @@ ivb_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
+	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
+	if (IS_IVYBRIDGE(dev_priv))
+		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
+
 	if (key->flags) {
 		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
 		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
 		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
 	}
 
-	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
-	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
-
 	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
 	 * register */
-	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
 		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
-	else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
+	} else {
 		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
-	else
 		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
+	}
 
-	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
-	if (IS_IVYBRIDGE(dev_priv))
-		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(SPRCTL(pipe), sprctl);
 	I915_WRITE_FW(SPRSURF(pipe),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
@@ -915,7 +927,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	I915_WRITE_FW(SPRCTL(pipe), 0);
-	/* Can't leave the scaler enabled... */
+	/* Disable the scaler */
 	if (IS_IVYBRIDGE(dev_priv))
 		I915_WRITE_FW(SPRSCALE(pipe), 0);
 	I915_WRITE_FW(SPRSURF(pipe), 0);
@@ -1017,7 +1029,6 @@ g4x_update_plane(struct intel_plane *plane,
 		 const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	u32 dvscntr = plane_state->ctl, dvsscale = 0;
 	u32 dvssurf_offset = plane_state->color_plane[0].offset;
@@ -1046,22 +1057,25 @@ g4x_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
+	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
+	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
+
 	if (key->flags) {
 		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
 		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
 		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
 	}
 
-	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
-	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
-
-	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
-		I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
-	else
-		I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
+	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
+	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
 
-	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
-	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
 	I915_WRITE_FW(DVSSURF(pipe),
 		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
-- 
2.18.1

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

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

* [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (5 preceding siblings ...)
  2018-11-01 15:05 ` [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-07 21:26   ` Rodrigo Vivi
  2018-11-08 22:06   ` Matt Roper
  2018-11-01 15:05 ` [PATCH 08/14] drm/i915: Generalize skl_ddb_allocation_overlaps() Ville Syrjala
                   ` (12 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

The plane color correction registers are single buffered. So
ideally we would write them at the start of vblank just after the
double buffered plane registers have been latched. Since we have
no convenient way to do that for now let's at least move the
single buffered register writes to happen after the double
buffered registers have been written.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 455b2d0cbaa6..84c5f532fba5 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -718,8 +718,6 @@ vlv_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
-	vlv_update_clrc(plane_state);
-
 	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
 		      plane_state->color_plane[0].stride);
 	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
@@ -747,6 +745,8 @@ vlv_update_plane(struct intel_plane *plane,
 	I915_WRITE_FW(SPSURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
 
+	vlv_update_clrc(plane_state);
+
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
-- 
2.18.1

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

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

* [PATCH 08/14] drm/i915: Generalize skl_ddb_allocation_overlaps()
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (6 preceding siblings ...)
  2018-11-01 15:05 ` [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end Ville Syrjala
@ 2018-11-01 15:05 ` Ville Syrjala
  2018-11-07 21:28   ` Rodrigo Vivi
  2018-11-01 15:06 ` [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask Ville Syrjala
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:05 UTC (permalink / raw)
  To: intel-gfx

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

Make skl_ddb_allocation_overlaps() useful for other callers
besides skl_update_crtcs(). We'll need it to do plane updates
as well.

And while we're here we can reduce the stack utilization a
bit by noting that each struct skl_ddb_entry is 4 bytes whereas
a pointer to one is 8 bytes (on 64bit). So we'll switch to an
array of structs from the array of pointers we used before.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 12 +++++-------
 drivers/gpu/drm/i915/intel_drv.h     |  7 +++----
 drivers/gpu/drm/i915/intel_pm.c      | 15 +++++++--------
 3 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9521cff5fb44..852b5897e80b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12678,13 +12678,12 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
 	int i;
 	u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
 	u8 required_slices = intel_state->wm_results.ddb.enabled_slices;
-
-	const struct skl_ddb_entry *entries[I915_MAX_PIPES] = {};
+	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
 
 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
 		/* ignore allocations for crtc's that have been turned off. */
 		if (new_crtc_state->active)
-			entries[i] = &to_intel_crtc_state(old_crtc_state)->wm.skl.ddb;
+			entries[i] = to_intel_crtc_state(old_crtc_state)->wm.skl.ddb;
 
 	/* If 2nd DBuf slice required, enable it here */
 	if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices)
@@ -12710,14 +12709,13 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
 			if (updated & cmask || !cstate->base.active)
 				continue;
 
-			if (skl_ddb_allocation_overlaps(dev_priv,
+			if (skl_ddb_allocation_overlaps(&cstate->wm.skl.ddb,
 							entries,
-							&cstate->wm.skl.ddb,
-							i))
+							INTEL_INFO(dev_priv)->num_pipes, i))
 				continue;
 
 			updated |= cmask;
-			entries[i] = &cstate->wm.skl.ddb;
+			entries[i] = cstate->wm.skl.ddb;
 
 			/*
 			 * If this is an already active pipe, it's DDB changed,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c5acc5f0d518..5331bbed5e8c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2182,10 +2182,9 @@ int intel_enable_sagv(struct drm_i915_private *dev_priv);
 int intel_disable_sagv(struct drm_i915_private *dev_priv);
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
 			 const struct skl_wm_level *l2);
-bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv,
-				 const struct skl_ddb_entry **entries,
-				 const struct skl_ddb_entry *ddb,
-				 int ignore);
+bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
+				 const struct skl_ddb_entry entries[],
+				 int num_entries, int ignore_idx);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 				  struct intel_crtc_state *cstate);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 82c82e233154..6fa1634e2db5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5197,16 +5197,15 @@ static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a,
 	return a->start < b->end && b->start < a->end;
 }
 
-bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv,
-				 const struct skl_ddb_entry **entries,
-				 const struct skl_ddb_entry *ddb,
-				 int ignore)
+bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
+				 const struct skl_ddb_entry entries[],
+				 int num_entries, int ignore_idx)
 {
-	enum pipe pipe;
+	int i;
 
-	for_each_pipe(dev_priv, pipe) {
-		if (pipe != ignore && entries[pipe] &&
-		    skl_ddb_entries_overlap(ddb, entries[pipe]))
+	for (i = 0; i < num_entries; i++) {
+		if (i != ignore_idx &&
+		    skl_ddb_entries_overlap(ddb, &entries[i]))
 			return true;
 	}
 
-- 
2.18.1

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

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

* [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (7 preceding siblings ...)
  2018-11-01 15:05 ` [PATCH 08/14] drm/i915: Generalize skl_ddb_allocation_overlaps() Ville Syrjala
@ 2018-11-01 15:06 ` Ville Syrjala
  2018-11-07 21:49   ` Rodrigo Vivi
  2018-11-08 23:22   ` Matt Roper
  2018-11-01 15:06 ` [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane() Ville Syrjala
                   ` (10 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:06 UTC (permalink / raw)
  To: intel-gfx

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

Keep track which planes need updating during the commit. For now this
is just (was_visible || is_visible) but I'll have need to update
invisible planes later on for skl plane ddbs and for pre-skl pipe
gamma/csc control (which lives in the primary plane control register).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c       | 1 +
 drivers/gpu/drm/i915/intel_atomic_plane.c | 8 ++++----
 drivers/gpu/drm/i915/intel_display.c      | 5 ++++-
 drivers/gpu/drm/i915/intel_drv.h          | 3 +++
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index a5a2c8fe58a7..8cb02f28d30c 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -184,6 +184,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	crtc_state->fifo_changed = false;
 	crtc_state->wm.need_postvbl_update = false;
 	crtc_state->fb_bits = 0;
+	crtc_state->update_planes = 0;
 
 	return &crtc_state->base;
 }
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 7d3685075201..010269a12390 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -137,6 +137,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 	if (state->visible && state->fb->format->format == DRM_FORMAT_NV12)
 		crtc_state->nv12_planes |= BIT(intel_plane->id);
 
+	if (state->visible || old_plane_state->base.visible)
+		crtc_state->update_planes |= BIT(intel_plane->id);
+
 	return intel_plane_atomic_calc_changes(old_crtc_state,
 					       &crtc_state->base,
 					       old_plane_state,
@@ -171,14 +174,11 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
 				 struct intel_crtc_state *old_crtc_state,
 				 struct intel_crtc_state *new_crtc_state)
 {
+	u32 update_mask = new_crtc_state->update_planes;
 	struct intel_plane_state *new_plane_state;
 	struct intel_plane *plane;
-	u32 update_mask;
 	int i;
 
-	update_mask = old_crtc_state->active_planes;
-	update_mask |= new_crtc_state->active_planes;
-
 	for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) {
 		if (crtc->pipe != plane->pipe ||
 		    !(update_mask & BIT(plane->id)))
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 852b5897e80b..33d73915b73e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10797,8 +10797,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 			continue;
 
 		plane_state->linked_plane = NULL;
-		if (plane_state->slave && !plane_state->base.visible)
+		if (plane_state->slave && !plane_state->base.visible) {
 			crtc_state->active_planes &= ~BIT(plane->id);
+			crtc_state->update_planes |= BIT(plane->id);
+		}
 
 		plane_state->slave = false;
 	}
@@ -10839,6 +10841,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 		linked_state->slave = true;
 		linked_state->linked_plane = plane;
 		crtc_state->active_planes |= BIT(linked->id);
+		crtc_state->update_planes |= BIT(linked->id);
 		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5331bbed5e8c..7a55f5921d34 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -925,6 +925,9 @@ struct intel_crtc_state {
 	u8 active_planes;
 	u8 nv12_planes;
 
+	/* bitmask of planes that will be updated during the commit */
+	u8 update_planes;
+
 	/* HDMI scrambling status */
 	bool hdmi_scrambling;
 
-- 
2.18.1

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

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

* [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane()
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (8 preceding siblings ...)
  2018-11-01 15:06 ` [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask Ville Syrjala
@ 2018-11-01 15:06 ` Ville Syrjala
  2018-11-07 22:08   ` Rodrigo Vivi
  2018-11-08 23:52   ` Matt Roper
  2018-11-01 15:06 ` [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+ Ville Syrjala
                   ` (9 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:06 UTC (permalink / raw)
  To: intel-gfx

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

We're going to need access to the new crtc state in ->disable_plane()
for SKL+ wm/ddb programming and pre-skl pipe gamma/csc control. Pass
the crtc state down.

We'll also try to make intel_crtc_disable_planes() drtr as much as
it's possible. The fact that we don't have a separate crtc state
for the disabled state when we're going to re-enable the crtc later
means we might end up poking at a few extra planes in there. But
that's harmless. I suppose one migth argue that we wouldn't have to
care about proper ddb/wm/csc/gamma if the pipe is going to permanently
disable anyway, but the state checker probably cares so we should try
our best to make sure everything is programmed correctly even in that
case.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c |  2 +-
 drivers/gpu/drm/i915/intel_display.c      | 39 ++++++++++++++---------
 drivers/gpu/drm/i915/intel_display.h      |  8 +++++
 drivers/gpu/drm/i915/intel_drv.h          |  2 +-
 drivers/gpu/drm/i915/intel_sprite.c       | 12 ++++---
 5 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 010269a12390..69fc7010190c 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -210,7 +210,7 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
 		} else {
 			trace_intel_disable_plane(&plane->base, crtc);
 
-			plane->disable_plane(plane, crtc);
+			plane->disable_plane(plane, new_crtc_state);
 		}
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 33d73915b73e..6088ae554e56 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2781,7 +2781,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
 		intel_pre_disable_primary_noatomic(&crtc->base);
 
 	trace_intel_disable_plane(&plane->base, crtc);
-	plane->disable_plane(plane, crtc);
+	plane->disable_plane(plane, crtc_state);
 }
 
 static void
@@ -3386,7 +3386,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
 }
 
 static void i9xx_disable_plane(struct intel_plane *plane,
-			       struct intel_crtc *crtc)
+			       const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
@@ -5421,23 +5421,32 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
 		intel_update_watermarks(crtc);
 }
 
-static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask)
+static void intel_crtc_disable_planes(struct intel_atomic_state *state,
+				      struct intel_crtc *crtc)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	const struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	unsigned int update_mask = new_crtc_state->update_planes;
+	const struct intel_plane_state *old_plane_state;
 	struct intel_plane *plane;
 	unsigned fb_bits = 0;
+	int i;
 
 	intel_crtc_dpms_overlay_disable(crtc);
 
-	for_each_intel_plane_on_crtc(dev, crtc, plane) {
-		if (plane_mask & BIT(plane->id)) {
-			plane->disable_plane(plane, crtc);
+	for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
+		if (crtc->pipe != plane->pipe ||
+		    !(update_mask & BIT(plane->id)))
+			continue;
+
+		plane->disable_plane(plane, new_crtc_state);
 
+		if (old_plane_state->base.visible)
 			fb_bits |= plane->frontbuffer_bit;
-		}
 	}
 
-	intel_frontbuffer_flip(to_i915(dev), fb_bits);
+	intel_frontbuffer_flip(dev_priv, fb_bits);
 }
 
 static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc,
@@ -9855,9 +9864,9 @@ static void i845_update_cursor(struct intel_plane *plane,
 }
 
 static void i845_disable_cursor(struct intel_plane *plane,
-				struct intel_crtc *crtc)
+				const struct intel_crtc_state *crtc_state)
 {
-	i845_update_cursor(plane, NULL, NULL);
+	i845_update_cursor(plane, crtc_state, NULL);
 }
 
 static bool i845_cursor_get_hw_state(struct intel_plane *plane,
@@ -10084,9 +10093,9 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 }
 
 static void i9xx_disable_cursor(struct intel_plane *plane,
-				struct intel_crtc *crtc)
+				const struct intel_crtc_state *crtc_state)
 {
-	i9xx_update_cursor(plane, NULL, NULL);
+	i9xx_update_cursor(plane, crtc_state, NULL);
 }
 
 static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
@@ -12840,7 +12849,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 		intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state);
 
 		if (old_crtc_state->active) {
-			intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes);
+			intel_crtc_disable_planes(intel_state, intel_crtc);
 
 			/*
 			 * We need to disable pipe CRC before disabling the pipe,
@@ -13695,7 +13704,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 					  to_intel_plane_state(plane->state));
 	} else {
 		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
-		intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
+		intel_plane->disable_plane(intel_plane, crtc_state);
 	}
 
 	intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index 5d50decbcbb5..df9e6ebb27de 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -382,6 +382,14 @@ struct intel_link_m_n {
 	for_each_power_well_rev(__dev_priv, __power_well)		        \
 		for_each_if((__power_well)->desc->domains & (__domain_mask))
 
+#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
+		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
+		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
+	     (__i)++) \
+		for_each_if(plane)
+
 #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \
 	for ((__i) = 0; \
 	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7a55f5921d34..facd5cb0b540 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1015,7 +1015,7 @@ struct intel_plane {
 			     const struct intel_crtc_state *crtc_state,
 			     const struct intel_plane_state *plane_state);
 	void (*disable_plane)(struct intel_plane *plane,
-			      struct intel_crtc *crtc);
+			      const struct intel_crtc_state *crtc_state);
 	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
 	int (*check_plane)(struct intel_crtc_state *crtc_state,
 			   struct intel_plane_state *plane_state);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 84c5f532fba5..2f97a298c24e 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -488,7 +488,8 @@ icl_update_slave(struct intel_plane *plane,
 }
 
 static void
-skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
+skl_disable_plane(struct intel_plane *plane,
+		  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum plane_id plane_id = plane->id;
@@ -751,7 +752,8 @@ vlv_update_plane(struct intel_plane *plane,
 }
 
 static void
-vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
+vlv_disable_plane(struct intel_plane *plane,
+		  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
@@ -918,7 +920,8 @@ ivb_update_plane(struct intel_plane *plane,
 }
 
 static void
-ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
+ivb_disable_plane(struct intel_plane *plane,
+		  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
@@ -1084,7 +1087,8 @@ g4x_update_plane(struct intel_plane *plane,
 }
 
 static void
-g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
+g4x_disable_plane(struct intel_plane *plane,
+		  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
-- 
2.18.1

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

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

* [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (9 preceding siblings ...)
  2018-11-01 15:06 ` [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane() Ville Syrjala
@ 2018-11-01 15:06 ` Ville Syrjala
  2018-11-07 22:09   ` Rodrigo Vivi
  2018-11-09  0:01   ` Matt Roper
  2018-11-01 15:06 ` [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations Ville Syrjala
                   ` (8 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:06 UTC (permalink / raw)
  To: intel-gfx

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

If the level 0 latency is 0 we can't do anything. Return an error
rather than success.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6fa1634e2db5..bd5f16bc7e08 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4703,8 +4703,10 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
 	uint32_t min_disp_buf_needed;
 
-	if (latency == 0 ||
-	    !intel_wm_plane_visible(cstate, intel_pstate)) {
+	if (latency == 0)
+		return level == 0 ? -EINVAL : 0;
+
+	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
 		result->plane_en = false;
 		return 0;
 	}
-- 
2.18.1

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

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

* [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (10 preceding siblings ...)
  2018-11-01 15:06 ` [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+ Ville Syrjala
@ 2018-11-01 15:06 ` Ville Syrjala
  2018-11-07 18:43   ` [PATCH v2 " Ville Syrjala
  2018-11-07 22:11   ` [PATCH " Rodrigo Vivi
  2018-11-01 15:06 ` [PATCH 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+ Ville Syrjala
                   ` (7 subsequent siblings)
  19 siblings, 2 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:06 UTC (permalink / raw)
  To: intel-gfx

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

We memset(0) the entire watermark struct the start, so there's no
need to clear things later on.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index bd5f16bc7e08..b0720994fa0a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4706,10 +4706,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if (latency == 0)
 		return level == 0 ? -EINVAL : 0;
 
-	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
-		result->plane_en = false;
+	if (!intel_wm_plane_visible(cstate, intel_pstate))
 		return 0;
-	}
 
 	/* Display WA #1141: kbl,cfl */
 	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
@@ -4806,8 +4804,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if ((level > 0 && res_lines > 31) ||
 	    res_blocks >= ddb_allocation ||
 	    min_disp_buf_needed >= ddb_allocation) {
-		result->plane_en = false;
-
 		/*
 		 * If there are no valid level 0 watermarks, then we can't
 		 * support this display configuration.
@@ -4831,10 +4827,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	 */
 	if (wp->is_planar && level >= 1 &&
 	    (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) ||
-	     IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) {
-		result->plane_en = false;
+	     IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0)))
 		return 0;
-	}
 
 	/* The number of lines are ignored for the level 0 watermark. */
 	result->plane_res_b = res_blocks;
@@ -4920,15 +4914,15 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
 
 	if (!cstate->base.active)
-		goto exit;
+		return;
 
 	/* Transition WM are not recommended by HW team for GEN9 */
 	if (INTEL_GEN(dev_priv) <= 9)
-		goto exit;
+		return;
 
 	/* Transition WM don't make any sense if ipc is disabled */
 	if (!dev_priv->ipc_enabled)
-		goto exit;
+		return;
 
 	trans_min = 14;
 	if (INTEL_GEN(dev_priv) >= 11)
@@ -4967,11 +4961,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	if (res_blocks < ddb_allocation) {
 		trans_wm->plane_res_b = res_blocks;
 		trans_wm->plane_en = true;
-		return;
 	}
-
-exit:
-	trans_wm->plane_en = false;
 }
 
 static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
-- 
2.18.1

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

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

* [PATCH 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (11 preceding siblings ...)
  2018-11-01 15:06 ` [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations Ville Syrjala
@ 2018-11-01 15:06 ` Ville Syrjala
  2018-11-07 18:44   ` [PATCH v2 " Ville Syrjala
  2018-11-01 15:06 ` [PATCH 14/14] drm/i915: Commit skl+ planes in an order that avoids ddb overlaps Ville Syrjala
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:06 UTC (permalink / raw)
  To: intel-gfx

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

On SKL+ the plane WM/BUF_CFG registers are a proper part of each
plane's register set. That means accessing them will cancel any
pending plane update, and we would need a PLANE_SURF register write
to arm the wm/ddb change as well.

To avoid all the problems with that let's just move the wm/ddb
programming into the plane update/disable hooks. Now all plane
registers get written in one (hopefully atomic) operation.

To make that feasible we'll move the plane ddb tracking into
the crtc state. Watermarks were already tracked there.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  21 +-
 drivers/gpu/drm/i915/i915_drv.h      |   3 -
 drivers/gpu/drm/i915/intel_display.c |  16 +-
 drivers/gpu/drm/i915/intel_display.h |  11 +-
 drivers/gpu/drm/i915/intel_drv.h     |   9 +
 drivers/gpu/drm/i915/intel_pm.c      | 450 ++++++++++++---------------
 drivers/gpu/drm/i915/intel_sprite.c  |   4 +
 7 files changed, 250 insertions(+), 264 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 041319d48ca3..4fde18422839 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3436,31 +3436,32 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
 	struct drm_device *dev = &dev_priv->drm;
-	struct skl_ddb_allocation *ddb;
 	struct skl_ddb_entry *entry;
-	enum pipe pipe;
-	int plane;
+	struct intel_crtc *crtc;
 
 	if (INTEL_GEN(dev_priv) < 9)
 		return -ENODEV;
 
 	drm_modeset_lock_all(dev);
 
-	ddb = &dev_priv->wm.skl_hw.ddb;
-
 	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
 
-	for_each_pipe(dev_priv, pipe) {
+	for_each_intel_crtc(&dev_priv->drm, crtc) {
+		struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+		enum pipe pipe = crtc->pipe;
+		enum plane_id plane_id;
+
 		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
 
-		for_each_universal_plane(dev_priv, pipe, plane) {
-			entry = &ddb->plane[pipe][plane];
-			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
+		for_each_plane_id_on_crtc(crtc, plane_id) {
+			entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
+			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
 				   entry->start, entry->end,
 				   skl_ddb_entry_size(entry));
 		}
 
-		entry = &ddb->plane[pipe][PLANE_CURSOR];
+		entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
 		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 c9e5bab6861b..4ed37ee23aac 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1231,9 +1231,6 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
 }
 
 struct skl_ddb_allocation {
-	/* packed/y */
-	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
-	struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
 	u8 enabled_slices; /* GEN11 has configurable 2 slices */
 };
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6088ae554e56..6905a267a13f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10072,6 +10072,10 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	 * except when the plane is getting enabled at which time
 	 * the CURCNTR write arms the update.
 	 */
+
+	if (INTEL_GEN(dev_priv) >= 9)
+		skl_write_cursor_wm(plane, crtc_state);
+
 	if (plane->cursor.base != base ||
 	    plane->cursor.size != fbc_ctl ||
 	    plane->cursor.cntl != cntl) {
@@ -11853,6 +11857,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 	struct skl_pipe_wm hw_wm, *sw_wm;
 	struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
 	struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
+	struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES];
+	struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES];
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	const enum pipe pipe = intel_crtc->pipe;
 	int plane, level, max_level = ilk_wm_max_level(dev_priv);
@@ -11863,6 +11869,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 	skl_pipe_wm_get_hw_state(crtc, &hw_wm);
 	sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal;
 
+	skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv);
+
 	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
 	sw_ddb = &dev_priv->wm.skl_hw.ddb;
 
@@ -11905,8 +11913,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 		}
 
 		/* DDB */
-		hw_ddb_entry = &hw_ddb.plane[pipe][plane];
-		sw_ddb_entry = &sw_ddb->plane[pipe][plane];
+		hw_ddb_entry = &hw_ddb_y[plane];
+		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane];
 
 		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
 			DRM_ERROR("mismatch in DDB state pipe %c plane %d (expected (%u,%u), found (%u,%u))\n",
@@ -11955,8 +11963,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 		}
 
 		/* DDB */
-		hw_ddb_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
-		sw_ddb_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+		hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR];
+		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR];
 
 		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
 			DRM_ERROR("mismatch in DDB state pipe %c cursor (expected (%u,%u), found (%u,%u))\n",
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index df9e6ebb27de..078406dc65e5 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -319,7 +319,7 @@ struct intel_link_m_n {
 			    &(dev)->mode_config.plane_list,		\
 			    base.head)					\
 		for_each_if((plane_mask) &				\
-			    drm_plane_mask(&intel_plane->base)))
+			    drm_plane_mask(&intel_plane->base))
 
 #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
 	list_for_each_entry(intel_plane,				\
@@ -415,6 +415,15 @@ struct intel_link_m_n {
 	     (__i)++) \
 		for_each_if(plane)
 
+#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
+		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
+		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
+		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
+	     (__i)++) \
+		for_each_if(crtc)
+
 void intel_link_compute_m_n(int bpp, int nlanes,
 			    int pixel_clock, int link_clock,
 			    struct intel_link_m_n *m_n,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index facd5cb0b540..8a93e0e8c89d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -705,6 +705,8 @@ struct intel_crtc_wm_state {
 			/* gen9+ only needs 1-step wm programming */
 			struct skl_pipe_wm optimal;
 			struct skl_ddb_entry ddb;
+			struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
+			struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES];
 		} skl;
 
 		struct {
@@ -2174,6 +2176,9 @@ void g4x_wm_get_hw_state(struct drm_device *dev);
 void vlv_wm_get_hw_state(struct drm_device *dev);
 void ilk_wm_get_hw_state(struct drm_device *dev);
 void skl_wm_get_hw_state(struct drm_device *dev);
+void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
+			       struct skl_ddb_entry *ddb_y,
+			       struct skl_ddb_entry *ddb_uv);
 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
 			  struct skl_ddb_allocation *ddb /* out */);
 void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
@@ -2188,6 +2193,10 @@ bool skl_wm_level_equals(const struct skl_wm_level *l1,
 bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
 				 const struct skl_ddb_entry entries[],
 				 int num_entries, int ignore_idx);
+void skl_write_plane_wm(struct intel_plane *plane,
+			const struct intel_crtc_state *crtc_state);
+void skl_write_cursor_wm(struct intel_plane *plane,
+			 const struct intel_crtc_state *crtc_state);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 				  struct intel_crtc_state *cstate);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b0720994fa0a..4c778bc153fa 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3911,68 +3911,70 @@ static void
 skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
 			   const enum pipe pipe,
 			   const enum plane_id plane_id,
-			   struct skl_ddb_allocation *ddb /* out */)
+			   struct skl_ddb_entry *ddb_y,
+			   struct skl_ddb_entry *ddb_uv)
 {
-	u32 val, val2 = 0;
-	int fourcc, pixel_format;
+	u32 val, val2;
+	u32 fourcc = 0;
 
 	/* Cursor doesn't support NV12/planar, so no extra calculation needed */
 	if (plane_id == PLANE_CURSOR) {
 		val = I915_READ(CUR_BUF_CFG(pipe));
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->plane[pipe][plane_id], val);
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
 		return;
 	}
 
 	val = I915_READ(PLANE_CTL(pipe, plane_id));
 
 	/* No DDB allocated for disabled planes */
-	if (!(val & PLANE_CTL_ENABLE))
-		return;
-
-	pixel_format = val & PLANE_CTL_FORMAT_MASK;
-	fourcc = skl_format_to_fourcc(pixel_format,
-				      val & PLANE_CTL_ORDER_RGBX,
-				      val & PLANE_CTL_ALPHA_MASK);
+	if (val & PLANE_CTL_ENABLE)
+		fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK,
+					      val & PLANE_CTL_ORDER_RGBX,
+					      val & PLANE_CTL_ALPHA_MASK);
 
-	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
-	if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) {
+	if (INTEL_GEN(dev_priv) >= 11) {
+		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
+	} else {
+		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
 		val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
 
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->plane[pipe][plane_id], val2);
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->uv_plane[pipe][plane_id], val);
-	} else {
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->plane[pipe][plane_id], val);
+		if (fourcc == DRM_FORMAT_NV12)
+			swap(val, val2);
+
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_uv, val2);
 	}
 }
 
-void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
-			  struct skl_ddb_allocation *ddb /* out */)
+void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
+			       struct skl_ddb_entry *ddb_y,
+			       struct skl_ddb_entry *ddb_uv)
 {
-	struct intel_crtc *crtc;
-
-	memset(ddb, 0, sizeof(*ddb));
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum intel_display_power_domain power_domain;
+	enum pipe pipe = crtc->pipe;
+	enum plane_id plane_id;
 
-	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
+	power_domain = POWER_DOMAIN_PIPE(pipe);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return;
 
-	for_each_intel_crtc(&dev_priv->drm, crtc) {
-		enum intel_display_power_domain power_domain;
-		enum plane_id plane_id;
-		enum pipe pipe = crtc->pipe;
+	for_each_plane_id_on_crtc(crtc, plane_id)
+		skl_ddb_get_hw_plane_state(dev_priv, pipe,
+					   plane_id,
+					   &ddb_y[plane_id],
+					   &ddb_uv[plane_id]);
 
-		power_domain = POWER_DOMAIN_PIPE(pipe);
-		if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
-			continue;
+	intel_display_power_put(dev_priv, power_domain);
+}
 
-		for_each_plane_id_on_crtc(crtc, plane_id)
-			skl_ddb_get_hw_plane_state(dev_priv, pipe,
-						   plane_id, ddb);
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+			  struct skl_ddb_allocation *ddb /* out */)
+{
+	memset(ddb, 0, sizeof(*ddb));
 
-		intel_display_power_put(dev_priv, power_domain);
-	}
+	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
 }
 
 /*
@@ -4370,7 +4372,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	struct drm_crtc *crtc = cstate->base.crtc;
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum pipe pipe = intel_crtc->pipe;
 	struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
 	uint16_t alloc_size, start;
 	uint16_t minimum[I915_MAX_PLANES] = {};
@@ -4383,8 +4384,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	uint16_t total_min_blocks = 0;
 
 	/* Clear the partitioning for disabled planes. */
-	memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
-	memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
+	memset(cstate->wm.skl.plane_ddb_y, 0, sizeof(cstate->wm.skl.plane_ddb_y));
+	memset(cstate->wm.skl.plane_ddb_uv, 0, sizeof(cstate->wm.skl.plane_ddb_uv));
 
 	if (WARN_ON(!state))
 		return 0;
@@ -4431,8 +4432,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	}
 
 	alloc_size -= total_min_blocks;
-	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
-	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
+	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
+	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end;
 
 	/*
 	 * 2. Distribute the remaining space in proportion to the amount of
@@ -4463,8 +4464,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
 		/* Leave disabled planes at (0,0) */
 		if (data_rate) {
-			ddb->plane[pipe][plane_id].start = start;
-			ddb->plane[pipe][plane_id].end = start + plane_blocks;
+			cstate->wm.skl.plane_ddb_y[plane_id].start = start;
+			cstate->wm.skl.plane_ddb_y[plane_id].end = start + plane_blocks;
 		}
 
 		start += plane_blocks;
@@ -4479,8 +4480,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks);
 
 		if (uv_data_rate) {
-			ddb->uv_plane[pipe][plane_id].start = start;
-			ddb->uv_plane[pipe][plane_id].end =
+			cstate->wm.skl.plane_ddb_uv[plane_id].start = start;
+			cstate->wm.skl.plane_ddb_uv[plane_id].end =
 				start + uv_plane_blocks;
 		}
 
@@ -4590,9 +4591,6 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
 		to_intel_atomic_state(cstate->base.state);
 	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
 
-	if (!intel_wm_plane_visible(cstate, intel_pstate))
-		return 0;
-
 	/* only NV12 format has two planes */
 	if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) {
 		DRM_DEBUG_KMS("Non NV12 format have single plane\n");
@@ -4706,9 +4704,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if (latency == 0)
 		return level == 0 ? -EINVAL : 0;
 
-	if (!intel_wm_plane_visible(cstate, intel_pstate))
-		return 0;
-
 	/* Display WA #1141: kbl,cfl */
 	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
 	    IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) &&
@@ -4840,21 +4835,16 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 
 static int
 skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
-		      struct skl_ddb_allocation *ddb,
 		      const struct intel_crtc_state *cstate,
 		      const struct intel_plane_state *intel_pstate,
 		      uint16_t ddb_blocks,
 		      const struct skl_wm_params *wm_params,
-		      struct skl_plane_wm *wm,
 		      struct skl_wm_level *levels)
 {
 	int level, max_level = ilk_wm_max_level(dev_priv);
 	struct skl_wm_level *result_prev = &levels[0];
 	int ret;
 
-	if (WARN_ON(!intel_pstate->base.fb))
-		return -EINVAL;
-
 	for (level = 0; level <= max_level; level++) {
 		struct skl_wm_level *result = &levels[level];
 
@@ -4872,9 +4862,6 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
 		result_prev = result;
 	}
 
-	if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
-		wm->is_planar = true;
-
 	return 0;
 }
 
@@ -4902,10 +4889,9 @@ skl_compute_linetime_wm(const struct intel_crtc_state *cstate)
 }
 
 static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
-				      struct skl_wm_params *wp,
-				      struct skl_wm_level *wm_l0,
-				      uint16_t ddb_allocation,
-				      struct skl_wm_level *trans_wm /* out */)
+				      const struct skl_wm_params *wp,
+				      struct skl_plane_wm *wm,
+				      uint16_t ddb_allocation)
 {
 	struct drm_device *dev = cstate->base.crtc->dev;
 	const struct drm_i915_private *dev_priv = to_i915(dev);
@@ -4913,9 +4899,6 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	const uint16_t trans_amount = 10; /* This is configurable amount */
 	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
 
-	if (!cstate->base.active)
-		return;
-
 	/* Transition WM are not recommended by HW team for GEN9 */
 	if (INTEL_GEN(dev_priv) <= 9)
 		return;
@@ -4940,7 +4923,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	 * Result Blocks is Result Blocks minus 1 and it should work for the
 	 * current platforms.
 	 */
-	wm0_sel_res_b = wm_l0->plane_res_b - 1;
+	wm0_sel_res_b = wm->wm[0].plane_res_b - 1;
 
 	if (wp->y_tiled) {
 		trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2,
@@ -4959,23 +4942,19 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	res_blocks += 1;
 
 	if (res_blocks < ddb_allocation) {
-		trans_wm->plane_res_b = res_blocks;
-		trans_wm->plane_en = true;
+		wm->trans_wm.plane_res_b = res_blocks;
+		wm->trans_wm.plane_en = true;
 	}
 }
 
-static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
-				       struct skl_pipe_wm *pipe_wm,
-				       enum plane_id plane_id,
-				       const struct intel_crtc_state *cstate,
-				       const struct intel_plane_state *pstate,
-				       int color_plane)
+static int skl_build_plane_wm_single(struct intel_crtc_state *cstate,
+				     const struct intel_plane_state *pstate,
+				     enum plane_id plane_id, int color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
-	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
-	enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe;
+	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
+	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_y[plane_id]);
 	struct skl_wm_params wm_params;
-	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
 	int ret;
 
 	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
@@ -4983,79 +4962,105 @@ static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
 	if (ret)
 		return ret;
 
-	ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
-				    ddb_blocks, &wm_params, wm, wm->wm);
-
+	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
+				    ddb_blocks, &wm_params, wm->wm);
 	if (ret)
 		return ret;
 
-	skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
-				  ddb_blocks, &wm->trans_wm);
+	skl_compute_transition_wm(cstate, &wm_params, wm, ddb_blocks);
 
 	return 0;
 }
 
-static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
-				     struct skl_pipe_wm *pipe_wm,
-				     const struct intel_crtc_state *cstate,
-				     const struct intel_plane_state *pstate)
+static int skl_build_plane_wm_uv(struct intel_crtc_state *cstate,
+				 const struct intel_plane_state *pstate,
+				 enum plane_id plane_id)
 {
-	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
+	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
+	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
+	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_uv[plane_id]);
+	struct skl_wm_params wm_params;
+	int ret;
+
+	wm->is_planar = true;
 
-	return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
+	/* uv plane watermarks must also be validated for NV12/Planar */
+	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
+					  &wm_params, 1);
+	if (ret)
+		return ret;
+
+	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
+				    ddb_blocks, &wm_params, wm->uv_wm);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
-static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
-				     struct skl_pipe_wm *pipe_wm,
-				     const struct intel_crtc_state *cstate,
-				     const struct intel_plane_state *pstate)
+static int skl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
+			      struct intel_crtc_state *cstate,
+			      const struct intel_plane_state *pstate)
 {
 	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
-	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	const struct drm_framebuffer *fb = pstate->base.fb;
 	enum plane_id plane_id = plane->id;
-	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
-	struct skl_wm_params wm_params;
-	enum pipe pipe = plane->pipe;
-	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
 	int ret;
 
-	ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
-	if (ret)
-		return ret;
-
-	/* uv plane watermarks must also be validated for NV12/Planar */
-	ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]);
+	if (!intel_wm_plane_visible(cstate, pstate))
+		return 0;
 
-	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1);
+	ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
 	if (ret)
 		return ret;
 
-	return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
-				     ddb_blocks, &wm_params, wm, wm->uv_wm);
+	if (fb->format->is_yuv && fb->format->num_planes > 1) {
+		ret = skl_build_plane_wm_uv(cstate, pstate, plane_id);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
-static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
-				     struct skl_pipe_wm *pipe_wm,
-				     const struct intel_crtc_state *cstate,
-				     const struct intel_plane_state *pstate)
+static int icl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
+			      struct intel_crtc_state *cstate,
+			      const struct intel_plane_state *pstate)
 {
+	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
 	int ret;
-	enum plane_id y_plane_id = pstate->linked_plane->id;
-	enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id;
 
-	ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id,
-					  cstate, pstate, 0);
-	if (ret)
-		return ret;
+	/* Watermarks calculated in master */
+	if (pstate->slave)
+		return 0;
+
+	if (pstate->linked_plane) {
+		const struct drm_framebuffer *fb = pstate->base.fb;
+		enum plane_id y_plane_id = pstate->linked_plane->id;
+
+		WARN_ON(!fb->format->is_yuv ||
+			fb->format->num_planes == 1);
+
+		ret = skl_build_plane_wm_single(cstate, pstate, y_plane_id, 0);
+		if (ret)
+			return ret;
 
-	return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id,
-					   cstate, pstate, 1);
+		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 1);
+		if (ret)
+			return ret;
+	} else if (intel_wm_plane_visible(cstate, pstate)) {
+		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
-			     struct skl_ddb_allocation *ddb,
 			     struct skl_pipe_wm *pipe_wm)
 {
+	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
 	struct drm_crtc_state *crtc_state = &cstate->base;
 	struct drm_plane *plane;
 	const struct drm_plane_state *pstate;
@@ -5071,18 +5076,10 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
 		const struct intel_plane_state *intel_pstate =
 						to_intel_plane_state(pstate);
 
-		/* Watermarks calculated in master */
-		if (intel_pstate->slave)
-			continue;
-
-		if (intel_pstate->linked_plane)
-			ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
-		else if (intel_pstate->base.fb &&
-			 intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
-			ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
+		if (INTEL_GEN(dev_priv) >= 11)
+			ret = icl_build_plane_wm(pipe_wm, cstate, intel_pstate);
 		else
-			ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate);
-
+			ret = skl_build_plane_wm(pipe_wm, cstate, intel_pstate);
 		if (ret)
 			return ret;
 	}
@@ -5097,9 +5094,9 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
 				const struct skl_ddb_entry *entry)
 {
 	if (entry->end)
-		I915_WRITE(reg, (entry->end - 1) << 16 | entry->start);
+		I915_WRITE_FW(reg, (entry->end - 1) << 16 | entry->start);
 	else
-		I915_WRITE(reg, 0);
+		I915_WRITE_FW(reg, 0);
 }
 
 static void skl_write_wm_level(struct drm_i915_private *dev_priv,
@@ -5114,19 +5111,22 @@ static void skl_write_wm_level(struct drm_i915_private *dev_priv,
 		val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
 	}
 
-	I915_WRITE(reg, val);
+	I915_WRITE_FW(reg, val);
 }
 
-static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
-			       const struct skl_plane_wm *wm,
-			       const struct skl_ddb_allocation *ddb,
-			       enum plane_id plane_id)
+void skl_write_plane_wm(struct intel_plane *plane,
+			const struct intel_crtc_state *crtc_state)
 {
-	struct drm_crtc *crtc = &intel_crtc->base;
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
-	enum pipe pipe = intel_crtc->pipe;
+	enum plane_id plane_id = plane->id;
+	enum pipe pipe = plane->pipe;
+	const struct skl_plane_wm *wm =
+		&crtc_state->wm.skl.optimal.planes[plane_id];
+	const struct skl_ddb_entry *ddb_y =
+		&crtc_state->wm.skl.plane_ddb_y[plane_id];
+	const struct skl_ddb_entry *ddb_uv =
+		&crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
 	for (level = 0; level <= max_level; level++) {
 		skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level),
@@ -5135,29 +5135,32 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
 			   &wm->trans_wm);
 
-	if (wm->is_planar && INTEL_GEN(dev_priv) < 11) {
-		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
-				    &ddb->uv_plane[pipe][plane_id]);
+	if (INTEL_GEN(dev_priv) >= 11) {
 		skl_ddb_entry_write(dev_priv,
-				    PLANE_NV12_BUF_CFG(pipe, plane_id),
-				    &ddb->plane[pipe][plane_id]);
-	} else {
-		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
-				    &ddb->plane[pipe][plane_id]);
-		if (INTEL_GEN(dev_priv) < 11)
-			I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
+				    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
+		return;
 	}
+
+	if (wm->is_planar)
+		swap(ddb_y, ddb_uv);
+
+	skl_ddb_entry_write(dev_priv,
+			    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
+	skl_ddb_entry_write(dev_priv,
+			    PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv);
 }
 
-static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
-				const struct skl_plane_wm *wm,
-				const struct skl_ddb_allocation *ddb)
+void skl_write_cursor_wm(struct intel_plane *plane,
+			 const struct intel_crtc_state *crtc_state)
 {
-	struct drm_crtc *crtc = &intel_crtc->base;
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
-	enum pipe pipe = intel_crtc->pipe;
+	enum plane_id plane_id = plane->id;
+	enum pipe pipe = plane->pipe;
+	const struct skl_plane_wm *wm =
+		&crtc_state->wm.skl.optimal.planes[plane_id];
+	const struct skl_ddb_entry *ddb =
+		&crtc_state->wm.skl.plane_ddb_y[plane_id];
 
 	for (level = 0; level <= max_level; level++) {
 		skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
@@ -5165,8 +5168,7 @@ static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
 	}
 	skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm);
 
-	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
-			    &ddb->plane[pipe][PLANE_CURSOR]);
+	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb);
 }
 
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
@@ -5207,13 +5209,12 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
 static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
 			      const struct skl_pipe_wm *old_pipe_wm,
 			      struct skl_pipe_wm *pipe_wm, /* out */
-			      struct skl_ddb_allocation *ddb, /* out */
 			      bool *changed /* out */)
 {
 	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
 	int ret;
 
-	ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
+	ret = skl_build_pipe_wm(intel_cstate, pipe_wm);
 	if (ret)
 		return ret;
 
@@ -5239,42 +5240,29 @@ pipes_modified(struct drm_atomic_state *state)
 }
 
 static int
-skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
+skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
+			    struct intel_crtc_state *new_crtc_state)
 {
-	struct drm_atomic_state *state = cstate->base.state;
-	struct drm_device *dev = state->dev;
-	struct drm_crtc *crtc = cstate->base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
-	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
-	struct drm_plane *plane;
-	enum pipe pipe = intel_crtc->pipe;
+	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_plane *plane;
 
-	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
-		struct drm_plane_state *plane_state;
-		struct intel_plane *linked;
-		enum plane_id plane_id = to_intel_plane(plane)->id;
+	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+		struct intel_plane_state *plane_state;
+		enum plane_id plane_id = plane->id;
 
-		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
-					&new_ddb->plane[pipe][plane_id]) &&
-		    skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
-					&new_ddb->uv_plane[pipe][plane_id]))
+		if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
+					&new_crtc_state->wm.skl.plane_ddb_y[plane_id]) &&
+		    skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id],
+					&new_crtc_state->wm.skl.plane_ddb_uv[plane_id]))
 			continue;
 
-		plane_state = drm_atomic_get_plane_state(state, plane);
+		plane_state = intel_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state))
 			return PTR_ERR(plane_state);
 
-		/* Make sure linked plane is updated too */
-		linked = to_intel_plane_state(plane_state)->linked_plane;
-		if (!linked)
-			continue;
-
-		plane_state = drm_atomic_get_plane_state(state, &linked->base);
-		if (IS_ERR(plane_state))
-			return PTR_ERR(plane_state);
+		new_crtc_state->update_planes |= BIT(plane_id);
 	}
 
 	return 0;
@@ -5286,18 +5274,21 @@ skl_compute_ddb(struct drm_atomic_state *state)
 	const struct drm_i915_private *dev_priv = to_i915(state->dev);
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
+	struct intel_crtc_state *old_crtc_state;
+	struct intel_crtc_state *new_crtc_state;
 	struct intel_crtc *crtc;
-	struct intel_crtc_state *cstate;
 	int ret, i;
 
 	memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
 
-	for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) {
-		ret = skl_allocate_pipe_ddb(cstate, ddb);
+	for_each_oldnew_intel_crtc_in_state(intel_state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		ret = skl_allocate_pipe_ddb(new_crtc_state, ddb);
 		if (ret)
 			return ret;
 
-		ret = skl_ddb_add_affected_planes(cstate);
+		ret = skl_ddb_add_affected_planes(old_crtc_state,
+						  new_crtc_state);
 		if (ret)
 			return ret;
 	}
@@ -5306,36 +5297,29 @@ skl_compute_ddb(struct drm_atomic_state *state)
 }
 
 static void
-skl_print_wm_changes(const struct drm_atomic_state *state)
+skl_print_wm_changes(struct intel_atomic_state *state)
 {
-	const struct drm_device *dev = state->dev;
-	const struct drm_i915_private *dev_priv = to_i915(dev);
-	const struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(state);
-	const struct drm_crtc *crtc;
-	const struct drm_crtc_state *cstate;
-	const struct intel_plane *intel_plane;
-	const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb;
-	const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	const struct intel_crtc_state *old_crtc_state;
+	const struct intel_crtc_state *new_crtc_state;
+	struct intel_plane *plane;
+	struct intel_crtc *crtc;
 	int i;
 
-	for_each_new_crtc_in_state(state, crtc, cstate, i) {
-		const struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-		enum pipe pipe = intel_crtc->pipe;
-
-		for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
-			enum plane_id plane_id = intel_plane->id;
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+			enum plane_id plane_id = plane->id;
 			const struct skl_ddb_entry *old, *new;
 
-			old = &old_ddb->plane[pipe][plane_id];
-			new = &new_ddb->plane[pipe][plane_id];
+			old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id];
+			new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id];
 
 			if (skl_ddb_entry_equal(old, new))
 				continue;
 
 			DRM_DEBUG_KMS("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n",
-				      intel_plane->base.base.id,
-				      intel_plane->base.name,
+				      plane->base.base.id, plane->base.name,
 				      old->start, old->end,
 				      new->start, new->end);
 		}
@@ -5471,8 +5455,7 @@ skl_compute_wm(struct drm_atomic_state *state)
 			&to_intel_crtc_state(crtc->state)->wm.skl.optimal;
 
 		pipe_wm = &intel_cstate->wm.skl.optimal;
-		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm,
-					 &results->ddb, &changed);
+		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, &changed);
 		if (ret)
 			return ret;
 
@@ -5486,7 +5469,7 @@ skl_compute_wm(struct drm_atomic_state *state)
 		intel_cstate->update_wm_pre = true;
 	}
 
-	skl_print_wm_changes(state);
+	skl_print_wm_changes(intel_state);
 
 	return 0;
 }
@@ -5497,23 +5480,12 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
 	struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
-	const struct skl_ddb_allocation *ddb = &state->wm_results.ddb;
 	enum pipe pipe = crtc->pipe;
-	enum plane_id plane_id;
 
 	if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base)))
 		return;
 
 	I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime);
-
-	for_each_plane_id_on_crtc(crtc, plane_id) {
-		if (plane_id != PLANE_CURSOR)
-			skl_write_plane_wm(crtc, &pipe_wm->planes[plane_id],
-					   ddb, plane_id);
-		else
-			skl_write_cursor_wm(crtc, &pipe_wm->planes[plane_id],
-					    ddb);
-	}
 }
 
 static void skl_initial_wm(struct intel_atomic_state *state,
@@ -5523,8 +5495,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct skl_ddb_values *results = &state->wm_results;
-	struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw;
-	enum pipe pipe = intel_crtc->pipe;
 
 	if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0)
 		return;
@@ -5534,11 +5504,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
 	if (cstate->base.active_changed)
 		skl_atomic_update_crtc_wm(state, cstate);
 
-	memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe],
-	       sizeof(hw_vals->ddb.uv_plane[pipe]));
-	memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe],
-	       sizeof(hw_vals->ddb.plane[pipe]));
-
 	mutex_unlock(&dev_priv->wm.wm_mutex);
 }
 
@@ -5689,13 +5654,6 @@ void skl_wm_get_hw_state(struct drm_device *dev)
 	if (dev_priv->active_crtcs) {
 		/* Fully recompute DDB on first atomic commit */
 		dev_priv->wm.distrust_bios_wm = true;
-	} else {
-		/*
-		 * Easy/common case; just sanitize DDB now if everything off
-		 * Keep dbuf slice info intact
-		 */
-		memset(ddb->plane, 0, sizeof(ddb->plane));
-		memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane));
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 2f97a298c24e..d0aa753012b5 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -436,6 +436,8 @@ skl_program_plane(struct intel_plane *plane,
 		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
 			      plane_state->color_ctl);
 
+	skl_write_plane_wm(plane, crtc_state);
+
 	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
 	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
 	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
@@ -498,6 +500,8 @@ skl_disable_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	skl_write_plane_wm(plane, crtc_state);
+
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
 
-- 
2.18.1

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

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

* [PATCH 14/14] drm/i915: Commit skl+ planes in an order that avoids ddb overlaps
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (12 preceding siblings ...)
  2018-11-01 15:06 ` [PATCH 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+ Ville Syrjala
@ 2018-11-01 15:06 ` Ville Syrjala
  2018-11-01 15:08 ` ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully Patchwork
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:06 UTC (permalink / raw)
  To: intel-gfx

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

skl+ can go belly up if there are overlapping ddb allocations between
planes. If we could absolutely guarantee that we can perform the atomic
update within a single frame we shouldn't have to worry about this. But
we can't rely on that so let's steal the ddb overlap check trick from
skl_update_crtcs() and apply it to the plane updates. Since each step
of the sequence is free from ddb overlaps we don't have to worry about
a vblank sneaking up on us in the middle of the sequence. The partial
state that gets latched by the hardware will be safe. And unlike
skl_update_crtcs() we don't have to intoduce any extra vblank waits
on accoung of only having to worry about a single pipe.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c | 96 ++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_display.c      |  7 +-
 drivers/gpu/drm/i915/intel_drv.h          |  8 +-
 3 files changed, 93 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 69fc7010190c..ff8d3e577bbf 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -169,24 +169,75 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 						   to_intel_plane_state(new_plane_state));
 }
 
-void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
-				 struct intel_crtc *crtc,
-				 struct intel_crtc_state *old_crtc_state,
-				 struct intel_crtc_state *new_crtc_state)
+static struct intel_plane *
+skl_next_plane_to_commit(struct intel_atomic_state *state,
+			 struct intel_crtc *crtc,
+			 struct skl_ddb_entry entries_y[I915_MAX_PLANES],
+			 struct skl_ddb_entry entries_uv[I915_MAX_PLANES],
+			 unsigned int *update_mask)
 {
-	u32 update_mask = new_crtc_state->update_planes;
-	struct intel_plane_state *new_plane_state;
+	struct intel_crtc_state *crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	struct intel_plane_state *plane_state;
 	struct intel_plane *plane;
 	int i;
 
-	for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) {
+	if (*update_mask == 0)
+		return NULL;
+
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		enum plane_id plane_id = plane->id;
+
 		if (crtc->pipe != plane->pipe ||
-		    !(update_mask & BIT(plane->id)))
+		    !(*update_mask & BIT(plane_id)))
 			continue;
 
+		if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id],
+						entries_y,
+						I915_MAX_PLANES, plane_id) ||
+		    skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_uv[plane_id],
+						entries_uv,
+						I915_MAX_PLANES, plane_id))
+			continue;
+
+		*update_mask &= ~BIT(plane_id);
+		entries_y[plane_id] = crtc_state->wm.skl.plane_ddb_y[plane_id];
+		entries_uv[plane_id] = crtc_state->wm.skl.plane_ddb_uv[plane_id];
+
+		return plane;
+	}
+
+	/* should never happen */
+	WARN_ON(1);
+
+	return NULL;
+}
+
+void skl_update_planes_on_crtc(struct intel_atomic_state *state,
+			       struct intel_crtc *crtc)
+{
+	struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
+	struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	struct skl_ddb_entry entries_y[I915_MAX_PLANES];
+	struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
+	u32 update_mask = new_crtc_state->update_planes;
+	struct intel_plane *plane;
+
+	memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
+	       sizeof(old_crtc_state->wm.skl.plane_ddb_y));
+	memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
+	       sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
+
+	while ((plane = skl_next_plane_to_commit(state, crtc,
+						 entries_y, entries_uv,
+						 &update_mask))) {
+		struct intel_plane_state *new_plane_state =
+			intel_atomic_get_new_plane_state(state, plane);
+
 		if (new_plane_state->base.visible) {
 			trace_intel_update_plane(&plane->base, crtc);
-
 			plane->update_plane(plane, new_crtc_state, new_plane_state);
 		} else if (new_plane_state->slave) {
 			struct intel_plane *master =
@@ -202,14 +253,37 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
 			 * plane_state.
 			 */
 			new_plane_state =
-				intel_atomic_get_new_plane_state(old_state, master);
+				intel_atomic_get_new_plane_state(state, master);
 
 			trace_intel_update_plane(&plane->base, crtc);
-
 			plane->update_slave(plane, new_crtc_state, new_plane_state);
 		} else {
 			trace_intel_disable_plane(&plane->base, crtc);
+			plane->disable_plane(plane, new_crtc_state);
+		}
+	}
+}
+
+void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
+				struct intel_crtc *crtc)
+{
+	struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	u32 update_mask = new_crtc_state->update_planes;
+	struct intel_plane_state *new_plane_state;
+	struct intel_plane *plane;
+	int i;
+
+	for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) {
+		if (crtc->pipe != plane->pipe ||
+		    !(update_mask & BIT(plane->id)))
+			continue;
 
+		if (new_plane_state->base.visible) {
+			trace_intel_update_plane(&plane->base, crtc);
+			plane->update_plane(plane, new_crtc_state, new_plane_state);
+		} else {
+			trace_intel_disable_plane(&plane->base, crtc);
 			plane->disable_plane(plane, new_crtc_state);
 		}
 	}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6905a267a13f..7be7c099e8c0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12640,7 +12640,6 @@ static void intel_update_crtc(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_crtc_state *old_intel_cstate = to_intel_crtc_state(old_crtc_state);
 	struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state);
 	bool modeset = needs_modeset(new_crtc_state);
 	struct intel_plane_state *new_plane_state =
@@ -12663,8 +12662,10 @@ static void intel_update_crtc(struct drm_crtc *crtc,
 
 	intel_begin_crtc_commit(crtc, old_crtc_state);
 
-	intel_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc,
-				    old_intel_cstate, pipe_config);
+	if (INTEL_GEN(dev_priv) >= 9)
+		skl_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc);
+	else
+		i9xx_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc);
 
 	intel_finish_crtc_commit(crtc, old_crtc_state);
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8a93e0e8c89d..653174b22773 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2290,10 +2290,10 @@ struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
 void intel_plane_destroy_state(struct drm_plane *plane,
 			       struct drm_plane_state *state);
 extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
-void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
-				 struct intel_crtc *crtc,
-				 struct intel_crtc_state *old_crtc_state,
-				 struct intel_crtc_state *new_crtc_state);
+void skl_update_planes_on_crtc(struct intel_atomic_state *state,
+			       struct intel_crtc *crtc);
+void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
+				struct intel_crtc *crtc);
 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
 					struct intel_crtc_state *crtc_state,
 					const struct intel_plane_state *old_plane_state,
-- 
2.18.1

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

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

* ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (13 preceding siblings ...)
  2018-11-01 15:06 ` [PATCH 14/14] drm/i915: Commit skl+ planes in an order that avoids ddb overlaps Ville Syrjala
@ 2018-11-01 15:08 ` Patchwork
  2018-11-01 16:04 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2) Patchwork
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 57+ messages in thread
From: Patchwork @ 2018-11-01 15:08 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Program SKL+ watermarks/ddb more carefully
URL   : https://patchwork.freedesktop.org/series/51878/
State : failure

== Summary ==

Applying: drm/i915: Nuke posting reads from plane update/disable funcs
Applying: drm/i915: Clean up skl_program_scaler()
error: sha1 information is lacking or useless (drivers/gpu/drm/i915/intel_sprite.c).
error: could not build fake ancestor
Patch failed at 0002 drm/i915: Clean up skl_program_scaler()
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

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

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

* [PATCH v2 02/14] drm/i915: Clean up skl_program_scaler()
  2018-11-01 15:05 ` [PATCH 02/14] drm/i915: Clean up skl_program_scaler() Ville Syrjala
@ 2018-11-01 15:17   ` Ville Syrjala
  2018-11-01 18:13     ` Rodrigo Vivi
  0 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-01 15:17 UTC (permalink / raw)
  To: intel-gfx

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

Remove the "sizes are 0 based" stuff that is not even true for the
scaler.

v2: Rebase

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 30b7485f1992..a77a17fda692 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -310,12 +310,11 @@ skl_plane_max_stride(struct intel_plane *plane,
 }
 
 static void
-skl_program_scaler(struct drm_i915_private *dev_priv,
-		   struct intel_plane *plane,
+skl_program_scaler(struct intel_plane *plane,
 		   const struct intel_crtc_state *crtc_state,
 		   const struct intel_plane_state *plane_state)
 {
-	enum plane_id plane_id = plane->id;
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 	int scaler_id = plane_state->scaler_id;
 	const struct intel_scaler *scaler =
@@ -327,10 +326,6 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
 	u16 y_hphase, uv_rgb_hphase;
 	u16 y_vphase, uv_rgb_vphase;
 
-	/* Sizes are 0 based */
-	crtc_w--;
-	crtc_h--;
-
 	/* TODO: handle sub-pixel coordinates */
 	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
 	    !icl_is_hdr_plane(plane)) {
@@ -350,15 +345,14 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
 	}
 
 	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
-		      PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
+		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
 	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
 	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
 		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
 	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
 		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
 	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
-	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
-		      ((crtc_w + 1) << 16)|(crtc_h + 1));
+	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
 }
 
 static void
@@ -441,11 +435,9 @@ skl_program_plane(struct intel_plane *plane,
 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
 	}
 
-	/* program plane scaler */
 	if (plane_state->scaler_id >= 0) {
 		if (!slave)
-			skl_program_scaler(dev_priv, plane,
-					   crtc_state, plane_state);
+			skl_program_scaler(plane, crtc_state, plane_state);
 
 		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
 	} else {
-- 
2.18.1

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

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

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (14 preceding siblings ...)
  2018-11-01 15:08 ` ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully Patchwork
@ 2018-11-01 16:04 ` Patchwork
  2018-11-01 16:09 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 57+ messages in thread
From: Patchwork @ 2018-11-01 16:04 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
URL   : https://patchwork.freedesktop.org/series/51878/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
240f2c27f544 drm/i915: Nuke posting reads from plane update/disable funcs
0fba33baedea drm/i915: Clean up skl_program_scaler()
8e59cc7e9005 drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler()
7c03b4e5b1ad drm/i915: Polish the skl+ plane keyval/msk/max register setup
28be8177bd68 drm/i915: Clean up skl+ PLANE_POS vs. scaler handling
7f92abec85e4 drm/i915: Reorganize plane register writes to make them more atomic
3865d3b2fe70 drm/i915: Move single buffered plane register writes to the end
1407dbc2af32 drm/i915: Generalize skl_ddb_allocation_overlaps()
c9f5cdb96fbd drm/i915: Introduce crtc_state->update_planes bitmask
b7f0fb03ec21 drm/i915: Pass the new crtc_state to ->disable_plane()
-:150: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__state' - possible side-effects?
#150: FILE: drivers/gpu/drm/i915/intel_display.h:385:
+#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
+		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
+		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
+	     (__i)++) \
+		for_each_if(plane)

-:150: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'plane' - possible side-effects?
#150: FILE: drivers/gpu/drm/i915/intel_display.h:385:
+#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
+		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
+		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
+	     (__i)++) \
+		for_each_if(plane)

-:150: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__i' - possible side-effects?
#150: FILE: drivers/gpu/drm/i915/intel_display.h:385:
+#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
+		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
+		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
+	     (__i)++) \
+		for_each_if(plane)

-:154: WARNING:LONG_LINE: line over 100 characters
#154: FILE: drivers/gpu/drm/i915/intel_display.h:389:
+		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \

total: 0 errors, 1 warnings, 3 checks, 159 lines checked
298d98fee3c4 drm/i915: Fix latency==0 handling for level 0 watermark on skl+
d48eeb6c6519 drm/i915: Remove some useless zeroing on skl+ wm calculations
1bd36424404f drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
-:157: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__state' - possible side-effects?
#157: FILE: drivers/gpu/drm/i915/intel_display.h:418:
+#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
+		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
+		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
+		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
+	     (__i)++) \
+		for_each_if(crtc)

-:157: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'crtc' - possible side-effects?
#157: FILE: drivers/gpu/drm/i915/intel_display.h:418:
+#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
+		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
+		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
+		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
+	     (__i)++) \
+		for_each_if(crtc)

-:157: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__i' - possible side-effects?
#157: FILE: drivers/gpu/drm/i915/intel_display.h:418:
+#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
+		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
+		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
+		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
+	     (__i)++) \
+		for_each_if(crtc)

-:161: WARNING:LONG_LINE: line over 100 characters
#161: FILE: drivers/gpu/drm/i915/intel_display.h:422:
+		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \

-:162: WARNING:LONG_LINE: line over 100 characters
#162: FILE: drivers/gpu/drm/i915/intel_display.h:423:
+		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \

total: 0 errors, 2 warnings, 3 checks, 912 lines checked
5d41e9a93e3e drm/i915: Commit skl+ planes in an order that avoids ddb overlaps

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

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

* ✗ Fi.CI.SPARSE: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (15 preceding siblings ...)
  2018-11-01 16:04 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2) Patchwork
@ 2018-11-01 16:09 ` Patchwork
  2018-11-01 16:26 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 57+ messages in thread
From: Patchwork @ 2018-11-01 16:09 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
URL   : https://patchwork.freedesktop.org/series/51878/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Nuke posting reads from plane update/disable funcs
Okay!

Commit: drm/i915: Clean up skl_program_scaler()
Okay!

Commit: drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler()
Okay!

Commit: drm/i915: Polish the skl+ plane keyval/msk/max register setup
Okay!

Commit: drm/i915: Clean up skl+ PLANE_POS vs. scaler handling
Okay!

Commit: drm/i915: Reorganize plane register writes to make them more atomic
Okay!

Commit: drm/i915: Move single buffered plane register writes to the end
Okay!

Commit: drm/i915: Generalize skl_ddb_allocation_overlaps()
Okay!

Commit: drm/i915: Introduce crtc_state->update_planes bitmask
Okay!

Commit: drm/i915: Pass the new crtc_state to ->disable_plane()
Okay!

Commit: drm/i915: Fix latency==0 handling for level 0 watermark on skl+
Okay!

Commit: drm/i915: Remove some useless zeroing on skl+ wm calculations
Okay!

Commit: drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3699:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3696:16: warning: expression using sizeof(void)

Commit: drm/i915: Commit skl+ planes in an order that avoids ddb overlaps
Okay!

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

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

* ✓ Fi.CI.BAT: success for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (16 preceding siblings ...)
  2018-11-01 16:09 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-11-01 16:26 ` Patchwork
  2018-11-01 18:13 ` ✓ Fi.CI.IGT: " Patchwork
  2018-11-07 19:01 ` ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully (rev6) Patchwork
  19 siblings, 0 replies; 57+ messages in thread
From: Patchwork @ 2018-11-01 16:26 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
URL   : https://patchwork.freedesktop.org/series/51878/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5067 -> Patchwork_10690 =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_10690 need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_10690, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/51878/revisions/2/mbox/

== Possible new issues ==

  Here are the unknown changes that may have been introduced in Patchwork_10690:

  === IGT changes ===

    ==== Warnings ====

    igt@drv_selftest@live_guc:
      fi-icl-u:           PASS -> SKIP +2
      fi-skl-iommu:       PASS -> SKIP +1

    
== Known issues ==

  Here are the changes found in Patchwork_10690 that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_selftest@live_hangcheck:
      fi-skl-iommu:       PASS -> INCOMPLETE (fdo#108602)

    
    ==== Possible fixes ====

    igt@gem_cpu_reloc@basic:
      fi-skl-6700hq:      INCOMPLETE (fdo#108011) -> PASS

    igt@gem_exec_suspend@basic-s3:
      fi-blb-e6850:       INCOMPLETE (fdo#107718) -> PASS

    igt@kms_frontbuffer_tracking@basic:
      fi-byt-clapper:     FAIL (fdo#103167) -> PASS

    
    ==== Warnings ====

    igt@drv_selftest@live_contexts:
      fi-icl-u:           DMESG-FAIL (fdo#108569) -> INCOMPLETE (fdo#108315)

    
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#107718 https://bugs.freedesktop.org/show_bug.cgi?id=107718
  fdo#108011 https://bugs.freedesktop.org/show_bug.cgi?id=108011
  fdo#108315 https://bugs.freedesktop.org/show_bug.cgi?id=108315
  fdo#108569 https://bugs.freedesktop.org/show_bug.cgi?id=108569
  fdo#108602 https://bugs.freedesktop.org/show_bug.cgi?id=108602


== Participating hosts (45 -> 42) ==

  Additional (1): fi-pnv-d510 
  Missing    (4): fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-hsw-4200u 


== Build changes ==

    * Linux: CI_DRM_5067 -> Patchwork_10690

  CI_DRM_5067: f784551fd7bad04465b1455a1d05b0e0aeae72a6 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4704: ace031dcb1e8bf2b32b4b0d54a55eb30e8f41d6f @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10690: 5d41e9a93e3e231f5dc22bba61b1d2b977e912e1 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

5d41e9a93e3e drm/i915: Commit skl+ planes in an order that avoids ddb overlaps
1bd36424404f drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
d48eeb6c6519 drm/i915: Remove some useless zeroing on skl+ wm calculations
298d98fee3c4 drm/i915: Fix latency==0 handling for level 0 watermark on skl+
b7f0fb03ec21 drm/i915: Pass the new crtc_state to ->disable_plane()
c9f5cdb96fbd drm/i915: Introduce crtc_state->update_planes bitmask
1407dbc2af32 drm/i915: Generalize skl_ddb_allocation_overlaps()
3865d3b2fe70 drm/i915: Move single buffered plane register writes to the end
7f92abec85e4 drm/i915: Reorganize plane register writes to make them more atomic
28be8177bd68 drm/i915: Clean up skl+ PLANE_POS vs. scaler handling
7c03b4e5b1ad drm/i915: Polish the skl+ plane keyval/msk/max register setup
8e59cc7e9005 drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler()
0fba33baedea drm/i915: Clean up skl_program_scaler()
240f2c27f544 drm/i915: Nuke posting reads from plane update/disable funcs

== Logs ==

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

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

* Re: [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs
  2018-11-01 15:05 ` [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs Ville Syrjala
@ 2018-11-01 18:08   ` Rodrigo Vivi
  0 siblings, 0 replies; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-01 18:08 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:52PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> No need for the posting reads in the plane update/disable hooks.
> If we need a posting read for something then a single one at the
> very end would be sufficient. We have that anyway in the form
> of eg. scanline/frame counter reads.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

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

> ---
>  drivers/gpu/drm/i915/intel_display.c |  6 ------
>  drivers/gpu/drm/i915/intel_sprite.c  | 12 ------------
>  2 files changed, 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 7e1131d806ae..c5ce3892d583 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3378,7 +3378,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  			      intel_plane_ggtt_offset(plane_state) +
>  			      dspaddr_offset);
>  	}
> -	POSTING_READ_FW(reg);
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -3397,7 +3396,6 @@ static void i9xx_disable_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(DSPSURF(i9xx_plane), 0);
>  	else
>  		I915_WRITE_FW(DSPADDR(i9xx_plane), 0);
> -	POSTING_READ_FW(DSPCNTR(i9xx_plane));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -9850,8 +9848,6 @@ static void i845_update_cursor(struct intel_plane *plane,
>  		I915_WRITE_FW(CURPOS(PIPE_A), pos);
>  	}
>  
> -	POSTING_READ_FW(CURCNTR(PIPE_A));
> -
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> @@ -10080,8 +10076,6 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  		I915_WRITE_FW(CURBASE(pipe), base);
>  	}
>  
> -	POSTING_READ_FW(CURBASE(pipe));
> -
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 20b5b9ff782f..bd7d988d7512 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -463,7 +463,6 @@ skl_program_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + surf_addr);
> -	POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -504,9 +503,7 @@ skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
> -
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
> -	POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -752,7 +749,6 @@ vlv_update_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
>  	I915_WRITE_FW(SPSURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> -	POSTING_READ_FW(SPSURF(pipe, plane_id));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -768,9 +764,7 @@ vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
> -
>  	I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
> -	POSTING_READ_FW(SPSURF(pipe, plane_id));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -918,7 +912,6 @@ ivb_update_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(SPRCTL(pipe), sprctl);
>  	I915_WRITE_FW(SPRSURF(pipe),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> -	POSTING_READ_FW(SPRSURF(pipe));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -936,9 +929,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  	/* Can't leave the scaler enabled... */
>  	if (IS_IVYBRIDGE(dev_priv))
>  		I915_WRITE_FW(SPRSCALE(pipe), 0);
> -
>  	I915_WRITE_FW(SPRSURF(pipe), 0);
> -	POSTING_READ_FW(SPRSURF(pipe));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -1085,7 +1076,6 @@ g4x_update_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
>  	I915_WRITE_FW(DVSSURF(pipe),
>  		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
> -	POSTING_READ_FW(DVSSURF(pipe));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -1102,9 +1092,7 @@ g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  	I915_WRITE_FW(DVSCNTR(pipe), 0);
>  	/* Disable the scaler */
>  	I915_WRITE_FW(DVSSCALE(pipe), 0);
> -
>  	I915_WRITE_FW(DVSSURF(pipe), 0);
> -	POSTING_READ_FW(DVSSURF(pipe));
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.IGT: success for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (17 preceding siblings ...)
  2018-11-01 16:26 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-11-01 18:13 ` Patchwork
  2018-11-07 19:01 ` ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully (rev6) Patchwork
  19 siblings, 0 replies; 57+ messages in thread
From: Patchwork @ 2018-11-01 18:13 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Program SKL+ watermarks/ddb more carefully (rev2)
URL   : https://patchwork.freedesktop.org/series/51878/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5067_full -> Patchwork_10690_full =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_10690_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_10690_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

== Possible new issues ==

  Here are the unknown changes that may have been introduced in Patchwork_10690_full:

  === IGT changes ===

    ==== Warnings ====

    igt@kms_vblank@pipe-b-wait-idle:
      shard-snb:          SKIP -> PASS +1

    
== Known issues ==

  Here are the changes found in Patchwork_10690_full that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_suspend@shrink:
      shard-skl:          PASS -> INCOMPLETE (fdo#106886)

    igt@gem_exec_schedule@pi-ringfull-bsd:
      shard-skl:          NOTRUN -> FAIL (fdo#103158)

    igt@kms_available_modes_crc@available_mode_test_crc:
      shard-apl:          PASS -> FAIL (fdo#106641)

    igt@kms_busy@extended-modeset-hang-newfb-with-reset-render-a:
      shard-skl:          NOTRUN -> DMESG-WARN (fdo#107956) +2

    igt@kms_cursor_crc@cursor-128x42-random:
      shard-glk:          PASS -> FAIL (fdo#103232) +2

    igt@kms_cursor_crc@cursor-64x21-random:
      shard-apl:          PASS -> FAIL (fdo#103232) +2

    igt@kms_draw_crc@draw-method-xrgb2101010-blt-ytiled:
      shard-skl:          PASS -> FAIL (fdo#103184)

    igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
      shard-glk:          PASS -> FAIL (fdo#105363)

    igt@kms_flip@flip-vs-expired-vblank:
      shard-skl:          PASS -> FAIL (fdo#105363)

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-onoff:
      shard-apl:          PASS -> FAIL (fdo#103167) +1

    igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-blt:
      shard-glk:          PASS -> FAIL (fdo#103167) +1

    igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-pwrite:
      shard-skl:          PASS -> FAIL (fdo#105682, fdo#103167)

    igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb:
      shard-skl:          NOTRUN -> FAIL (fdo#108145) +1

    igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
      shard-skl:          PASS -> FAIL (fdo#107815)

    igt@kms_plane_multiple@atomic-pipe-a-tiling-y:
      shard-glk:          PASS -> FAIL (fdo#103166) +3

    igt@kms_plane_multiple@atomic-pipe-b-tiling-y:
      shard-apl:          PASS -> FAIL (fdo#103166) +3

    igt@kms_setmode@basic:
      shard-apl:          PASS -> FAIL (fdo#99912)

    igt@kms_vblank@pipe-b-ts-continuation-suspend:
      shard-skl:          PASS -> INCOMPLETE (fdo#104108, fdo#107773)

    
    ==== Possible fixes ====

    igt@drv_hangman@error-state-capture-blt:
      shard-apl:          INCOMPLETE (fdo#103927) -> PASS

    igt@gem_ppgtt@blt-vs-render-ctxn:
      shard-skl:          TIMEOUT (fdo#108039) -> PASS

    igt@kms_chv_cursor_fail@pipe-b-256x256-right-edge:
      shard-skl:          FAIL (fdo#104671) -> PASS

    igt@kms_color@pipe-c-degamma:
      shard-apl:          FAIL (fdo#104782) -> PASS

    igt@kms_cursor_crc@cursor-128x128-dpms:
      shard-glk:          FAIL (fdo#103232) -> PASS

    igt@kms_cursor_crc@cursor-256x85-sliding:
      shard-apl:          FAIL (fdo#103232) -> PASS +2

    igt@kms_cursor_crc@cursor-64x21-random:
      shard-hsw:          DMESG-WARN (fdo#102614) -> PASS

    igt@kms_cursor_crc@cursor-64x64-suspend:
      shard-skl:          INCOMPLETE (fdo#104108) -> PASS

    igt@kms_cursor_crc@cursor-size-change:
      shard-hsw:          DMESG-FAIL (fdo#102614, fdo#103232) -> PASS

    igt@kms_cursor_legacy@cursora-vs-flipa-toggle:
      shard-glk:          DMESG-WARN (fdo#106538, fdo#105763) -> PASS

    igt@kms_draw_crc@draw-method-xrgb8888-render-untiled:
      shard-skl:          FAIL (fdo#103184) -> PASS +1

    igt@kms_flip@flip-vs-expired-vblank:
      shard-snb:          DMESG-WARN (fdo#107469) -> PASS

    igt@kms_flip@plain-flip-fb-recreate:
      shard-skl:          FAIL (fdo#100368) -> PASS

    igt@kms_flip_tiling@flip-changes-tiling-yf:
      shard-skl:          FAIL (fdo#108303, fdo#108228) -> PASS

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render:
      shard-apl:          FAIL (fdo#103167) -> PASS

    igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-render:
      shard-glk:          FAIL (fdo#103167) -> PASS +2

    igt@kms_plane_multiple@atomic-pipe-c-tiling-yf:
      shard-apl:          FAIL (fdo#103166) -> PASS +2

    igt@kms_setmode@basic:
      shard-hsw:          FAIL (fdo#99912) -> PASS

    
  fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
  fdo#102614 https://bugs.freedesktop.org/show_bug.cgi?id=102614
  fdo#103158 https://bugs.freedesktop.org/show_bug.cgi?id=103158
  fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103184 https://bugs.freedesktop.org/show_bug.cgi?id=103184
  fdo#103232 https://bugs.freedesktop.org/show_bug.cgi?id=103232
  fdo#103927 https://bugs.freedesktop.org/show_bug.cgi?id=103927
  fdo#104108 https://bugs.freedesktop.org/show_bug.cgi?id=104108
  fdo#104671 https://bugs.freedesktop.org/show_bug.cgi?id=104671
  fdo#104782 https://bugs.freedesktop.org/show_bug.cgi?id=104782
  fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363
  fdo#105682 https://bugs.freedesktop.org/show_bug.cgi?id=105682
  fdo#105763 https://bugs.freedesktop.org/show_bug.cgi?id=105763
  fdo#106538 https://bugs.freedesktop.org/show_bug.cgi?id=106538
  fdo#106641 https://bugs.freedesktop.org/show_bug.cgi?id=106641
  fdo#106886 https://bugs.freedesktop.org/show_bug.cgi?id=106886
  fdo#107469 https://bugs.freedesktop.org/show_bug.cgi?id=107469
  fdo#107773 https://bugs.freedesktop.org/show_bug.cgi?id=107773
  fdo#107815 https://bugs.freedesktop.org/show_bug.cgi?id=107815
  fdo#107956 https://bugs.freedesktop.org/show_bug.cgi?id=107956
  fdo#108039 https://bugs.freedesktop.org/show_bug.cgi?id=108039
  fdo#108145 https://bugs.freedesktop.org/show_bug.cgi?id=108145
  fdo#108228 https://bugs.freedesktop.org/show_bug.cgi?id=108228
  fdo#108303 https://bugs.freedesktop.org/show_bug.cgi?id=108303
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912


== Participating hosts (6 -> 6) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_5067 -> Patchwork_10690

  CI_DRM_5067: f784551fd7bad04465b1455a1d05b0e0aeae72a6 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4704: ace031dcb1e8bf2b32b4b0d54a55eb30e8f41d6f @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10690: 5d41e9a93e3e231f5dc22bba61b1d2b977e912e1 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

* Re: [PATCH v2 02/14] drm/i915: Clean up skl_program_scaler()
  2018-11-01 15:17   ` [PATCH v2 " Ville Syrjala
@ 2018-11-01 18:13     ` Rodrigo Vivi
  2018-11-07 18:29       ` Ville Syrjälä
  0 siblings, 1 reply; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-01 18:13 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:17:36PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Remove the "sizes are 0 based" stuff that is not even true for the
> scaler.
> 
> v2: Rebase
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

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

> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 18 +++++-------------
>  1 file changed, 5 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 30b7485f1992..a77a17fda692 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -310,12 +310,11 @@ skl_plane_max_stride(struct intel_plane *plane,
>  }
>  
>  static void
> -skl_program_scaler(struct drm_i915_private *dev_priv,
> -		   struct intel_plane *plane,
> +skl_program_scaler(struct intel_plane *plane,
>  		   const struct intel_crtc_state *crtc_state,
>  		   const struct intel_plane_state *plane_state)
>  {
> -	enum plane_id plane_id = plane->id;
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
>  	int scaler_id = plane_state->scaler_id;
>  	const struct intel_scaler *scaler =
> @@ -327,10 +326,6 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
>  	u16 y_hphase, uv_rgb_hphase;
>  	u16 y_vphase, uv_rgb_vphase;
>  
> -	/* Sizes are 0 based */
> -	crtc_w--;
> -	crtc_h--;
> -
>  	/* TODO: handle sub-pixel coordinates */
>  	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
>  	    !icl_is_hdr_plane(plane)) {
> @@ -350,15 +345,14 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
>  	}
>  
>  	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
> -		      PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
> +		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
>  	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
>  	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
>  		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
>  	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
>  		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
>  	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
> -	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
> -		      ((crtc_w + 1) << 16)|(crtc_h + 1));
> +	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
>  }
>  
>  static void
> @@ -441,11 +435,9 @@ skl_program_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
>  	}
>  
> -	/* program plane scaler */
>  	if (plane_state->scaler_id >= 0) {
>  		if (!slave)
> -			skl_program_scaler(dev_priv, plane,
> -					   crtc_state, plane_state);
> +			skl_program_scaler(plane, crtc_state, plane_state);
>  
>  		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
>  	} else {
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 02/14] drm/i915: Clean up skl_program_scaler()
  2018-11-01 18:13     ` Rodrigo Vivi
@ 2018-11-07 18:29       ` Ville Syrjälä
  2018-11-09 17:24         ` Ville Syrjälä
  0 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-07 18:29 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 11:13:50AM -0700, Rodrigo Vivi wrote:
> On Thu, Nov 01, 2018 at 05:17:36PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Remove the "sizes are 0 based" stuff that is not even true for the
> > scaler.
> > 
> > v2: Rebase
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

Thanks. First two patches pushed.

> 
> > ---
> >  drivers/gpu/drm/i915/intel_sprite.c | 18 +++++-------------
> >  1 file changed, 5 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 30b7485f1992..a77a17fda692 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -310,12 +310,11 @@ skl_plane_max_stride(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -skl_program_scaler(struct drm_i915_private *dev_priv,
> > -		   struct intel_plane *plane,
> > +skl_program_scaler(struct intel_plane *plane,
> >  		   const struct intel_crtc_state *crtc_state,
> >  		   const struct intel_plane_state *plane_state)
> >  {
> > -	enum plane_id plane_id = plane->id;
> > +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> >  	int scaler_id = plane_state->scaler_id;
> >  	const struct intel_scaler *scaler =
> > @@ -327,10 +326,6 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
> >  	u16 y_hphase, uv_rgb_hphase;
> >  	u16 y_vphase, uv_rgb_vphase;
> >  
> > -	/* Sizes are 0 based */
> > -	crtc_w--;
> > -	crtc_h--;
> > -
> >  	/* TODO: handle sub-pixel coordinates */
> >  	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
> >  	    !icl_is_hdr_plane(plane)) {
> > @@ -350,15 +345,14 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
> >  	}
> >  
> >  	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
> > -		      PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
> > +		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
> >  	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> >  	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
> >  		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
> >  	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
> >  		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
> >  	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
> > -	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
> > -		      ((crtc_w + 1) << 16)|(crtc_h + 1));
> > +	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
> >  }
> >  
> >  static void
> > @@ -441,11 +435,9 @@ skl_program_plane(struct intel_plane *plane,
> >  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
> >  	}
> >  
> > -	/* program plane scaler */
> >  	if (plane_state->scaler_id >= 0) {
> >  		if (!slave)
> > -			skl_program_scaler(dev_priv, plane,
> > -					   crtc_state, plane_state);
> > +			skl_program_scaler(plane, crtc_state, plane_state);
> >  
> >  		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
> >  	} else {
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* [PATCH v2 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup
  2018-11-01 15:05 ` [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup Ville Syrjala
@ 2018-11-07 18:41   ` Ville Syrjala
  2018-11-07 19:55   ` [PATCH " Rodrigo Vivi
  1 sibling, 0 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-07 18:41 UTC (permalink / raw)
  To: intel-gfx

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

Due to the constant alpha we're going to have to program two of
the the tree keying registers anyway, so might as well always
program all three.

And parametrize the plane constant alpha define while at it.

v2: Rebase due to input CSC

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h     |  2 +-
 drivers/gpu/drm/i915/intel_sprite.c | 22 +++++++++-------------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 158cf4716d03..fe4b913e46ac 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6559,7 +6559,7 @@ enum {
 #define  PLANE_KEYMSK_ALPHA_ENABLE		(1 << 31)
 #define _PLANE_KEYMAX_1_A			0x701a0
 #define _PLANE_KEYMAX_2_A			0x702a0
-#define  PLANE_KEYMAX_ALPHA_SHIFT		24
+#define  PLANE_KEYMAX_ALPHA(a)			((a) << 24)
 #define _PLANE_AUX_DIST_1_A			0x701c0
 #define _PLANE_AUX_DIST_2_A			0x702c0
 #define _PLANE_AUX_OFFSET_1_A			0x701c4
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 287a43524564..6d9f321cdf7b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -478,13 +478,20 @@ skl_program_plane(struct intel_plane *plane,
 	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
 	struct intel_plane *linked = plane_state->linked_plane;
 	const struct drm_framebuffer *fb = plane_state->base.fb;
+	u8 alpha = plane_state->base.alpha >> 8;
 	unsigned long irqflags;
-	u32 keymsk = 0, keymax = 0;
+	u32 keymsk, keymax;
 
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
 
+	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
+
+	keymsk = key->channel_mask & 0x3ffffff;
+	if (alpha < 0xff)
+		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
+
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
@@ -494,18 +501,7 @@ skl_program_plane(struct intel_plane *plane,
 	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
 		icl_program_input_csc_coeff(crtc_state, plane_state);
 
-	if (key->flags) {
-		I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
-
-		keymax |= key->max_value & 0xffffff;
-		keymsk |= key->channel_mask & 0x3ffffff;
-	}
-
-	keymax |= (plane_state->base.alpha >> 8) << PLANE_KEYMAX_ALPHA_SHIFT;
-
-	if (plane_state->base.alpha < 0xff00)
-		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
-
+	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
 	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
 	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
 
-- 
2.18.1

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

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

* [PATCH v2 06/14] drm/i915: Reorganize plane register writes to make them more atomic
  2018-11-01 15:05 ` [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic Ville Syrjala
@ 2018-11-07 18:42   ` Ville Syrjala
  2018-11-08 19:30     ` Matt Roper
  2018-11-07 21:26   ` [PATCH " Rodrigo Vivi
  1 sibling, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-07 18:42 UTC (permalink / raw)
  To: intel-gfx

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

Some observations about the plane registers:
- the control register will self-arm if the plane is not already
  enabled, thus we want to write it as close to (or ideally after)
  the surface register
- tileoff/linoff/offset/aux_offset are self-arming as well so we want
  them close to the surface register as well
- color keying registers we maybe self arming before SKL. Not 100%
  sure but we can try to keep them near to the surface register
  as well
- chv pipe b csc register are double buffered but self arming so
  moving them down a bit
- the rest should be mostly armed by the surface register so we can
  safely write them first, and to just for some consistency let's try
  to follow keep them in order based on the register offset

v2: Rebase due to input CSC

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  40 +++++----
 drivers/gpu/drm/i915/intel_sprite.c  | 120 +++++++++++++++------------
 2 files changed, 89 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ae6d58dbf1ed..ac46497cfc52 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3313,7 +3313,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
 	u32 linear_offset;
 	u32 dspcntr = plane_state->ctl;
-	i915_reg_t reg = DSPCNTR(i9xx_plane);
 	int x = plane_state->color_plane[0].x;
 	int y = plane_state->color_plane[0].y;
 	unsigned long irqflags;
@@ -3328,41 +3327,45 @@ static void i9xx_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
+
 	if (INTEL_GEN(dev_priv) < 4) {
 		/* pipesrc and dspsize control the size that is scaled from,
 		 * which should always be the user's requested size.
 		 */
+		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
 		I915_WRITE_FW(DSPSIZE(i9xx_plane),
 			      ((crtc_state->pipe_src_h - 1) << 16) |
 			      (crtc_state->pipe_src_w - 1));
-		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
 	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
+		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
 		I915_WRITE_FW(PRIMSIZE(i9xx_plane),
 			      ((crtc_state->pipe_src_h - 1) << 16) |
 			      (crtc_state->pipe_src_w - 1));
-		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
 		I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
 	}
 
-	I915_WRITE_FW(reg, dspcntr);
-
-	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
-		I915_WRITE_FW(DSPSURF(i9xx_plane),
-			      intel_plane_ggtt_offset(plane_state) +
-			      dspaddr_offset);
 		I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
 	} else if (INTEL_GEN(dev_priv) >= 4) {
+		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
+		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
+	}
+
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
+	I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
+	if (INTEL_GEN(dev_priv) >= 4)
 		I915_WRITE_FW(DSPSURF(i9xx_plane),
 			      intel_plane_ggtt_offset(plane_state) +
 			      dspaddr_offset);
-		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
-		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
-	} else {
+	else
 		I915_WRITE_FW(DSPADDR(i9xx_plane),
 			      intel_plane_ggtt_offset(plane_state) +
 			      dspaddr_offset);
-	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -10013,8 +10016,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	 * On some platforms writing CURCNTR first will also
 	 * cause CURPOS to be armed by the CURBASE write.
 	 * Without the CURCNTR write the CURPOS write would
-	 * arm itself. Thus we always start the full update
-	 * with a CURCNTR write.
+	 * arm itself. Thus we always update CURCNTR before
+	 * CURPOS.
 	 *
 	 * On other platforms CURPOS always requires the
 	 * CURBASE write to arm the update. Additonally
@@ -10024,15 +10027,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	 * cursor that doesn't appear to move, or even change
 	 * shape. Thus we always write CURBASE.
 	 *
-	 * CURCNTR and CUR_FBC_CTL are always
-	 * armed by the CURBASE write only.
+	 * The other registers are armed by by the CURBASE write
+	 * except when the plane is getting enabled at which time
+	 * the CURCNTR write arms the update.
 	 */
 	if (plane->cursor.base != base ||
 	    plane->cursor.size != fbc_ctl ||
 	    plane->cursor.cntl != cntl) {
-		I915_WRITE_FW(CURCNTR(pipe), cntl);
 		if (HAS_CUR_FBC(dev_priv))
 			I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
+		I915_WRITE_FW(CURCNTR(pipe), cntl);
 		I915_WRITE_FW(CURPOS(pipe), pos);
 		I915_WRITE_FW(CURBASE(pipe), base);
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index facf7ca8f14f..be6e3c3de1ff 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -500,27 +500,12 @@ skl_program_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
-	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
-		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
-			      plane_state->color_ctl);
-
-	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
-		icl_program_input_csc_coeff(crtc_state, plane_state);
-
-	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
-	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
-	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
-
-	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
 	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
+	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
 	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
 	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
-		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
-
-	if (INTEL_GEN(dev_priv) < 11)
-		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
-			      (plane_state->color_plane[1].y << 16) |
-			       plane_state->color_plane[1].x);
+		      (plane_state->color_plane[1].offset - surf_addr) |
+		      aux_stride);
 
 	if (icl_is_hdr_plane(plane)) {
 		u32 cus_ctl = 0;
@@ -543,15 +528,36 @@ skl_program_plane(struct intel_plane *plane,
 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
 	}
 
-	if (!slave && plane_state->scaler_id >= 0)
-		skl_program_scaler(plane, crtc_state, plane_state);
+	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
+			      plane_state->color_ctl);
 
-	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
+	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
+		icl_program_input_csc_coeff(crtc_state, plane_state);
+
+	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
+	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
+	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
+
+	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
+
+	if (INTEL_GEN(dev_priv) < 11)
+		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+			      (plane_state->color_plane[1].y << 16) |
+			      plane_state->color_plane[1].x);
 
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + surf_addr);
 
+	if (!slave && plane_state->scaler_id >= 0)
+		skl_program_scaler(plane, crtc_state, plane_state);
+
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -789,7 +795,6 @@ vlv_update_plane(struct intel_plane *plane,
 		 const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	enum plane_id plane_id = plane->id;
 	u32 sprctl = plane_state->ctl;
@@ -814,6 +819,12 @@ vlv_update_plane(struct intel_plane *plane,
 
 	vlv_update_clrc(plane_state);
 
+	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
+		      plane_state->color_plane[0].stride);
+	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
+	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
+
 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
 		chv_update_csc(plane_state);
 
@@ -822,18 +833,15 @@ vlv_update_plane(struct intel_plane *plane,
 		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
 		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
 	}
-	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
-		      plane_state->color_plane[0].stride);
-	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
-
-	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
-		I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
-	else
-		I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
 
-	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
+	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
+	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
 
-	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
 	I915_WRITE_FW(SPSURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
@@ -947,7 +955,6 @@ ivb_update_plane(struct intel_plane *plane,
 		 const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	u32 sprctl = plane_state->ctl, sprscale = 0;
 	u32 sprsurf_offset = plane_state->color_plane[0].offset;
@@ -976,27 +983,32 @@ ivb_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
+	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
+	if (IS_IVYBRIDGE(dev_priv))
+		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
+
 	if (key->flags) {
 		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
 		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
 		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
 	}
 
-	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
-	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
-
 	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
 	 * register */
-	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
 		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
-	else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
+	} else {
 		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
-	else
 		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
+	}
 
-	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
-	if (IS_IVYBRIDGE(dev_priv))
-		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(SPRCTL(pipe), sprctl);
 	I915_WRITE_FW(SPRSURF(pipe),
 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
@@ -1014,7 +1026,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	I915_WRITE_FW(SPRCTL(pipe), 0);
-	/* Can't leave the scaler enabled... */
+	/* Disable the scaler */
 	if (IS_IVYBRIDGE(dev_priv))
 		I915_WRITE_FW(SPRSCALE(pipe), 0);
 	I915_WRITE_FW(SPRSURF(pipe), 0);
@@ -1116,7 +1128,6 @@ g4x_update_plane(struct intel_plane *plane,
 		 const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	u32 dvscntr = plane_state->ctl, dvsscale = 0;
 	u32 dvssurf_offset = plane_state->color_plane[0].offset;
@@ -1145,22 +1156,25 @@ g4x_update_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
+	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
+	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
+
 	if (key->flags) {
 		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
 		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
 		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
 	}
 
-	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
-	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
+	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
 
-	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
-		I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
-	else
-		I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
-
-	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
-	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
+	/*
+	 * The control register self-arms if the plane was previously
+	 * disabled. Try to make the plane enable atomic by writing
+	 * the control register just before the surface register.
+	 */
 	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
 	I915_WRITE_FW(DVSSURF(pipe),
 		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
-- 
2.18.1

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

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

* [PATCH v2 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations
  2018-11-01 15:06 ` [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations Ville Syrjala
@ 2018-11-07 18:43   ` Ville Syrjala
  2018-11-07 22:11   ` [PATCH " Rodrigo Vivi
  1 sibling, 0 replies; 57+ messages in thread
From: Ville Syrjala @ 2018-11-07 18:43 UTC (permalink / raw)
  To: intel-gfx

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

We memset(0) the entire watermark struct the start, so there's no
need to clear things later on.

v2: Rebase due to some stale w/a removal

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 791d75322732..749e8d814ce5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4706,10 +4706,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if (latency == 0)
 		return level == 0 ? -EINVAL : 0;
 
-	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
-		result->plane_en = false;
+	if (!intel_wm_plane_visible(cstate, intel_pstate))
 		return 0;
-	}
 
 	/* Display WA #1141: kbl,cfl */
 	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
@@ -4806,8 +4804,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if ((level > 0 && res_lines > 31) ||
 	    res_blocks >= ddb_allocation ||
 	    min_disp_buf_needed >= ddb_allocation) {
-		result->plane_en = false;
-
 		/*
 		 * If there are no valid level 0 watermarks, then we can't
 		 * support this display configuration.
@@ -4909,15 +4905,15 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
 
 	if (!cstate->base.active)
-		goto exit;
+		return;
 
 	/* Transition WM are not recommended by HW team for GEN9 */
 	if (INTEL_GEN(dev_priv) <= 9)
-		goto exit;
+		return;
 
 	/* Transition WM don't make any sense if ipc is disabled */
 	if (!dev_priv->ipc_enabled)
-		goto exit;
+		return;
 
 	trans_min = 14;
 	if (INTEL_GEN(dev_priv) >= 11)
@@ -4956,11 +4952,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	if (res_blocks < ddb_allocation) {
 		trans_wm->plane_res_b = res_blocks;
 		trans_wm->plane_en = true;
-		return;
 	}
-
-exit:
-	trans_wm->plane_en = false;
 }
 
 static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
-- 
2.18.1

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

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

* [PATCH v2 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
  2018-11-01 15:06 ` [PATCH 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+ Ville Syrjala
@ 2018-11-07 18:44   ` Ville Syrjala
  2018-11-09  1:38     ` Matt Roper
  0 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjala @ 2018-11-07 18:44 UTC (permalink / raw)
  To: intel-gfx

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

On SKL+ the plane WM/BUF_CFG registers are a proper part of each
plane's register set. That means accessing them will cancel any
pending plane update, and we would need a PLANE_SURF register write
to arm the wm/ddb change as well.

To avoid all the problems with that let's just move the wm/ddb
programming into the plane update/disable hooks. Now all plane
registers get written in one (hopefully atomic) operation.

To make that feasible we'll move the plane ddb tracking into
the crtc state. Watermarks were already tracked there.

v2: Rebase due to input CSC

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  21 +-
 drivers/gpu/drm/i915/i915_drv.h      |   3 -
 drivers/gpu/drm/i915/intel_display.c |  16 +-
 drivers/gpu/drm/i915/intel_display.h |  11 +-
 drivers/gpu/drm/i915/intel_drv.h     |   9 +
 drivers/gpu/drm/i915/intel_pm.c      | 450 ++++++++++++---------------
 drivers/gpu/drm/i915/intel_sprite.c  |   4 +
 7 files changed, 250 insertions(+), 264 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index f60485906f7e..3e80a04d2790 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3437,31 +3437,32 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
 	struct drm_device *dev = &dev_priv->drm;
-	struct skl_ddb_allocation *ddb;
 	struct skl_ddb_entry *entry;
-	enum pipe pipe;
-	int plane;
+	struct intel_crtc *crtc;
 
 	if (INTEL_GEN(dev_priv) < 9)
 		return -ENODEV;
 
 	drm_modeset_lock_all(dev);
 
-	ddb = &dev_priv->wm.skl_hw.ddb;
-
 	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
 
-	for_each_pipe(dev_priv, pipe) {
+	for_each_intel_crtc(&dev_priv->drm, crtc) {
+		struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+		enum pipe pipe = crtc->pipe;
+		enum plane_id plane_id;
+
 		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
 
-		for_each_universal_plane(dev_priv, pipe, plane) {
-			entry = &ddb->plane[pipe][plane];
-			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
+		for_each_plane_id_on_crtc(crtc, plane_id) {
+			entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
+			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
 				   entry->start, entry->end,
 				   skl_ddb_entry_size(entry));
 		}
 
-		entry = &ddb->plane[pipe][PLANE_CURSOR];
+		entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
 		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 2a88a7eb871b..17023a869091 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1236,9 +1236,6 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
 }
 
 struct skl_ddb_allocation {
-	/* packed/y */
-	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
-	struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
 	u8 enabled_slices; /* GEN11 has configurable 2 slices */
 };
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ac3687a0245d..f497bb521baf 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10040,6 +10040,10 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	 * except when the plane is getting enabled at which time
 	 * the CURCNTR write arms the update.
 	 */
+
+	if (INTEL_GEN(dev_priv) >= 9)
+		skl_write_cursor_wm(plane, crtc_state);
+
 	if (plane->cursor.base != base ||
 	    plane->cursor.size != fbc_ctl ||
 	    plane->cursor.cntl != cntl) {
@@ -11829,6 +11833,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 	struct skl_pipe_wm hw_wm, *sw_wm;
 	struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
 	struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
+	struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES];
+	struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES];
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	const enum pipe pipe = intel_crtc->pipe;
 	int plane, level, max_level = ilk_wm_max_level(dev_priv);
@@ -11839,6 +11845,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 	skl_pipe_wm_get_hw_state(crtc, &hw_wm);
 	sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal;
 
+	skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv);
+
 	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
 	sw_ddb = &dev_priv->wm.skl_hw.ddb;
 
@@ -11881,8 +11889,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 		}
 
 		/* DDB */
-		hw_ddb_entry = &hw_ddb.plane[pipe][plane];
-		sw_ddb_entry = &sw_ddb->plane[pipe][plane];
+		hw_ddb_entry = &hw_ddb_y[plane];
+		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane];
 
 		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
 			DRM_ERROR("mismatch in DDB state pipe %c plane %d (expected (%u,%u), found (%u,%u))\n",
@@ -11931,8 +11939,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
 		}
 
 		/* DDB */
-		hw_ddb_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
-		sw_ddb_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+		hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR];
+		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR];
 
 		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
 			DRM_ERROR("mismatch in DDB state pipe %c cursor (expected (%u,%u), found (%u,%u))\n",
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index df9e6ebb27de..078406dc65e5 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -319,7 +319,7 @@ struct intel_link_m_n {
 			    &(dev)->mode_config.plane_list,		\
 			    base.head)					\
 		for_each_if((plane_mask) &				\
-			    drm_plane_mask(&intel_plane->base)))
+			    drm_plane_mask(&intel_plane->base))
 
 #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
 	list_for_each_entry(intel_plane,				\
@@ -415,6 +415,15 @@ struct intel_link_m_n {
 	     (__i)++) \
 		for_each_if(plane)
 
+#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
+		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
+		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
+		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
+	     (__i)++) \
+		for_each_if(crtc)
+
 void intel_link_compute_m_n(int bpp, int nlanes,
 			    int pixel_clock, int link_clock,
 			    struct intel_link_m_n *m_n,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fae8c8f6d009..64ee84c6ee09 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -705,6 +705,8 @@ struct intel_crtc_wm_state {
 			/* gen9+ only needs 1-step wm programming */
 			struct skl_pipe_wm optimal;
 			struct skl_ddb_entry ddb;
+			struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
+			struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES];
 		} skl;
 
 		struct {
@@ -2183,6 +2185,9 @@ void g4x_wm_get_hw_state(struct drm_device *dev);
 void vlv_wm_get_hw_state(struct drm_device *dev);
 void ilk_wm_get_hw_state(struct drm_device *dev);
 void skl_wm_get_hw_state(struct drm_device *dev);
+void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
+			       struct skl_ddb_entry *ddb_y,
+			       struct skl_ddb_entry *ddb_uv);
 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
 			  struct skl_ddb_allocation *ddb /* out */);
 void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
@@ -2197,6 +2202,10 @@ bool skl_wm_level_equals(const struct skl_wm_level *l1,
 bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
 				 const struct skl_ddb_entry entries[],
 				 int num_entries, int ignore_idx);
+void skl_write_plane_wm(struct intel_plane *plane,
+			const struct intel_crtc_state *crtc_state);
+void skl_write_cursor_wm(struct intel_plane *plane,
+			 const struct intel_crtc_state *crtc_state);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 				  struct intel_crtc_state *cstate);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 749e8d814ce5..40406cc0d40b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3911,68 +3911,70 @@ static void
 skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
 			   const enum pipe pipe,
 			   const enum plane_id plane_id,
-			   struct skl_ddb_allocation *ddb /* out */)
+			   struct skl_ddb_entry *ddb_y,
+			   struct skl_ddb_entry *ddb_uv)
 {
-	u32 val, val2 = 0;
-	int fourcc, pixel_format;
+	u32 val, val2;
+	u32 fourcc = 0;
 
 	/* Cursor doesn't support NV12/planar, so no extra calculation needed */
 	if (plane_id == PLANE_CURSOR) {
 		val = I915_READ(CUR_BUF_CFG(pipe));
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->plane[pipe][plane_id], val);
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
 		return;
 	}
 
 	val = I915_READ(PLANE_CTL(pipe, plane_id));
 
 	/* No DDB allocated for disabled planes */
-	if (!(val & PLANE_CTL_ENABLE))
-		return;
-
-	pixel_format = val & PLANE_CTL_FORMAT_MASK;
-	fourcc = skl_format_to_fourcc(pixel_format,
-				      val & PLANE_CTL_ORDER_RGBX,
-				      val & PLANE_CTL_ALPHA_MASK);
+	if (val & PLANE_CTL_ENABLE)
+		fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK,
+					      val & PLANE_CTL_ORDER_RGBX,
+					      val & PLANE_CTL_ALPHA_MASK);
 
-	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
-	if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) {
+	if (INTEL_GEN(dev_priv) >= 11) {
+		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
+	} else {
+		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
 		val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
 
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->plane[pipe][plane_id], val2);
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->uv_plane[pipe][plane_id], val);
-	} else {
-		skl_ddb_entry_init_from_hw(dev_priv,
-					   &ddb->plane[pipe][plane_id], val);
+		if (fourcc == DRM_FORMAT_NV12)
+			swap(val, val2);
+
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
+		skl_ddb_entry_init_from_hw(dev_priv, ddb_uv, val2);
 	}
 }
 
-void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
-			  struct skl_ddb_allocation *ddb /* out */)
+void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
+			       struct skl_ddb_entry *ddb_y,
+			       struct skl_ddb_entry *ddb_uv)
 {
-	struct intel_crtc *crtc;
-
-	memset(ddb, 0, sizeof(*ddb));
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum intel_display_power_domain power_domain;
+	enum pipe pipe = crtc->pipe;
+	enum plane_id plane_id;
 
-	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
+	power_domain = POWER_DOMAIN_PIPE(pipe);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return;
 
-	for_each_intel_crtc(&dev_priv->drm, crtc) {
-		enum intel_display_power_domain power_domain;
-		enum plane_id plane_id;
-		enum pipe pipe = crtc->pipe;
+	for_each_plane_id_on_crtc(crtc, plane_id)
+		skl_ddb_get_hw_plane_state(dev_priv, pipe,
+					   plane_id,
+					   &ddb_y[plane_id],
+					   &ddb_uv[plane_id]);
 
-		power_domain = POWER_DOMAIN_PIPE(pipe);
-		if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
-			continue;
+	intel_display_power_put(dev_priv, power_domain);
+}
 
-		for_each_plane_id_on_crtc(crtc, plane_id)
-			skl_ddb_get_hw_plane_state(dev_priv, pipe,
-						   plane_id, ddb);
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+			  struct skl_ddb_allocation *ddb /* out */)
+{
+	memset(ddb, 0, sizeof(*ddb));
 
-		intel_display_power_put(dev_priv, power_domain);
-	}
+	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
 }
 
 /*
@@ -4370,7 +4372,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	struct drm_crtc *crtc = cstate->base.crtc;
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum pipe pipe = intel_crtc->pipe;
 	struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
 	uint16_t alloc_size, start;
 	uint16_t minimum[I915_MAX_PLANES] = {};
@@ -4383,8 +4384,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	uint16_t total_min_blocks = 0;
 
 	/* Clear the partitioning for disabled planes. */
-	memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
-	memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
+	memset(cstate->wm.skl.plane_ddb_y, 0, sizeof(cstate->wm.skl.plane_ddb_y));
+	memset(cstate->wm.skl.plane_ddb_uv, 0, sizeof(cstate->wm.skl.plane_ddb_uv));
 
 	if (WARN_ON(!state))
 		return 0;
@@ -4431,8 +4432,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	}
 
 	alloc_size -= total_min_blocks;
-	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
-	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
+	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
+	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end;
 
 	/*
 	 * 2. Distribute the remaining space in proportion to the amount of
@@ -4463,8 +4464,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
 		/* Leave disabled planes at (0,0) */
 		if (data_rate) {
-			ddb->plane[pipe][plane_id].start = start;
-			ddb->plane[pipe][plane_id].end = start + plane_blocks;
+			cstate->wm.skl.plane_ddb_y[plane_id].start = start;
+			cstate->wm.skl.plane_ddb_y[plane_id].end = start + plane_blocks;
 		}
 
 		start += plane_blocks;
@@ -4479,8 +4480,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks);
 
 		if (uv_data_rate) {
-			ddb->uv_plane[pipe][plane_id].start = start;
-			ddb->uv_plane[pipe][plane_id].end =
+			cstate->wm.skl.plane_ddb_uv[plane_id].start = start;
+			cstate->wm.skl.plane_ddb_uv[plane_id].end =
 				start + uv_plane_blocks;
 		}
 
@@ -4590,9 +4591,6 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
 		to_intel_atomic_state(cstate->base.state);
 	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
 
-	if (!intel_wm_plane_visible(cstate, intel_pstate))
-		return 0;
-
 	/* only NV12 format has two planes */
 	if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) {
 		DRM_DEBUG_KMS("Non NV12 format have single plane\n");
@@ -4706,9 +4704,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if (latency == 0)
 		return level == 0 ? -EINVAL : 0;
 
-	if (!intel_wm_plane_visible(cstate, intel_pstate))
-		return 0;
-
 	/* Display WA #1141: kbl,cfl */
 	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
 	    IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) &&
@@ -4831,21 +4826,16 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 
 static int
 skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
-		      struct skl_ddb_allocation *ddb,
 		      const struct intel_crtc_state *cstate,
 		      const struct intel_plane_state *intel_pstate,
 		      uint16_t ddb_blocks,
 		      const struct skl_wm_params *wm_params,
-		      struct skl_plane_wm *wm,
 		      struct skl_wm_level *levels)
 {
 	int level, max_level = ilk_wm_max_level(dev_priv);
 	struct skl_wm_level *result_prev = &levels[0];
 	int ret;
 
-	if (WARN_ON(!intel_pstate->base.fb))
-		return -EINVAL;
-
 	for (level = 0; level <= max_level; level++) {
 		struct skl_wm_level *result = &levels[level];
 
@@ -4863,9 +4853,6 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
 		result_prev = result;
 	}
 
-	if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
-		wm->is_planar = true;
-
 	return 0;
 }
 
@@ -4893,10 +4880,9 @@ skl_compute_linetime_wm(const struct intel_crtc_state *cstate)
 }
 
 static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
-				      struct skl_wm_params *wp,
-				      struct skl_wm_level *wm_l0,
-				      uint16_t ddb_allocation,
-				      struct skl_wm_level *trans_wm /* out */)
+				      const struct skl_wm_params *wp,
+				      struct skl_plane_wm *wm,
+				      uint16_t ddb_allocation)
 {
 	struct drm_device *dev = cstate->base.crtc->dev;
 	const struct drm_i915_private *dev_priv = to_i915(dev);
@@ -4904,9 +4890,6 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	const uint16_t trans_amount = 10; /* This is configurable amount */
 	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
 
-	if (!cstate->base.active)
-		return;
-
 	/* Transition WM are not recommended by HW team for GEN9 */
 	if (INTEL_GEN(dev_priv) <= 9)
 		return;
@@ -4931,7 +4914,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	 * Result Blocks is Result Blocks minus 1 and it should work for the
 	 * current platforms.
 	 */
-	wm0_sel_res_b = wm_l0->plane_res_b - 1;
+	wm0_sel_res_b = wm->wm[0].plane_res_b - 1;
 
 	if (wp->y_tiled) {
 		trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2,
@@ -4950,23 +4933,19 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 	res_blocks += 1;
 
 	if (res_blocks < ddb_allocation) {
-		trans_wm->plane_res_b = res_blocks;
-		trans_wm->plane_en = true;
+		wm->trans_wm.plane_res_b = res_blocks;
+		wm->trans_wm.plane_en = true;
 	}
 }
 
-static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
-				       struct skl_pipe_wm *pipe_wm,
-				       enum plane_id plane_id,
-				       const struct intel_crtc_state *cstate,
-				       const struct intel_plane_state *pstate,
-				       int color_plane)
+static int skl_build_plane_wm_single(struct intel_crtc_state *cstate,
+				     const struct intel_plane_state *pstate,
+				     enum plane_id plane_id, int color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
-	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
-	enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe;
+	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
+	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_y[plane_id]);
 	struct skl_wm_params wm_params;
-	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
 	int ret;
 
 	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
@@ -4974,79 +4953,105 @@ static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
 	if (ret)
 		return ret;
 
-	ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
-				    ddb_blocks, &wm_params, wm, wm->wm);
-
+	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
+				    ddb_blocks, &wm_params, wm->wm);
 	if (ret)
 		return ret;
 
-	skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
-				  ddb_blocks, &wm->trans_wm);
+	skl_compute_transition_wm(cstate, &wm_params, wm, ddb_blocks);
 
 	return 0;
 }
 
-static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
-				     struct skl_pipe_wm *pipe_wm,
-				     const struct intel_crtc_state *cstate,
-				     const struct intel_plane_state *pstate)
+static int skl_build_plane_wm_uv(struct intel_crtc_state *cstate,
+				 const struct intel_plane_state *pstate,
+				 enum plane_id plane_id)
 {
-	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
+	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
+	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
+	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_uv[plane_id]);
+	struct skl_wm_params wm_params;
+	int ret;
+
+	wm->is_planar = true;
 
-	return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
+	/* uv plane watermarks must also be validated for NV12/Planar */
+	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
+					  &wm_params, 1);
+	if (ret)
+		return ret;
+
+	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
+				    ddb_blocks, &wm_params, wm->uv_wm);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
-static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
-				     struct skl_pipe_wm *pipe_wm,
-				     const struct intel_crtc_state *cstate,
-				     const struct intel_plane_state *pstate)
+static int skl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
+			      struct intel_crtc_state *cstate,
+			      const struct intel_plane_state *pstate)
 {
 	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
-	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	const struct drm_framebuffer *fb = pstate->base.fb;
 	enum plane_id plane_id = plane->id;
-	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
-	struct skl_wm_params wm_params;
-	enum pipe pipe = plane->pipe;
-	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
 	int ret;
 
-	ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
-	if (ret)
-		return ret;
-
-	/* uv plane watermarks must also be validated for NV12/Planar */
-	ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]);
+	if (!intel_wm_plane_visible(cstate, pstate))
+		return 0;
 
-	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1);
+	ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
 	if (ret)
 		return ret;
 
-	return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
-				     ddb_blocks, &wm_params, wm, wm->uv_wm);
+	if (fb->format->is_yuv && fb->format->num_planes > 1) {
+		ret = skl_build_plane_wm_uv(cstate, pstate, plane_id);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
-static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
-				     struct skl_pipe_wm *pipe_wm,
-				     const struct intel_crtc_state *cstate,
-				     const struct intel_plane_state *pstate)
+static int icl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
+			      struct intel_crtc_state *cstate,
+			      const struct intel_plane_state *pstate)
 {
+	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
 	int ret;
-	enum plane_id y_plane_id = pstate->linked_plane->id;
-	enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id;
 
-	ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id,
-					  cstate, pstate, 0);
-	if (ret)
-		return ret;
+	/* Watermarks calculated in master */
+	if (pstate->slave)
+		return 0;
+
+	if (pstate->linked_plane) {
+		const struct drm_framebuffer *fb = pstate->base.fb;
+		enum plane_id y_plane_id = pstate->linked_plane->id;
+
+		WARN_ON(!fb->format->is_yuv ||
+			fb->format->num_planes == 1);
+
+		ret = skl_build_plane_wm_single(cstate, pstate, y_plane_id, 0);
+		if (ret)
+			return ret;
 
-	return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id,
-					   cstate, pstate, 1);
+		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 1);
+		if (ret)
+			return ret;
+	} else if (intel_wm_plane_visible(cstate, pstate)) {
+		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
-			     struct skl_ddb_allocation *ddb,
 			     struct skl_pipe_wm *pipe_wm)
 {
+	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
 	struct drm_crtc_state *crtc_state = &cstate->base;
 	struct drm_plane *plane;
 	const struct drm_plane_state *pstate;
@@ -5062,18 +5067,10 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
 		const struct intel_plane_state *intel_pstate =
 						to_intel_plane_state(pstate);
 
-		/* Watermarks calculated in master */
-		if (intel_pstate->slave)
-			continue;
-
-		if (intel_pstate->linked_plane)
-			ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
-		else if (intel_pstate->base.fb &&
-			 intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
-			ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
+		if (INTEL_GEN(dev_priv) >= 11)
+			ret = icl_build_plane_wm(pipe_wm, cstate, intel_pstate);
 		else
-			ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate);
-
+			ret = skl_build_plane_wm(pipe_wm, cstate, intel_pstate);
 		if (ret)
 			return ret;
 	}
@@ -5088,9 +5085,9 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
 				const struct skl_ddb_entry *entry)
 {
 	if (entry->end)
-		I915_WRITE(reg, (entry->end - 1) << 16 | entry->start);
+		I915_WRITE_FW(reg, (entry->end - 1) << 16 | entry->start);
 	else
-		I915_WRITE(reg, 0);
+		I915_WRITE_FW(reg, 0);
 }
 
 static void skl_write_wm_level(struct drm_i915_private *dev_priv,
@@ -5105,19 +5102,22 @@ static void skl_write_wm_level(struct drm_i915_private *dev_priv,
 		val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
 	}
 
-	I915_WRITE(reg, val);
+	I915_WRITE_FW(reg, val);
 }
 
-static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
-			       const struct skl_plane_wm *wm,
-			       const struct skl_ddb_allocation *ddb,
-			       enum plane_id plane_id)
+void skl_write_plane_wm(struct intel_plane *plane,
+			const struct intel_crtc_state *crtc_state)
 {
-	struct drm_crtc *crtc = &intel_crtc->base;
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
-	enum pipe pipe = intel_crtc->pipe;
+	enum plane_id plane_id = plane->id;
+	enum pipe pipe = plane->pipe;
+	const struct skl_plane_wm *wm =
+		&crtc_state->wm.skl.optimal.planes[plane_id];
+	const struct skl_ddb_entry *ddb_y =
+		&crtc_state->wm.skl.plane_ddb_y[plane_id];
+	const struct skl_ddb_entry *ddb_uv =
+		&crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
 	for (level = 0; level <= max_level; level++) {
 		skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level),
@@ -5126,29 +5126,32 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
 			   &wm->trans_wm);
 
-	if (wm->is_planar && INTEL_GEN(dev_priv) < 11) {
-		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
-				    &ddb->uv_plane[pipe][plane_id]);
+	if (INTEL_GEN(dev_priv) >= 11) {
 		skl_ddb_entry_write(dev_priv,
-				    PLANE_NV12_BUF_CFG(pipe, plane_id),
-				    &ddb->plane[pipe][plane_id]);
-	} else {
-		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
-				    &ddb->plane[pipe][plane_id]);
-		if (INTEL_GEN(dev_priv) < 11)
-			I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
+				    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
+		return;
 	}
+
+	if (wm->is_planar)
+		swap(ddb_y, ddb_uv);
+
+	skl_ddb_entry_write(dev_priv,
+			    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
+	skl_ddb_entry_write(dev_priv,
+			    PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv);
 }
 
-static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
-				const struct skl_plane_wm *wm,
-				const struct skl_ddb_allocation *ddb)
+void skl_write_cursor_wm(struct intel_plane *plane,
+			 const struct intel_crtc_state *crtc_state)
 {
-	struct drm_crtc *crtc = &intel_crtc->base;
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
-	enum pipe pipe = intel_crtc->pipe;
+	enum plane_id plane_id = plane->id;
+	enum pipe pipe = plane->pipe;
+	const struct skl_plane_wm *wm =
+		&crtc_state->wm.skl.optimal.planes[plane_id];
+	const struct skl_ddb_entry *ddb =
+		&crtc_state->wm.skl.plane_ddb_y[plane_id];
 
 	for (level = 0; level <= max_level; level++) {
 		skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
@@ -5156,8 +5159,7 @@ static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
 	}
 	skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm);
 
-	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
-			    &ddb->plane[pipe][PLANE_CURSOR]);
+	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb);
 }
 
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
@@ -5198,13 +5200,12 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
 static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
 			      const struct skl_pipe_wm *old_pipe_wm,
 			      struct skl_pipe_wm *pipe_wm, /* out */
-			      struct skl_ddb_allocation *ddb, /* out */
 			      bool *changed /* out */)
 {
 	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
 	int ret;
 
-	ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
+	ret = skl_build_pipe_wm(intel_cstate, pipe_wm);
 	if (ret)
 		return ret;
 
@@ -5230,42 +5231,29 @@ pipes_modified(struct drm_atomic_state *state)
 }
 
 static int
-skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
+skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
+			    struct intel_crtc_state *new_crtc_state)
 {
-	struct drm_atomic_state *state = cstate->base.state;
-	struct drm_device *dev = state->dev;
-	struct drm_crtc *crtc = cstate->base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
-	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
-	struct drm_plane *plane;
-	enum pipe pipe = intel_crtc->pipe;
+	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_plane *plane;
 
-	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
-		struct drm_plane_state *plane_state;
-		struct intel_plane *linked;
-		enum plane_id plane_id = to_intel_plane(plane)->id;
+	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+		struct intel_plane_state *plane_state;
+		enum plane_id plane_id = plane->id;
 
-		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
-					&new_ddb->plane[pipe][plane_id]) &&
-		    skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
-					&new_ddb->uv_plane[pipe][plane_id]))
+		if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
+					&new_crtc_state->wm.skl.plane_ddb_y[plane_id]) &&
+		    skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id],
+					&new_crtc_state->wm.skl.plane_ddb_uv[plane_id]))
 			continue;
 
-		plane_state = drm_atomic_get_plane_state(state, plane);
+		plane_state = intel_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state))
 			return PTR_ERR(plane_state);
 
-		/* Make sure linked plane is updated too */
-		linked = to_intel_plane_state(plane_state)->linked_plane;
-		if (!linked)
-			continue;
-
-		plane_state = drm_atomic_get_plane_state(state, &linked->base);
-		if (IS_ERR(plane_state))
-			return PTR_ERR(plane_state);
+		new_crtc_state->update_planes |= BIT(plane_id);
 	}
 
 	return 0;
@@ -5277,18 +5265,21 @@ skl_compute_ddb(struct drm_atomic_state *state)
 	const struct drm_i915_private *dev_priv = to_i915(state->dev);
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
+	struct intel_crtc_state *old_crtc_state;
+	struct intel_crtc_state *new_crtc_state;
 	struct intel_crtc *crtc;
-	struct intel_crtc_state *cstate;
 	int ret, i;
 
 	memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
 
-	for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) {
-		ret = skl_allocate_pipe_ddb(cstate, ddb);
+	for_each_oldnew_intel_crtc_in_state(intel_state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		ret = skl_allocate_pipe_ddb(new_crtc_state, ddb);
 		if (ret)
 			return ret;
 
-		ret = skl_ddb_add_affected_planes(cstate);
+		ret = skl_ddb_add_affected_planes(old_crtc_state,
+						  new_crtc_state);
 		if (ret)
 			return ret;
 	}
@@ -5297,36 +5288,29 @@ skl_compute_ddb(struct drm_atomic_state *state)
 }
 
 static void
-skl_print_wm_changes(const struct drm_atomic_state *state)
+skl_print_wm_changes(struct intel_atomic_state *state)
 {
-	const struct drm_device *dev = state->dev;
-	const struct drm_i915_private *dev_priv = to_i915(dev);
-	const struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(state);
-	const struct drm_crtc *crtc;
-	const struct drm_crtc_state *cstate;
-	const struct intel_plane *intel_plane;
-	const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb;
-	const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	const struct intel_crtc_state *old_crtc_state;
+	const struct intel_crtc_state *new_crtc_state;
+	struct intel_plane *plane;
+	struct intel_crtc *crtc;
 	int i;
 
-	for_each_new_crtc_in_state(state, crtc, cstate, i) {
-		const struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-		enum pipe pipe = intel_crtc->pipe;
-
-		for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
-			enum plane_id plane_id = intel_plane->id;
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+			enum plane_id plane_id = plane->id;
 			const struct skl_ddb_entry *old, *new;
 
-			old = &old_ddb->plane[pipe][plane_id];
-			new = &new_ddb->plane[pipe][plane_id];
+			old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id];
+			new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id];
 
 			if (skl_ddb_entry_equal(old, new))
 				continue;
 
 			DRM_DEBUG_KMS("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n",
-				      intel_plane->base.base.id,
-				      intel_plane->base.name,
+				      plane->base.base.id, plane->base.name,
 				      old->start, old->end,
 				      new->start, new->end);
 		}
@@ -5462,8 +5446,7 @@ skl_compute_wm(struct drm_atomic_state *state)
 			&to_intel_crtc_state(crtc->state)->wm.skl.optimal;
 
 		pipe_wm = &intel_cstate->wm.skl.optimal;
-		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm,
-					 &results->ddb, &changed);
+		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, &changed);
 		if (ret)
 			return ret;
 
@@ -5477,7 +5460,7 @@ skl_compute_wm(struct drm_atomic_state *state)
 		intel_cstate->update_wm_pre = true;
 	}
 
-	skl_print_wm_changes(state);
+	skl_print_wm_changes(intel_state);
 
 	return 0;
 }
@@ -5488,23 +5471,12 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
 	struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
-	const struct skl_ddb_allocation *ddb = &state->wm_results.ddb;
 	enum pipe pipe = crtc->pipe;
-	enum plane_id plane_id;
 
 	if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base)))
 		return;
 
 	I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime);
-
-	for_each_plane_id_on_crtc(crtc, plane_id) {
-		if (plane_id != PLANE_CURSOR)
-			skl_write_plane_wm(crtc, &pipe_wm->planes[plane_id],
-					   ddb, plane_id);
-		else
-			skl_write_cursor_wm(crtc, &pipe_wm->planes[plane_id],
-					    ddb);
-	}
 }
 
 static void skl_initial_wm(struct intel_atomic_state *state,
@@ -5514,8 +5486,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct skl_ddb_values *results = &state->wm_results;
-	struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw;
-	enum pipe pipe = intel_crtc->pipe;
 
 	if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0)
 		return;
@@ -5525,11 +5495,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
 	if (cstate->base.active_changed)
 		skl_atomic_update_crtc_wm(state, cstate);
 
-	memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe],
-	       sizeof(hw_vals->ddb.uv_plane[pipe]));
-	memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe],
-	       sizeof(hw_vals->ddb.plane[pipe]));
-
 	mutex_unlock(&dev_priv->wm.wm_mutex);
 }
 
@@ -5680,13 +5645,6 @@ void skl_wm_get_hw_state(struct drm_device *dev)
 	if (dev_priv->active_crtcs) {
 		/* Fully recompute DDB on first atomic commit */
 		dev_priv->wm.distrust_bios_wm = true;
-	} else {
-		/*
-		 * Easy/common case; just sanitize DDB now if everything off
-		 * Keep dbuf slice info intact
-		 */
-		memset(ddb->plane, 0, sizeof(ddb->plane));
-		memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane));
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 99d4396cac00..126a51a7b376 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -535,6 +535,8 @@ skl_program_plane(struct intel_plane *plane,
 	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
 		icl_program_input_csc_coeff(crtc_state, plane_state);
 
+	skl_write_plane_wm(plane, crtc_state);
+
 	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
 	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
 	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
@@ -597,6 +599,8 @@ skl_disable_plane(struct intel_plane *plane,
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
+	skl_write_plane_wm(plane, crtc_state);
+
 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
 
-- 
2.18.1

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

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

* Re: [PATCH 03/14] drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler()
  2018-11-01 15:05 ` [PATCH 03/14] drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler() Ville Syrjala
@ 2018-11-07 18:53   ` Rodrigo Vivi
  0 siblings, 0 replies; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 18:53 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:54PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> If we don't need the PS_PWR_GATE write when programming the
> pipe scaler I don't see why we'd need it for plane scalers either.
> Just remove it.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>


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

> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index a1e215636331..399d44c57a7d 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -354,7 +354,6 @@ skl_program_scaler(struct intel_plane *plane,
>  
>  	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
>  		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
> -	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
>  	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
>  		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
>  	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully (rev6)
  2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
                   ` (18 preceding siblings ...)
  2018-11-01 18:13 ` ✓ Fi.CI.IGT: " Patchwork
@ 2018-11-07 19:01 ` Patchwork
  19 siblings, 0 replies; 57+ messages in thread
From: Patchwork @ 2018-11-07 19:01 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Program SKL+ watermarks/ddb more carefully (rev6)
URL   : https://patchwork.freedesktop.org/series/51878/
State : failure

== Summary ==

Applying: drm/i915: Nuke posting reads from plane update/disable funcs
error: sha1 information is lacking or useless (drivers/gpu/drm/i915/intel_display.c).
error: could not build fake ancestor
Patch failed at 0001 drm/i915: Nuke posting reads from plane update/disable funcs
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

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

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

* Re: [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup
  2018-11-01 15:05 ` [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup Ville Syrjala
  2018-11-07 18:41   ` [PATCH v2 " Ville Syrjala
@ 2018-11-07 19:55   ` Rodrigo Vivi
  2018-11-07 20:56     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 19:55 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:55PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Due to the constant alpha we're going to have to program two of
> the the tree keying registers anyway, so might as well always
> program all three.
> 
> And parametrize the plane constant alpha define while at it.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

I'm not 100% confident we can just ignore the key->flags,
but I couldn't convince me that we need that either.

And clean-up by itself looks good, so:

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



> ---
>  drivers/gpu/drm/i915/i915_reg.h     |  2 +-
>  drivers/gpu/drm/i915/intel_sprite.c | 22 +++++++++-------------
>  2 files changed, 10 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 8d089ef848b2..b6ee863b5df2 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6545,7 +6545,7 @@ enum {
>  #define  PLANE_KEYMSK_ALPHA_ENABLE		(1 << 31)
>  #define _PLANE_KEYMAX_1_A			0x701a0
>  #define _PLANE_KEYMAX_2_A			0x702a0
> -#define  PLANE_KEYMAX_ALPHA_SHIFT		24
> +#define  PLANE_KEYMAX_ALPHA(a)			((a) << 24)
>  #define _PLANE_AUX_DIST_1_A			0x701c0
>  #define _PLANE_AUX_DIST_2_A			0x702c0
>  #define _PLANE_AUX_OFFSET_1_A			0x701c4
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 399d44c57a7d..b36238282b4e 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -382,31 +382,27 @@ skl_program_plane(struct intel_plane *plane,
>  	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
>  	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
>  	struct intel_plane *linked = plane_state->linked_plane;
> +	u8 alpha = plane_state->base.alpha >> 8;
>  	unsigned long irqflags;
> -	u32 keymsk = 0, keymax = 0;
> +	u32 keymsk, keymax;
>  
>  	/* Sizes are 0 based */
>  	src_w--;
>  	src_h--;
>  
> +	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
> +
> +	keymsk = key->channel_mask & 0x3ffffff;
> +	if (alpha < 0xff)
> +		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
> +
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
>  		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
>  			      plane_state->color_ctl);
>  
> -	if (key->flags) {
> -		I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> -
> -		keymax |= key->max_value & 0xffffff;
> -		keymsk |= key->channel_mask & 0x3ffffff;
> -	}
> -
> -	keymax |= (plane_state->base.alpha >> 8) << PLANE_KEYMAX_ALPHA_SHIFT;
> -
> -	if (plane_state->base.alpha < 0xff00)
> -		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
> -
> +	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
>  	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
>  	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/14] drm/i915: Clean up skl+ PLANE_POS vs. scaler handling
  2018-11-01 15:05 ` [PATCH 05/14] drm/i915: Clean up skl+ PLANE_POS vs. scaler handling Ville Syrjala
@ 2018-11-07 19:56   ` Rodrigo Vivi
  0 siblings, 0 replies; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 19:56 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:56PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> On skl+ the scaler (when enabled) will take care of the plane output
> position. Make the code less ugly by just setting crtc_x/y to 0
> when the scaler is enabled.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

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

> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index b36238282b4e..8a40879abe30 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -396,6 +396,12 @@ skl_program_plane(struct intel_plane *plane,
>  	if (alpha < 0xff)
>  		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
>  
> +	/* The scaler will handle the output position */
> +	if (plane_state->scaler_id >= 0) {
> +		crtc_x = 0;
> +		crtc_y = 0;
> +	}
> +
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> @@ -438,14 +444,10 @@ skl_program_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
>  	}
>  
> -	if (plane_state->scaler_id >= 0) {
> -		if (!slave)
> -			skl_program_scaler(plane, crtc_state, plane_state);
> +	if (!slave && plane_state->scaler_id >= 0)
> +		skl_program_scaler(plane, crtc_state, plane_state);
>  
> -		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
> -	} else {
> -		I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> -	}
> +	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
>  
>  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup
  2018-11-07 19:55   ` [PATCH " Rodrigo Vivi
@ 2018-11-07 20:56     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-07 20:56 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 11:55:27AM -0800, Rodrigo Vivi wrote:
> On Thu, Nov 01, 2018 at 05:05:55PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Due to the constant alpha we're going to have to program two of
> > the the tree keying registers anyway, so might as well always
> > program all three.
> > 
> > And parametrize the plane constant alpha define while at it.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> I'm not 100% confident we can just ignore the key->flags,
> but I couldn't convince me that we need that either.

The colorkey registers should be nops unless we enable the relevant bits
in the control register (skl_plane_ctl()). If not we'd already have a
bug because we were leaving stale values in those registers when
colorkeying was not enabled.

> 
> And clean-up by itself looks good, so:
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> 
> 
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h     |  2 +-
> >  drivers/gpu/drm/i915/intel_sprite.c | 22 +++++++++-------------
> >  2 files changed, 10 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 8d089ef848b2..b6ee863b5df2 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -6545,7 +6545,7 @@ enum {
> >  #define  PLANE_KEYMSK_ALPHA_ENABLE		(1 << 31)
> >  #define _PLANE_KEYMAX_1_A			0x701a0
> >  #define _PLANE_KEYMAX_2_A			0x702a0
> > -#define  PLANE_KEYMAX_ALPHA_SHIFT		24
> > +#define  PLANE_KEYMAX_ALPHA(a)			((a) << 24)
> >  #define _PLANE_AUX_DIST_1_A			0x701c0
> >  #define _PLANE_AUX_DIST_2_A			0x702c0
> >  #define _PLANE_AUX_OFFSET_1_A			0x701c4
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 399d44c57a7d..b36238282b4e 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -382,31 +382,27 @@ skl_program_plane(struct intel_plane *plane,
> >  	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
> >  	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
> >  	struct intel_plane *linked = plane_state->linked_plane;
> > +	u8 alpha = plane_state->base.alpha >> 8;
> >  	unsigned long irqflags;
> > -	u32 keymsk = 0, keymax = 0;
> > +	u32 keymsk, keymax;
> >  
> >  	/* Sizes are 0 based */
> >  	src_w--;
> >  	src_h--;
> >  
> > +	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
> > +
> > +	keymsk = key->channel_mask & 0x3ffffff;
> > +	if (alpha < 0xff)
> > +		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
> > +
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> >  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> >  		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> >  			      plane_state->color_ctl);
> >  
> > -	if (key->flags) {
> > -		I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> > -
> > -		keymax |= key->max_value & 0xffffff;
> > -		keymsk |= key->channel_mask & 0x3ffffff;
> > -	}
> > -
> > -	keymax |= (plane_state->base.alpha >> 8) << PLANE_KEYMAX_ALPHA_SHIFT;
> > -
> > -	if (plane_state->base.alpha < 0xff00)
> > -		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
> > -
> > +	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> >  	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> >  	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> >  
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic
  2018-11-01 15:05 ` [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic Ville Syrjala
  2018-11-07 18:42   ` [PATCH v2 " Ville Syrjala
@ 2018-11-07 21:26   ` Rodrigo Vivi
  2018-11-07 21:38     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 21:26 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:57PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Some observations about the plane registers:
> - the control register will self-arm if the plane is not already
>   enabled, thus we want to write it as close to (or ideally after)
>   the surface register
> - tileoff/linoff/offset/aux_offset are self-arming as well so we want
>   them close to the surface register as well
> - color keying registers we maybe self arming before SKL. Not 100%
>   sure but we can try to keep them near to the surface register
>   as well
> - chv pipe b csc register are double buffered but self arming so
>   moving them down a bit
> - the rest should be mostly armed by the surface register so we can
>   safely write them first, and to just for some consistency let's try
>   to follow keep them in order based on the register offset
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c |  40 +++++-----
>  drivers/gpu/drm/i915/intel_sprite.c  | 114 +++++++++++++++------------
>  2 files changed, 86 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c5ce3892d583..9521cff5fb44 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3328,7 +3328,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
>  	u32 linear_offset;
>  	u32 dspcntr = plane_state->ctl;
> -	i915_reg_t reg = DSPCNTR(i9xx_plane);
>  	int x = plane_state->color_plane[0].x;
>  	int y = plane_state->color_plane[0].y;
>  	unsigned long irqflags;
> @@ -3343,41 +3342,45 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
> +
>  	if (INTEL_GEN(dev_priv) < 4) {
>  		/* pipesrc and dspsize control the size that is scaled from,
>  		 * which should always be the user's requested size.
>  		 */
> +		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
>  		I915_WRITE_FW(DSPSIZE(i9xx_plane),
>  			      ((crtc_state->pipe_src_h - 1) << 16) |
>  			      (crtc_state->pipe_src_w - 1));
> -		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
>  	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
> +		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
>  		I915_WRITE_FW(PRIMSIZE(i9xx_plane),
>  			      ((crtc_state->pipe_src_h - 1) << 16) |
>  			      (crtc_state->pipe_src_w - 1));
> -		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
>  		I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
>  	}
>  
> -	I915_WRITE_FW(reg, dspcntr);
> -
> -	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> -		I915_WRITE_FW(DSPSURF(i9xx_plane),
> -			      intel_plane_ggtt_offset(plane_state) +
> -			      dspaddr_offset);
>  		I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
>  	} else if (INTEL_GEN(dev_priv) >= 4) {
> +		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> +		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> +	}
> +
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
> +	I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
> +	if (INTEL_GEN(dev_priv) >= 4)
>  		I915_WRITE_FW(DSPSURF(i9xx_plane),
>  			      intel_plane_ggtt_offset(plane_state) +
>  			      dspaddr_offset);
> -		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> -		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> -	} else {
> +	else
>  		I915_WRITE_FW(DSPADDR(i9xx_plane),
>  			      intel_plane_ggtt_offset(plane_state) +
>  			      dspaddr_offset);
> -	}
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -10045,8 +10048,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  	 * On some platforms writing CURCNTR first will also
>  	 * cause CURPOS to be armed by the CURBASE write.
>  	 * Without the CURCNTR write the CURPOS write would
> -	 * arm itself. Thus we always start the full update
> -	 * with a CURCNTR write.
> +	 * arm itself. Thus we always update CURCNTR before
> +	 * CURPOS.
>  	 *
>  	 * On other platforms CURPOS always requires the
>  	 * CURBASE write to arm the update. Additonally
> @@ -10056,15 +10059,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  	 * cursor that doesn't appear to move, or even change
>  	 * shape. Thus we always write CURBASE.
>  	 *
> -	 * CURCNTR and CUR_FBC_CTL are always
> -	 * armed by the CURBASE write only.
> +	 * The other registers are armed by by the CURBASE write
> +	 * except when the plane is getting enabled at which time
> +	 * the CURCNTR write arms the update.
>  	 */
>  	if (plane->cursor.base != base ||
>  	    plane->cursor.size != fbc_ctl ||
>  	    plane->cursor.cntl != cntl) {
> -		I915_WRITE_FW(CURCNTR(pipe), cntl);
>  		if (HAS_CUR_FBC(dev_priv))
>  			I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
> +		I915_WRITE_FW(CURCNTR(pipe), cntl);
>  		I915_WRITE_FW(CURPOS(pipe), pos);
>  		I915_WRITE_FW(CURBASE(pipe), base);
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 8a40879abe30..455b2d0cbaa6 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -404,24 +404,12 @@ skl_program_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> -			      plane_state->color_ctl);
> -
> -	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> -	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> -	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> -
> -	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
>  	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
> +	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
>  	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
>  	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
> -		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
> -
> -	if (INTEL_GEN(dev_priv) < 11)
> -		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> -			      (plane_state->color_plane[1].y << 16) |
> -			       plane_state->color_plane[1].x);
> +		      (plane_state->color_plane[1].offset - surf_addr) |
> +		      aux_stride);
>  
>  	if (icl_is_hdr_plane(plane)) {
>  		u32 cus_ctl = 0;
> @@ -444,15 +432,33 @@ skl_program_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
>  	}
>  
> -	if (!slave && plane_state->scaler_id >= 0)
> -		skl_program_scaler(plane, crtc_state, plane_state);
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> +			      plane_state->color_ctl);
>  
> -	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> +	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> +	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> +
> +	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
>  
> +	if (INTEL_GEN(dev_priv) < 11)
> +		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> +			      (plane_state->color_plane[1].y << 16) |
> +			      plane_state->color_plane[1].x);
> +
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + surf_addr);
>  
> +	if (!slave && plane_state->scaler_id >= 0)
> +		skl_program_scaler(plane, crtc_state, plane_state);
> +
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> @@ -690,7 +696,6 @@ vlv_update_plane(struct intel_plane *plane,
>  		 const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	enum plane_id plane_id = plane->id;
>  	u32 sprctl = plane_state->ctl;
> @@ -715,6 +720,12 @@ vlv_update_plane(struct intel_plane *plane,
>  
>  	vlv_update_clrc(plane_state);
>  
> +	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> +		      plane_state->color_plane[0].stride);
> +	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> +	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> +
>  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
>  		chv_update_csc(plane_state);
>  
> @@ -723,18 +734,15 @@ vlv_update_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
>  		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
>  	}
> -	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> -		      plane_state->color_plane[0].stride);
> -	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> -
> -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> -		I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> -	else
> -		I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
>  
> -	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> +	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> +	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
>  
> -	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
>  	I915_WRITE_FW(SPSURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> @@ -848,7 +856,6 @@ ivb_update_plane(struct intel_plane *plane,
>  		 const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	u32 sprctl = plane_state->ctl, sprscale = 0;
>  	u32 sprsurf_offset = plane_state->color_plane[0].offset;
> @@ -877,27 +884,32 @@ ivb_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> +	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> +	if (IS_IVYBRIDGE(dev_priv))
> +		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> +
>  	if (key->flags) {
>  		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
>  		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
>  		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
>  	}
>  
> -	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> -	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> -
>  	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
>  	 * register */
> -	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> +	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
>  		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
> -	else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> +	} else {
>  		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
> -	else
>  		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
> +	}
>  
> -	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> -	if (IS_IVYBRIDGE(dev_priv))
> -		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(SPRCTL(pipe), sprctl);
>  	I915_WRITE_FW(SPRSURF(pipe),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> @@ -915,7 +927,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	I915_WRITE_FW(SPRCTL(pipe), 0);
> -	/* Can't leave the scaler enabled... */
> +	/* Disable the scaler */
>  	if (IS_IVYBRIDGE(dev_priv))
>  		I915_WRITE_FW(SPRSCALE(pipe), 0);
>  	I915_WRITE_FW(SPRSURF(pipe), 0);
> @@ -1017,7 +1029,6 @@ g4x_update_plane(struct intel_plane *plane,
>  		 const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	u32 dvscntr = plane_state->ctl, dvsscale = 0;
>  	u32 dvssurf_offset = plane_state->color_plane[0].offset;
> @@ -1046,22 +1057,25 @@ g4x_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> +	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> +	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> +
>  	if (key->flags) {
>  		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
>  		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
>  		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
>  	}
>  
> -	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> -	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> -
> -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)

I believe this removed if deserves a separated patch...

the rest was hard to review, but after you pointed out how to check
on bspec the armed-by field I think it all makes sense.

> -		I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> -	else
> -		I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
> +	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> +	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
>  
> -	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> -	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
>  	I915_WRITE_FW(DVSSURF(pipe),
>  		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end
  2018-11-01 15:05 ` [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end Ville Syrjala
@ 2018-11-07 21:26   ` Rodrigo Vivi
  2018-11-08 22:06   ` Matt Roper
  1 sibling, 0 replies; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 21:26 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:58PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> The plane color correction registers are single buffered. So
> ideally we would write them at the start of vblank just after the
> double buffered plane registers have been latched. Since we have
> no convenient way to do that for now let's at least move the
> single buffered register writes to happen after the double
> buffered registers have been written.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

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

> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 455b2d0cbaa6..84c5f532fba5 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -718,8 +718,6 @@ vlv_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> -	vlv_update_clrc(plane_state);
> -
>  	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
>  		      plane_state->color_plane[0].stride);
>  	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> @@ -747,6 +745,8 @@ vlv_update_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(SPSURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
>  
> +	vlv_update_clrc(plane_state);
> +
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/14] drm/i915: Generalize skl_ddb_allocation_overlaps()
  2018-11-01 15:05 ` [PATCH 08/14] drm/i915: Generalize skl_ddb_allocation_overlaps() Ville Syrjala
@ 2018-11-07 21:28   ` Rodrigo Vivi
  0 siblings, 0 replies; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 21:28 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:59PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Make skl_ddb_allocation_overlaps() useful for other callers
> besides skl_update_crtcs(). We'll need it to do plane updates
> as well.
> 
> And while we're here we can reduce the stack utilization a
> bit by noting that each struct skl_ddb_entry is 4 bytes whereas
> a pointer to one is 8 bytes (on 64bit). So we'll switch to an
> array of structs from the array of pointers we used before.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

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

> ---
>  drivers/gpu/drm/i915/intel_display.c | 12 +++++-------
>  drivers/gpu/drm/i915/intel_drv.h     |  7 +++----
>  drivers/gpu/drm/i915/intel_pm.c      | 15 +++++++--------
>  3 files changed, 15 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9521cff5fb44..852b5897e80b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12678,13 +12678,12 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
>  	int i;
>  	u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
>  	u8 required_slices = intel_state->wm_results.ddb.enabled_slices;
> -
> -	const struct skl_ddb_entry *entries[I915_MAX_PIPES] = {};
> +	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
>  
>  	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
>  		/* ignore allocations for crtc's that have been turned off. */
>  		if (new_crtc_state->active)
> -			entries[i] = &to_intel_crtc_state(old_crtc_state)->wm.skl.ddb;
> +			entries[i] = to_intel_crtc_state(old_crtc_state)->wm.skl.ddb;
>  
>  	/* If 2nd DBuf slice required, enable it here */
>  	if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices)
> @@ -12710,14 +12709,13 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
>  			if (updated & cmask || !cstate->base.active)
>  				continue;
>  
> -			if (skl_ddb_allocation_overlaps(dev_priv,
> +			if (skl_ddb_allocation_overlaps(&cstate->wm.skl.ddb,
>  							entries,
> -							&cstate->wm.skl.ddb,
> -							i))
> +							INTEL_INFO(dev_priv)->num_pipes, i))
>  				continue;
>  
>  			updated |= cmask;
> -			entries[i] = &cstate->wm.skl.ddb;
> +			entries[i] = cstate->wm.skl.ddb;
>  
>  			/*
>  			 * If this is an already active pipe, it's DDB changed,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index c5acc5f0d518..5331bbed5e8c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -2182,10 +2182,9 @@ int intel_enable_sagv(struct drm_i915_private *dev_priv);
>  int intel_disable_sagv(struct drm_i915_private *dev_priv);
>  bool skl_wm_level_equals(const struct skl_wm_level *l1,
>  			 const struct skl_wm_level *l2);
> -bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv,
> -				 const struct skl_ddb_entry **entries,
> -				 const struct skl_ddb_entry *ddb,
> -				 int ignore);
> +bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
> +				 const struct skl_ddb_entry entries[],
> +				 int num_entries, int ignore_idx);
>  bool ilk_disable_lp_wm(struct drm_device *dev);
>  int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  				  struct intel_crtc_state *cstate);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 82c82e233154..6fa1634e2db5 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5197,16 +5197,15 @@ static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a,
>  	return a->start < b->end && b->start < a->end;
>  }
>  
> -bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv,
> -				 const struct skl_ddb_entry **entries,
> -				 const struct skl_ddb_entry *ddb,
> -				 int ignore)
> +bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
> +				 const struct skl_ddb_entry entries[],
> +				 int num_entries, int ignore_idx)
>  {
> -	enum pipe pipe;
> +	int i;
>  
> -	for_each_pipe(dev_priv, pipe) {
> -		if (pipe != ignore && entries[pipe] &&
> -		    skl_ddb_entries_overlap(ddb, entries[pipe]))
> +	for (i = 0; i < num_entries; i++) {
> +		if (i != ignore_idx &&
> +		    skl_ddb_entries_overlap(ddb, &entries[i]))
>  			return true;
>  	}
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic
  2018-11-07 21:26   ` [PATCH " Rodrigo Vivi
@ 2018-11-07 21:38     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-07 21:38 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 01:26:18PM -0800, Rodrigo Vivi wrote:
> On Thu, Nov 01, 2018 at 05:05:57PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Some observations about the plane registers:
> > - the control register will self-arm if the plane is not already
> >   enabled, thus we want to write it as close to (or ideally after)
> >   the surface register
> > - tileoff/linoff/offset/aux_offset are self-arming as well so we want
> >   them close to the surface register as well
> > - color keying registers we maybe self arming before SKL. Not 100%
> >   sure but we can try to keep them near to the surface register
> >   as well
> > - chv pipe b csc register are double buffered but self arming so
> >   moving them down a bit
> > - the rest should be mostly armed by the surface register so we can
> >   safely write them first, and to just for some consistency let's try
> >   to follow keep them in order based on the register offset
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c |  40 +++++-----
> >  drivers/gpu/drm/i915/intel_sprite.c  | 114 +++++++++++++++------------
> >  2 files changed, 86 insertions(+), 68 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index c5ce3892d583..9521cff5fb44 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3328,7 +3328,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
> >  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> >  	u32 linear_offset;
> >  	u32 dspcntr = plane_state->ctl;
> > -	i915_reg_t reg = DSPCNTR(i9xx_plane);
> >  	int x = plane_state->color_plane[0].x;
> >  	int y = plane_state->color_plane[0].y;
> >  	unsigned long irqflags;
> > @@ -3343,41 +3342,45 @@ static void i9xx_update_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
> > +
> >  	if (INTEL_GEN(dev_priv) < 4) {
> >  		/* pipesrc and dspsize control the size that is scaled from,
> >  		 * which should always be the user's requested size.
> >  		 */
> > +		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
> >  		I915_WRITE_FW(DSPSIZE(i9xx_plane),
> >  			      ((crtc_state->pipe_src_h - 1) << 16) |
> >  			      (crtc_state->pipe_src_w - 1));
> > -		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
> >  	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
> > +		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
> >  		I915_WRITE_FW(PRIMSIZE(i9xx_plane),
> >  			      ((crtc_state->pipe_src_h - 1) << 16) |
> >  			      (crtc_state->pipe_src_w - 1));
> > -		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
> >  		I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
> >  	}
> >  
> > -	I915_WRITE_FW(reg, dspcntr);
> > -
> > -	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
> >  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> > -		I915_WRITE_FW(DSPSURF(i9xx_plane),
> > -			      intel_plane_ggtt_offset(plane_state) +
> > -			      dspaddr_offset);
> >  		I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
> >  	} else if (INTEL_GEN(dev_priv) >= 4) {
> > +		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> > +		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> > +	}
> > +
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> > +	I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
> > +	if (INTEL_GEN(dev_priv) >= 4)
> >  		I915_WRITE_FW(DSPSURF(i9xx_plane),
> >  			      intel_plane_ggtt_offset(plane_state) +
> >  			      dspaddr_offset);
> > -		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> > -		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> > -	} else {
> > +	else
> >  		I915_WRITE_FW(DSPADDR(i9xx_plane),
> >  			      intel_plane_ggtt_offset(plane_state) +
> >  			      dspaddr_offset);
> > -	}
> >  
> >  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> >  }
> > @@ -10045,8 +10048,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  	 * On some platforms writing CURCNTR first will also
> >  	 * cause CURPOS to be armed by the CURBASE write.
> >  	 * Without the CURCNTR write the CURPOS write would
> > -	 * arm itself. Thus we always start the full update
> > -	 * with a CURCNTR write.
> > +	 * arm itself. Thus we always update CURCNTR before
> > +	 * CURPOS.
> >  	 *
> >  	 * On other platforms CURPOS always requires the
> >  	 * CURBASE write to arm the update. Additonally
> > @@ -10056,15 +10059,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  	 * cursor that doesn't appear to move, or even change
> >  	 * shape. Thus we always write CURBASE.
> >  	 *
> > -	 * CURCNTR and CUR_FBC_CTL are always
> > -	 * armed by the CURBASE write only.
> > +	 * The other registers are armed by by the CURBASE write
> > +	 * except when the plane is getting enabled at which time
> > +	 * the CURCNTR write arms the update.
> >  	 */
> >  	if (plane->cursor.base != base ||
> >  	    plane->cursor.size != fbc_ctl ||
> >  	    plane->cursor.cntl != cntl) {
> > -		I915_WRITE_FW(CURCNTR(pipe), cntl);
> >  		if (HAS_CUR_FBC(dev_priv))
> >  			I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
> > +		I915_WRITE_FW(CURCNTR(pipe), cntl);
> >  		I915_WRITE_FW(CURPOS(pipe), pos);
> >  		I915_WRITE_FW(CURBASE(pipe), base);
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 8a40879abe30..455b2d0cbaa6 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -404,24 +404,12 @@ skl_program_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> > -		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> > -			      plane_state->color_ctl);
> > -
> > -	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> > -	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> > -	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> > -
> > -	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
> >  	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
> > +	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> >  	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
> >  	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
> > -		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
> > -
> > -	if (INTEL_GEN(dev_priv) < 11)
> > -		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> > -			      (plane_state->color_plane[1].y << 16) |
> > -			       plane_state->color_plane[1].x);
> > +		      (plane_state->color_plane[1].offset - surf_addr) |
> > +		      aux_stride);
> >  
> >  	if (icl_is_hdr_plane(plane)) {
> >  		u32 cus_ctl = 0;
> > @@ -444,15 +432,33 @@ skl_program_plane(struct intel_plane *plane,
> >  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
> >  	}
> >  
> > -	if (!slave && plane_state->scaler_id >= 0)
> > -		skl_program_scaler(plane, crtc_state, plane_state);
> > +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> > +		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> > +			      plane_state->color_ctl);
> >  
> > -	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> > +	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> > +	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> > +
> > +	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
> >  
> > +	if (INTEL_GEN(dev_priv) < 11)
> > +		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> > +			      (plane_state->color_plane[1].y << 16) |
> > +			      plane_state->color_plane[1].x);
> > +
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
> >  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
> >  		      intel_plane_ggtt_offset(plane_state) + surf_addr);
> >  
> > +	if (!slave && plane_state->scaler_id >= 0)
> > +		skl_program_scaler(plane, crtc_state, plane_state);
> > +
> >  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> >  }
> >  
> > @@ -690,7 +696,6 @@ vlv_update_plane(struct intel_plane *plane,
> >  		 const struct intel_plane_state *plane_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > -	const struct drm_framebuffer *fb = plane_state->base.fb;
> >  	enum pipe pipe = plane->pipe;
> >  	enum plane_id plane_id = plane->id;
> >  	u32 sprctl = plane_state->ctl;
> > @@ -715,6 +720,12 @@ vlv_update_plane(struct intel_plane *plane,
> >  
> >  	vlv_update_clrc(plane_state);
> >  
> > +	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> > +		      plane_state->color_plane[0].stride);
> > +	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> > +	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> > +
> >  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
> >  		chv_update_csc(plane_state);
> >  
> > @@ -723,18 +734,15 @@ vlv_update_plane(struct intel_plane *plane,
> >  		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
> >  		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
> >  	}
> > -	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> > -		      plane_state->color_plane[0].stride);
> > -	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> > -
> > -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> > -		I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> > -	else
> > -		I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
> >  
> > -	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> > +	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> > +	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
> >  
> > -	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
> >  	I915_WRITE_FW(SPSURF(pipe, plane_id),
> >  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> > @@ -848,7 +856,6 @@ ivb_update_plane(struct intel_plane *plane,
> >  		 const struct intel_plane_state *plane_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > -	const struct drm_framebuffer *fb = plane_state->base.fb;
> >  	enum pipe pipe = plane->pipe;
> >  	u32 sprctl = plane_state->ctl, sprscale = 0;
> >  	u32 sprsurf_offset = plane_state->color_plane[0].offset;
> > @@ -877,27 +884,32 @@ ivb_update_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> > +	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> > +	if (IS_IVYBRIDGE(dev_priv))
> > +		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> > +
> >  	if (key->flags) {
> >  		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
> >  		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
> >  		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
> >  	}
> >  
> > -	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> > -	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> > -
> >  	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
> >  	 * register */
> > -	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> > +	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> >  		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
> > -	else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> > +	} else {
> >  		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
> > -	else
> >  		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
> > +	}
> >  
> > -	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> > -	if (IS_IVYBRIDGE(dev_priv))
> > -		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(SPRCTL(pipe), sprctl);
> >  	I915_WRITE_FW(SPRSURF(pipe),
> >  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> > @@ -915,7 +927,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> >  	I915_WRITE_FW(SPRCTL(pipe), 0);
> > -	/* Can't leave the scaler enabled... */
> > +	/* Disable the scaler */
> >  	if (IS_IVYBRIDGE(dev_priv))
> >  		I915_WRITE_FW(SPRSCALE(pipe), 0);
> >  	I915_WRITE_FW(SPRSURF(pipe), 0);
> > @@ -1017,7 +1029,6 @@ g4x_update_plane(struct intel_plane *plane,
> >  		 const struct intel_plane_state *plane_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > -	const struct drm_framebuffer *fb = plane_state->base.fb;
> >  	enum pipe pipe = plane->pipe;
> >  	u32 dvscntr = plane_state->ctl, dvsscale = 0;
> >  	u32 dvssurf_offset = plane_state->color_plane[0].offset;
> > @@ -1046,22 +1057,25 @@ g4x_update_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> > +	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> > +	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> > +
> >  	if (key->flags) {
> >  		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
> >  		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
> >  		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
> >  	}
> >  
> > -	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> > -	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> > -
> > -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> 
> I believe this removed if deserves a separated patch...

Forgot I even did that :) But yeah, I'll split that out into a separate
patch.

> 
> the rest was hard to review, but after you pointed out how to check
> on bspec the armed-by field I think it all makes sense.

Cool. And sorry for the messy patch. Couldn't think of a nice way to
split it except maybe "one register at a time" which would have been
a bit much perhaps.

> 
> > -		I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> > -	else
> > -		I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
> > +	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> > +	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
> >  
> > -	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> > -	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
> >  	I915_WRITE_FW(DVSSURF(pipe),
> >  		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask
  2018-11-01 15:06 ` [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask Ville Syrjala
@ 2018-11-07 21:49   ` Rodrigo Vivi
  2018-11-08 11:32     ` Ville Syrjälä
  2018-11-08 23:22   ` Matt Roper
  1 sibling, 1 reply; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 21:49 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:06:00PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Keep track which planes need updating during the commit. For now this
> is just (was_visible || is_visible) but I'll have need to update
> invisible planes later on for skl plane ddbs and for pre-skl pipe
> gamma/csc control (which lives in the primary plane control register).
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c       | 1 +
>  drivers/gpu/drm/i915/intel_atomic_plane.c | 8 ++++----
>  drivers/gpu/drm/i915/intel_display.c      | 5 ++++-
>  drivers/gpu/drm/i915/intel_drv.h          | 3 +++
>  4 files changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index a5a2c8fe58a7..8cb02f28d30c 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -184,6 +184,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	crtc_state->fifo_changed = false;
>  	crtc_state->wm.need_postvbl_update = false;
>  	crtc_state->fb_bits = 0;
> +	crtc_state->update_planes = 0;
>  
>  	return &crtc_state->base;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index 7d3685075201..010269a12390 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -137,6 +137,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  	if (state->visible && state->fb->format->format == DRM_FORMAT_NV12)
>  		crtc_state->nv12_planes |= BIT(intel_plane->id);
>  
> +	if (state->visible || old_plane_state->base.visible)
> +		crtc_state->update_planes |= BIT(intel_plane->id);
> +
>  	return intel_plane_atomic_calc_changes(old_crtc_state,
>  					       &crtc_state->base,
>  					       old_plane_state,
> @@ -171,14 +174,11 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>  				 struct intel_crtc_state *old_crtc_state,
>  				 struct intel_crtc_state *new_crtc_state)
>  {
> +	u32 update_mask = new_crtc_state->update_planes;
>  	struct intel_plane_state *new_plane_state;
>  	struct intel_plane *plane;
> -	u32 update_mask;
>  	int i;
>  
> -	update_mask = old_crtc_state->active_planes;
> -	update_mask |= new_crtc_state->active_planes;
> -

maybe this useless update_mask removal deserved a separated patch,
but not a big deal...

>  	for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) {
>  		if (crtc->pipe != plane->pipe ||
>  		    !(update_mask & BIT(plane->id)))
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 852b5897e80b..33d73915b73e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10797,8 +10797,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  			continue;
>  
>  		plane_state->linked_plane = NULL;
> -		if (plane_state->slave && !plane_state->base.visible)
> +		if (plane_state->slave && !plane_state->base.visible) {
>  			crtc_state->active_planes &= ~BIT(plane->id);
> +			crtc_state->update_planes |= BIT(plane->id);
> +		}
>  
>  		plane_state->slave = false;
>  	}
> @@ -10839,6 +10841,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  		linked_state->slave = true;
>  		linked_state->linked_plane = plane;
>  		crtc_state->active_planes |= BIT(linked->id);
> +		crtc_state->update_planes |= BIT(linked->id);
>  		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 5331bbed5e8c..7a55f5921d34 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -925,6 +925,9 @@ struct intel_crtc_state {
>  	u8 active_planes;
>  	u8 nv12_planes;
>  
> +	/* bitmask of planes that will be updated during the commit */

I noticed how bad we are with documentation compared to the rest of drm
structs :/

but I'm glad you added the explanation in the comment here.

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

> +	u8 update_planes;
> +
>  	/* HDMI scrambling status */
>  	bool hdmi_scrambling;
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane()
  2018-11-01 15:06 ` [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane() Ville Syrjala
@ 2018-11-07 22:08   ` Rodrigo Vivi
  2018-11-08 11:43     ` Ville Syrjälä
  2018-11-08 23:52   ` Matt Roper
  1 sibling, 1 reply; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 22:08 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:06:01PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We're going to need access to the new crtc state in ->disable_plane()
> for SKL+ wm/ddb programming and pre-skl pipe gamma/csc control. Pass
> the crtc state down.
> 
> We'll also try to make intel_crtc_disable_planes() drtr as much as
> it's possible. The fact that we don't have a separate crtc state
> for the disabled state when we're going to re-enable the crtc later
> means we might end up poking at a few extra planes in there. But
> that's harmless. I suppose one migth argue that we wouldn't have to
> care about proper ddb/wm/csc/gamma if the pipe is going to permanently
> disable anyway, but the state checker probably cares so we should try
> our best to make sure everything is programmed correctly even in that
> case.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  2 +-
>  drivers/gpu/drm/i915/intel_display.c      | 39 ++++++++++++++---------
>  drivers/gpu/drm/i915/intel_display.h      |  8 +++++
>  drivers/gpu/drm/i915/intel_drv.h          |  2 +-
>  drivers/gpu/drm/i915/intel_sprite.c       | 12 ++++---
>  5 files changed, 42 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index 010269a12390..69fc7010190c 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -210,7 +210,7 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>  		} else {
>  			trace_intel_disable_plane(&plane->base, crtc);
>  
> -			plane->disable_plane(plane, crtc);
> +			plane->disable_plane(plane, new_crtc_state);
>  		}
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 33d73915b73e..6088ae554e56 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2781,7 +2781,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
>  		intel_pre_disable_primary_noatomic(&crtc->base);
>  
>  	trace_intel_disable_plane(&plane->base, crtc);
> -	plane->disable_plane(plane, crtc);
> +	plane->disable_plane(plane, crtc_state);
>  }
>  
>  static void
> @@ -3386,7 +3386,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  }
>  
>  static void i9xx_disable_plane(struct intel_plane *plane,
> -			       struct intel_crtc *crtc)
> +			       const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> @@ -5421,23 +5421,32 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>  		intel_update_watermarks(crtc);
>  }
>  
> -static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask)
> +static void intel_crtc_disable_planes(struct intel_atomic_state *state,
> +				      struct intel_crtc *crtc)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	const struct intel_crtc_state *new_crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	unsigned int update_mask = new_crtc_state->update_planes;
> +	const struct intel_plane_state *old_plane_state;
>  	struct intel_plane *plane;
>  	unsigned fb_bits = 0;
> +	int i;
>  
>  	intel_crtc_dpms_overlay_disable(crtc);
>  
> -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> -		if (plane_mask & BIT(plane->id)) {
> -			plane->disable_plane(plane, crtc);
> +	for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {

why getting "i" if it is unused later?

do you have plans to reuse this for_each_old_intel_plane_in_state somewhere else?
Besides the "i" I'm not sure I liked it returning multiple things.

if we are not going to use in more places I'd prefer something more verbose
here than macromagics.

> +		if (crtc->pipe != plane->pipe ||
> +		    !(update_mask & BIT(plane->id)))
> +			continue;
> +
> +		plane->disable_plane(plane, new_crtc_state);
>  
> +		if (old_plane_state->base.visible)
>  			fb_bits |= plane->frontbuffer_bit;
> -		}
>  	}
>  
> -	intel_frontbuffer_flip(to_i915(dev), fb_bits);
> +	intel_frontbuffer_flip(dev_priv, fb_bits);
>  }
>  
>  static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc,
> @@ -9855,9 +9864,9 @@ static void i845_update_cursor(struct intel_plane *plane,
>  }
>  
>  static void i845_disable_cursor(struct intel_plane *plane,
> -				struct intel_crtc *crtc)
> +				const struct intel_crtc_state *crtc_state)
>  {
> -	i845_update_cursor(plane, NULL, NULL);
> +	i845_update_cursor(plane, crtc_state, NULL);
>  }
>  
>  static bool i845_cursor_get_hw_state(struct intel_plane *plane,
> @@ -10084,9 +10093,9 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  }
>  
>  static void i9xx_disable_cursor(struct intel_plane *plane,
> -				struct intel_crtc *crtc)
> +				const struct intel_crtc_state *crtc_state)
>  {
> -	i9xx_update_cursor(plane, NULL, NULL);
> +	i9xx_update_cursor(plane, crtc_state, NULL);
>  }
>  
>  static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
> @@ -12840,7 +12849,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
>  		intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state);
>  
>  		if (old_crtc_state->active) {
> -			intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes);
> +			intel_crtc_disable_planes(intel_state, intel_crtc);
>  
>  			/*
>  			 * We need to disable pipe CRC before disabling the pipe,
> @@ -13695,7 +13704,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
>  					  to_intel_plane_state(plane->state));
>  	} else {
>  		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> -		intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
> +		intel_plane->disable_plane(intel_plane, crtc_state);
>  	}
>  
>  	intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
> diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
> index 5d50decbcbb5..df9e6ebb27de 100644
> --- a/drivers/gpu/drm/i915/intel_display.h
> +++ b/drivers/gpu/drm/i915/intel_display.h
> @@ -382,6 +382,14 @@ struct intel_link_m_n {
>  	for_each_power_well_rev(__dev_priv, __power_well)		        \
>  		for_each_if((__power_well)->desc->domains & (__domain_mask))
>  
> +#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> +		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
> +		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
> +	     (__i)++) \
> +		for_each_if(plane)
> +
>  #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \
>  	for ((__i) = 0; \
>  	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7a55f5921d34..facd5cb0b540 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1015,7 +1015,7 @@ struct intel_plane {
>  			     const struct intel_crtc_state *crtc_state,
>  			     const struct intel_plane_state *plane_state);
>  	void (*disable_plane)(struct intel_plane *plane,
> -			      struct intel_crtc *crtc);
> +			      const struct intel_crtc_state *crtc_state);
>  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
>  	int (*check_plane)(struct intel_crtc_state *crtc_state,
>  			   struct intel_plane_state *plane_state);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 84c5f532fba5..2f97a298c24e 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -488,7 +488,8 @@ icl_update_slave(struct intel_plane *plane,
>  }
>  
>  static void
> -skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +skl_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum plane_id plane_id = plane->id;
> @@ -751,7 +752,8 @@ vlv_update_plane(struct intel_plane *plane,
>  }
>  
>  static void
> -vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +vlv_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
> @@ -918,7 +920,8 @@ ivb_update_plane(struct intel_plane *plane,
>  }
>  
>  static void
> -ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +ivb_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
> @@ -1084,7 +1087,8 @@ g4x_update_plane(struct intel_plane *plane,
>  }
>  
>  static void
> -g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +g4x_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+
  2018-11-01 15:06 ` [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+ Ville Syrjala
@ 2018-11-07 22:09   ` Rodrigo Vivi
  2018-11-09  0:01   ` Matt Roper
  1 sibling, 0 replies; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 22:09 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx


1;5202;0cOn Thu, Nov 01, 2018 at 05:06:02PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> If the level 0 latency is 0 we can't do anything. Return an error
> rather than success.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

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



> ---
>  drivers/gpu/drm/i915/intel_pm.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 6fa1634e2db5..bd5f16bc7e08 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4703,8 +4703,10 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
>  	uint32_t min_disp_buf_needed;
>  
> -	if (latency == 0 ||
> -	    !intel_wm_plane_visible(cstate, intel_pstate)) {
> +	if (latency == 0)
> +		return level == 0 ? -EINVAL : 0;
> +
> +	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
>  		result->plane_en = false;
>  		return 0;
>  	}
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations
  2018-11-01 15:06 ` [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations Ville Syrjala
  2018-11-07 18:43   ` [PATCH v2 " Ville Syrjala
@ 2018-11-07 22:11   ` Rodrigo Vivi
  2018-11-08 11:46     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Rodrigo Vivi @ 2018-11-07 22:11 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx


On Thu, Nov 01, 2018 at 05:06:03PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We memset(0) the entire watermark struct the start, so there's no
> need to clear things later on.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 20 +++++---------------
>  1 file changed, 5 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index bd5f16bc7e08..b0720994fa0a 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4706,10 +4706,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	if (latency == 0)
>  		return level == 0 ? -EINVAL : 0;
>  
> -	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
> -		result->plane_en = false;
> +	if (!intel_wm_plane_visible(cstate, intel_pstate))
>  		return 0;
> -	}
>  
>  	/* Display WA #1141: kbl,cfl */
>  	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
> @@ -4806,8 +4804,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	if ((level > 0 && res_lines > 31) ||
>  	    res_blocks >= ddb_allocation ||
>  	    min_disp_buf_needed >= ddb_allocation) {
> -		result->plane_en = false;
> -
>  		/*
>  		 * If there are no valid level 0 watermarks, then we can't
>  		 * support this display configuration.
> @@ -4831,10 +4827,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	 */
>  	if (wp->is_planar && level >= 1 &&
>  	    (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) ||
> -	     IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) {
> -		result->plane_en = false;
> +	     IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0)))

this reminds me that I probably forgot one patch behind somewhere...


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


>  		return 0;
> -	}
>  
>  	/* The number of lines are ignored for the level 0 watermark. */
>  	result->plane_res_b = res_blocks;
> @@ -4920,15 +4914,15 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
>  	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
>  
>  	if (!cstate->base.active)
> -		goto exit;
> +		return;
>  
>  	/* Transition WM are not recommended by HW team for GEN9 */
>  	if (INTEL_GEN(dev_priv) <= 9)
> -		goto exit;
> +		return;
>  
>  	/* Transition WM don't make any sense if ipc is disabled */
>  	if (!dev_priv->ipc_enabled)
> -		goto exit;
> +		return;
>  
>  	trans_min = 14;
>  	if (INTEL_GEN(dev_priv) >= 11)
> @@ -4967,11 +4961,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
>  	if (res_blocks < ddb_allocation) {
>  		trans_wm->plane_res_b = res_blocks;
>  		trans_wm->plane_en = true;
> -		return;
>  	}
> -
> -exit:
> -	trans_wm->plane_en = false;
>  }
>  
>  static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask
  2018-11-07 21:49   ` Rodrigo Vivi
@ 2018-11-08 11:32     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-08 11:32 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 01:49:39PM -0800, Rodrigo Vivi wrote:
> On Thu, Nov 01, 2018 at 05:06:00PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Keep track which planes need updating during the commit. For now this
> > is just (was_visible || is_visible) but I'll have need to update
> > invisible planes later on for skl plane ddbs and for pre-skl pipe
> > gamma/csc control (which lives in the primary plane control register).
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c       | 1 +
> >  drivers/gpu/drm/i915/intel_atomic_plane.c | 8 ++++----
> >  drivers/gpu/drm/i915/intel_display.c      | 5 ++++-
> >  drivers/gpu/drm/i915/intel_drv.h          | 3 +++
> >  4 files changed, 12 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> > index a5a2c8fe58a7..8cb02f28d30c 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -184,6 +184,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
> >  	crtc_state->fifo_changed = false;
> >  	crtc_state->wm.need_postvbl_update = false;
> >  	crtc_state->fb_bits = 0;
> > +	crtc_state->update_planes = 0;
> >  
> >  	return &crtc_state->base;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > index 7d3685075201..010269a12390 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > @@ -137,6 +137,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
> >  	if (state->visible && state->fb->format->format == DRM_FORMAT_NV12)
> >  		crtc_state->nv12_planes |= BIT(intel_plane->id);
> >  
> > +	if (state->visible || old_plane_state->base.visible)
> > +		crtc_state->update_planes |= BIT(intel_plane->id);
> > +
> >  	return intel_plane_atomic_calc_changes(old_crtc_state,
> >  					       &crtc_state->base,
> >  					       old_plane_state,
> > @@ -171,14 +174,11 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
> >  				 struct intel_crtc_state *old_crtc_state,
> >  				 struct intel_crtc_state *new_crtc_state)
> >  {
> > +	u32 update_mask = new_crtc_state->update_planes;
> >  	struct intel_plane_state *new_plane_state;
> >  	struct intel_plane *plane;
> > -	u32 update_mask;
> >  	int i;
> >  
> > -	update_mask = old_crtc_state->active_planes;
> > -	update_mask |= new_crtc_state->active_planes;
> > -
> 
> maybe this useless update_mask removal deserved a separated patch,
> but not a big deal...

It's still there, just populated differently.

> 
> >  	for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) {
> >  		if (crtc->pipe != plane->pipe ||
> >  		    !(update_mask & BIT(plane->id)))
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 852b5897e80b..33d73915b73e 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10797,8 +10797,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> >  			continue;
> >  
> >  		plane_state->linked_plane = NULL;
> > -		if (plane_state->slave && !plane_state->base.visible)
> > +		if (plane_state->slave && !plane_state->base.visible) {
> >  			crtc_state->active_planes &= ~BIT(plane->id);
> > +			crtc_state->update_planes |= BIT(plane->id);
> > +		}
> >  
> >  		plane_state->slave = false;
> >  	}
> > @@ -10839,6 +10841,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> >  		linked_state->slave = true;
> >  		linked_state->linked_plane = plane;
> >  		crtc_state->active_planes |= BIT(linked->id);
> > +		crtc_state->update_planes |= BIT(linked->id);
> >  		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 5331bbed5e8c..7a55f5921d34 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -925,6 +925,9 @@ struct intel_crtc_state {
> >  	u8 active_planes;
> >  	u8 nv12_planes;
> >  
> > +	/* bitmask of planes that will be updated during the commit */
> 
> I noticed how bad we are with documentation compared to the rest of drm
> structs :/
> 
> but I'm glad you added the explanation in the comment here.
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> > +	u8 update_planes;
> > +
> >  	/* HDMI scrambling status */
> >  	bool hdmi_scrambling;
> >  
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane()
  2018-11-07 22:08   ` Rodrigo Vivi
@ 2018-11-08 11:43     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-08 11:43 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 02:08:43PM -0800, Rodrigo Vivi wrote:
> On Thu, Nov 01, 2018 at 05:06:01PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > We're going to need access to the new crtc state in ->disable_plane()
> > for SKL+ wm/ddb programming and pre-skl pipe gamma/csc control. Pass
> > the crtc state down.
> > 
> > We'll also try to make intel_crtc_disable_planes() drtr as much as
> > it's possible. The fact that we don't have a separate crtc state
> > for the disabled state when we're going to re-enable the crtc later
> > means we might end up poking at a few extra planes in there. But
> > that's harmless. I suppose one migth argue that we wouldn't have to
> > care about proper ddb/wm/csc/gamma if the pipe is going to permanently
> > disable anyway, but the state checker probably cares so we should try
> > our best to make sure everything is programmed correctly even in that
> > case.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic_plane.c |  2 +-
> >  drivers/gpu/drm/i915/intel_display.c      | 39 ++++++++++++++---------
> >  drivers/gpu/drm/i915/intel_display.h      |  8 +++++
> >  drivers/gpu/drm/i915/intel_drv.h          |  2 +-
> >  drivers/gpu/drm/i915/intel_sprite.c       | 12 ++++---
> >  5 files changed, 42 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > index 010269a12390..69fc7010190c 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > @@ -210,7 +210,7 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
> >  		} else {
> >  			trace_intel_disable_plane(&plane->base, crtc);
> >  
> > -			plane->disable_plane(plane, crtc);
> > +			plane->disable_plane(plane, new_crtc_state);
> >  		}
> >  	}
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 33d73915b73e..6088ae554e56 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2781,7 +2781,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
> >  		intel_pre_disable_primary_noatomic(&crtc->base);
> >  
> >  	trace_intel_disable_plane(&plane->base, crtc);
> > -	plane->disable_plane(plane, crtc);
> > +	plane->disable_plane(plane, crtc_state);
> >  }
> >  
> >  static void
> > @@ -3386,7 +3386,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void i9xx_disable_plane(struct intel_plane *plane,
> > -			       struct intel_crtc *crtc)
> > +			       const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> > @@ -5421,23 +5421,32 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
> >  		intel_update_watermarks(crtc);
> >  }
> >  
> > -static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask)
> > +static void intel_crtc_disable_planes(struct intel_atomic_state *state,
> > +				      struct intel_crtc *crtc)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	const struct intel_crtc_state *new_crtc_state =
> > +		intel_atomic_get_new_crtc_state(state, crtc);
> > +	unsigned int update_mask = new_crtc_state->update_planes;
> > +	const struct intel_plane_state *old_plane_state;
> >  	struct intel_plane *plane;
> >  	unsigned fb_bits = 0;
> > +	int i;
> >  
> >  	intel_crtc_dpms_overlay_disable(crtc);
> >  
> > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > -		if (plane_mask & BIT(plane->id)) {
> > -			plane->disable_plane(plane, crtc);
> > +	for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
> 
> why getting "i" if it is unused later?

The macro requires it. I've been pondering using c99 and moving the
declaration into the for loop itself, but I'm not sure whether that's
still acceptable in the kernel. IIRC there is no other kernel code doing
that but there is some in tools/.

> 
> do you have plans to reuse this for_each_old_intel_plane_in_state somewhere else?
> Besides the "i" I'm not sure I liked it returning multiple things.

These things are used all over atomic code. There are drm_ versions that
operate on the drm_ types, and for the purposes of not cluttering our
code so much with aliasing pointers, casts and whatnot we have our intel_
variants as well.

> 
> if we are not going to use in more places I'd prefer something more verbose
> here than macromagics.
> 
> > +		if (crtc->pipe != plane->pipe ||
> > +		    !(update_mask & BIT(plane->id)))
> > +			continue;
> > +
> > +		plane->disable_plane(plane, new_crtc_state);
> >  
> > +		if (old_plane_state->base.visible)
> >  			fb_bits |= plane->frontbuffer_bit;
> > -		}
> >  	}
> >  
> > -	intel_frontbuffer_flip(to_i915(dev), fb_bits);
> > +	intel_frontbuffer_flip(dev_priv, fb_bits);
> >  }
> >  
> >  static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc,
> > @@ -9855,9 +9864,9 @@ static void i845_update_cursor(struct intel_plane *plane,
> >  }
> >  
> >  static void i845_disable_cursor(struct intel_plane *plane,
> > -				struct intel_crtc *crtc)
> > +				const struct intel_crtc_state *crtc_state)
> >  {
> > -	i845_update_cursor(plane, NULL, NULL);
> > +	i845_update_cursor(plane, crtc_state, NULL);
> >  }
> >  
> >  static bool i845_cursor_get_hw_state(struct intel_plane *plane,
> > @@ -10084,9 +10093,9 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  }
> >  
> >  static void i9xx_disable_cursor(struct intel_plane *plane,
> > -				struct intel_crtc *crtc)
> > +				const struct intel_crtc_state *crtc_state)
> >  {
> > -	i9xx_update_cursor(plane, NULL, NULL);
> > +	i9xx_update_cursor(plane, crtc_state, NULL);
> >  }
> >  
> >  static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
> > @@ -12840,7 +12849,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
> >  		intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state);
> >  
> >  		if (old_crtc_state->active) {
> > -			intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes);
> > +			intel_crtc_disable_planes(intel_state, intel_crtc);
> >  
> >  			/*
> >  			 * We need to disable pipe CRC before disabling the pipe,
> > @@ -13695,7 +13704,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
> >  					  to_intel_plane_state(plane->state));
> >  	} else {
> >  		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> > -		intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
> > +		intel_plane->disable_plane(intel_plane, crtc_state);
> >  	}
> >  
> >  	intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
> > diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
> > index 5d50decbcbb5..df9e6ebb27de 100644
> > --- a/drivers/gpu/drm/i915/intel_display.h
> > +++ b/drivers/gpu/drm/i915/intel_display.h
> > @@ -382,6 +382,14 @@ struct intel_link_m_n {
> >  	for_each_power_well_rev(__dev_priv, __power_well)		        \
> >  		for_each_if((__power_well)->desc->domains & (__domain_mask))
> >  
> > +#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
> > +	for ((__i) = 0; \
> > +	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> > +		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
> > +		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
> > +	     (__i)++) \
> > +		for_each_if(plane)
> > +
> >  #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \
> >  	for ((__i) = 0; \
> >  	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 7a55f5921d34..facd5cb0b540 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1015,7 +1015,7 @@ struct intel_plane {
> >  			     const struct intel_crtc_state *crtc_state,
> >  			     const struct intel_plane_state *plane_state);
> >  	void (*disable_plane)(struct intel_plane *plane,
> > -			      struct intel_crtc *crtc);
> > +			      const struct intel_crtc_state *crtc_state);
> >  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
> >  	int (*check_plane)(struct intel_crtc_state *crtc_state,
> >  			   struct intel_plane_state *plane_state);
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 84c5f532fba5..2f97a298c24e 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -488,7 +488,8 @@ icl_update_slave(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +skl_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum plane_id plane_id = plane->id;
> > @@ -751,7 +752,8 @@ vlv_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +vlv_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> > @@ -918,7 +920,8 @@ ivb_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +ivb_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> > @@ -1084,7 +1087,8 @@ g4x_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +g4x_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations
  2018-11-07 22:11   ` [PATCH " Rodrigo Vivi
@ 2018-11-08 11:46     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-08 11:46 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 02:11:10PM -0800, Rodrigo Vivi wrote:
> 
> On Thu, Nov 01, 2018 at 05:06:03PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > We memset(0) the entire watermark struct the start, so there's no
> > need to clear things later on.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 20 +++++---------------
> >  1 file changed, 5 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index bd5f16bc7e08..b0720994fa0a 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -4706,10 +4706,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> >  	if (latency == 0)
> >  		return level == 0 ? -EINVAL : 0;
> >  
> > -	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
> > -		result->plane_en = false;
> > +	if (!intel_wm_plane_visible(cstate, intel_pstate))
> >  		return 0;
> > -	}
> >  
> >  	/* Display WA #1141: kbl,cfl */
> >  	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
> > @@ -4806,8 +4804,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> >  	if ((level > 0 && res_lines > 31) ||
> >  	    res_blocks >= ddb_allocation ||
> >  	    min_disp_buf_needed >= ddb_allocation) {
> > -		result->plane_en = false;
> > -
> >  		/*
> >  		 * If there are no valid level 0 watermarks, then we can't
> >  		 * support this display configuration.
> > @@ -4831,10 +4827,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> >  	 */
> >  	if (wp->is_planar && level >= 1 &&
> >  	    (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) ||
> > -	     IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) {
> > -		result->plane_en = false;
> > +	     IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0)))
> 
> this reminds me that I probably forgot one patch behind somewhere...

Nah. You just reviewed the old version here :)

> 
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> 
> >  		return 0;
> > -	}
> >  
> >  	/* The number of lines are ignored for the level 0 watermark. */
> >  	result->plane_res_b = res_blocks;
> > @@ -4920,15 +4914,15 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> >  	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
> >  
> >  	if (!cstate->base.active)
> > -		goto exit;
> > +		return;
> >  
> >  	/* Transition WM are not recommended by HW team for GEN9 */
> >  	if (INTEL_GEN(dev_priv) <= 9)
> > -		goto exit;
> > +		return;
> >  
> >  	/* Transition WM don't make any sense if ipc is disabled */
> >  	if (!dev_priv->ipc_enabled)
> > -		goto exit;
> > +		return;
> >  
> >  	trans_min = 14;
> >  	if (INTEL_GEN(dev_priv) >= 11)
> > @@ -4967,11 +4961,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> >  	if (res_blocks < ddb_allocation) {
> >  		trans_wm->plane_res_b = res_blocks;
> >  		trans_wm->plane_en = true;
> > -		return;
> >  	}
> > -
> > -exit:
> > -	trans_wm->plane_en = false;
> >  }
> >  
> >  static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH v2 06/14] drm/i915: Reorganize plane register writes to make them more atomic
  2018-11-07 18:42   ` [PATCH v2 " Ville Syrjala
@ 2018-11-08 19:30     ` Matt Roper
  2018-11-08 19:48       ` Ville Syrjälä
  0 siblings, 1 reply; 57+ messages in thread
From: Matt Roper @ 2018-11-08 19:30 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 08:42:55PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Some observations about the plane registers:
> - the control register will self-arm if the plane is not already
>   enabled, thus we want to write it as close to (or ideally after)
>   the surface register
> - tileoff/linoff/offset/aux_offset are self-arming as well so we want
>   them close to the surface register as well
> - color keying registers we maybe self arming before SKL. Not 100%
>   sure but we can try to keep them near to the surface register
>   as well
> - chv pipe b csc register are double buffered but self arming so
>   moving them down a bit
> - the rest should be mostly armed by the surface register so we can
>   safely write them first, and to just for some consistency let's try
>   to follow keep them in order based on the register offset

In general these functions all run under vblank evasion currently, so
this won't have a visible effect on atomicity unless we fail the
evasion, right?  Is the longer-term goal here to eventually pull a bunch
of the register writing out and only evade around the actual arming
registers?

> 
> v2: Rebase due to input CSC
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c |  40 +++++----
>  drivers/gpu/drm/i915/intel_sprite.c  | 120 +++++++++++++++------------
>  2 files changed, 89 insertions(+), 71 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ae6d58dbf1ed..ac46497cfc52 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3313,7 +3313,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
>  	u32 linear_offset;
>  	u32 dspcntr = plane_state->ctl;
> -	i915_reg_t reg = DSPCNTR(i9xx_plane);
>  	int x = plane_state->color_plane[0].x;
>  	int y = plane_state->color_plane[0].y;
>  	unsigned long irqflags;
> @@ -3328,41 +3327,45 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
> +
>  	if (INTEL_GEN(dev_priv) < 4) {
>  		/* pipesrc and dspsize control the size that is scaled from,
>  		 * which should always be the user's requested size.
>  		 */
> +		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
>  		I915_WRITE_FW(DSPSIZE(i9xx_plane),
>  			      ((crtc_state->pipe_src_h - 1) << 16) |
>  			      (crtc_state->pipe_src_w - 1));
> -		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
>  	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
> +		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
>  		I915_WRITE_FW(PRIMSIZE(i9xx_plane),
>  			      ((crtc_state->pipe_src_h - 1) << 16) |
>  			      (crtc_state->pipe_src_w - 1));
> -		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
>  		I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
>  	}
>  
> -	I915_WRITE_FW(reg, dspcntr);
> -
> -	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> -		I915_WRITE_FW(DSPSURF(i9xx_plane),
> -			      intel_plane_ggtt_offset(plane_state) +
> -			      dspaddr_offset);
>  		I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
>  	} else if (INTEL_GEN(dev_priv) >= 4) {
> +		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> +		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> +	}
> +
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
> +	I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
> +	if (INTEL_GEN(dev_priv) >= 4)
>  		I915_WRITE_FW(DSPSURF(i9xx_plane),
>  			      intel_plane_ggtt_offset(plane_state) +
>  			      dspaddr_offset);
> -		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> -		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> -	} else {
> +	else
>  		I915_WRITE_FW(DSPADDR(i9xx_plane),
>  			      intel_plane_ggtt_offset(plane_state) +
>  			      dspaddr_offset);
> -	}
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -10013,8 +10016,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  	 * On some platforms writing CURCNTR first will also
>  	 * cause CURPOS to be armed by the CURBASE write.
>  	 * Without the CURCNTR write the CURPOS write would
> -	 * arm itself. Thus we always start the full update
> -	 * with a CURCNTR write.
> +	 * arm itself. Thus we always update CURCNTR before
> +	 * CURPOS.
>  	 *
>  	 * On other platforms CURPOS always requires the
>  	 * CURBASE write to arm the update. Additonally
> @@ -10024,15 +10027,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  	 * cursor that doesn't appear to move, or even change
>  	 * shape. Thus we always write CURBASE.
>  	 *
> -	 * CURCNTR and CUR_FBC_CTL are always
> -	 * armed by the CURBASE write only.
> +	 * The other registers are armed by by the CURBASE write
> +	 * except when the plane is getting enabled at which time
> +	 * the CURCNTR write arms the update.
>  	 */
>  	if (plane->cursor.base != base ||
>  	    plane->cursor.size != fbc_ctl ||
>  	    plane->cursor.cntl != cntl) {
> -		I915_WRITE_FW(CURCNTR(pipe), cntl);
>  		if (HAS_CUR_FBC(dev_priv))
>  			I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
> +		I915_WRITE_FW(CURCNTR(pipe), cntl);
>  		I915_WRITE_FW(CURPOS(pipe), pos);
>  		I915_WRITE_FW(CURBASE(pipe), base);
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index facf7ca8f14f..be6e3c3de1ff 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -500,27 +500,12 @@ skl_program_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> -			      plane_state->color_ctl);
> -
> -	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
> -		icl_program_input_csc_coeff(crtc_state, plane_state);
> -
> -	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> -	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> -	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> -
> -	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
>  	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
> +	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
>  	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
>  	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
> -		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
> -
> -	if (INTEL_GEN(dev_priv) < 11)
> -		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> -			      (plane_state->color_plane[1].y << 16) |
> -			       plane_state->color_plane[1].x);
> +		      (plane_state->color_plane[1].offset - surf_addr) |
> +		      aux_stride);
>  
>  	if (icl_is_hdr_plane(plane)) {
>  		u32 cus_ctl = 0;
> @@ -543,15 +528,36 @@ skl_program_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
>  	}
>  
> -	if (!slave && plane_state->scaler_id >= 0)
> -		skl_program_scaler(plane, crtc_state, plane_state);
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> +			      plane_state->color_ctl);
>  
> -	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> +	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
> +		icl_program_input_csc_coeff(crtc_state, plane_state);
> +
> +	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> +	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> +	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);

You mentioned above that you wanted to follow register offset ordering
where possible, so I believe MSK should come before MAX here.  Same
comment for the vlv and g4x functions farther down.

> +
> +	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
> +
> +	if (INTEL_GEN(dev_priv) < 11)
> +		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> +			      (plane_state->color_plane[1].y << 16) |
> +			      plane_state->color_plane[1].x);
>  
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + surf_addr);
>  
> +	if (!slave && plane_state->scaler_id >= 0)
> +		skl_program_scaler(plane, crtc_state, plane_state);
> +
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> @@ -789,7 +795,6 @@ vlv_update_plane(struct intel_plane *plane,
>  		 const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	enum plane_id plane_id = plane->id;
>  	u32 sprctl = plane_state->ctl;
> @@ -814,6 +819,12 @@ vlv_update_plane(struct intel_plane *plane,
>  
>  	vlv_update_clrc(plane_state);
>  
> +	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> +		      plane_state->color_plane[0].stride);
> +	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> +	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> +
>  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
>  		chv_update_csc(plane_state);
>  
> @@ -822,18 +833,15 @@ vlv_update_plane(struct intel_plane *plane,
>  		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
>  		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
>  	}
> -	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> -		      plane_state->color_plane[0].stride);
> -	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> -
> -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> -		I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> -	else
> -		I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
>  
> -	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> +	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> +	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);

I think you already indicated you were going to pull the "ignore tiling
and just write both offset registers" out into a separate patch, but
these are another case where you might want to flip the order to match
register offset (linear < tiled).


Matt

>  
> -	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
>  	I915_WRITE_FW(SPSURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> @@ -947,7 +955,6 @@ ivb_update_plane(struct intel_plane *plane,
>  		 const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	u32 sprctl = plane_state->ctl, sprscale = 0;
>  	u32 sprsurf_offset = plane_state->color_plane[0].offset;
> @@ -976,27 +983,32 @@ ivb_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> +	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> +	if (IS_IVYBRIDGE(dev_priv))
> +		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> +
>  	if (key->flags) {
>  		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
>  		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
>  		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
>  	}
>  
> -	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> -	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> -
>  	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
>  	 * register */
> -	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> +	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
>  		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
> -	else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> +	} else {
>  		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
> -	else
>  		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
> +	}
>  
> -	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> -	if (IS_IVYBRIDGE(dev_priv))
> -		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(SPRCTL(pipe), sprctl);
>  	I915_WRITE_FW(SPRSURF(pipe),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> @@ -1014,7 +1026,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	I915_WRITE_FW(SPRCTL(pipe), 0);
> -	/* Can't leave the scaler enabled... */
> +	/* Disable the scaler */
>  	if (IS_IVYBRIDGE(dev_priv))
>  		I915_WRITE_FW(SPRSCALE(pipe), 0);
>  	I915_WRITE_FW(SPRSURF(pipe), 0);
> @@ -1116,7 +1128,6 @@ g4x_update_plane(struct intel_plane *plane,
>  		 const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	u32 dvscntr = plane_state->ctl, dvsscale = 0;
>  	u32 dvssurf_offset = plane_state->color_plane[0].offset;
> @@ -1145,22 +1156,25 @@ g4x_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> +	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> +	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> +
>  	if (key->flags) {
>  		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
>  		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
>  		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
>  	}
>  
> -	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> -	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> +	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> +	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
>  
> -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> -		I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> -	else
> -		I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
> -
> -	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> -	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
>  	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
>  	I915_WRITE_FW(DVSSURF(pipe),
>  		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://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
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 06/14] drm/i915: Reorganize plane register writes to make them more atomic
  2018-11-08 19:30     ` Matt Roper
@ 2018-11-08 19:48       ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-08 19:48 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Thu, Nov 08, 2018 at 11:30:07AM -0800, Matt Roper wrote:
> On Wed, Nov 07, 2018 at 08:42:55PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Some observations about the plane registers:
> > - the control register will self-arm if the plane is not already
> >   enabled, thus we want to write it as close to (or ideally after)
> >   the surface register
> > - tileoff/linoff/offset/aux_offset are self-arming as well so we want
> >   them close to the surface register as well
> > - color keying registers we maybe self arming before SKL. Not 100%
> >   sure but we can try to keep them near to the surface register
> >   as well
> > - chv pipe b csc register are double buffered but self arming so
> >   moving them down a bit
> > - the rest should be mostly armed by the surface register so we can
> >   safely write them first, and to just for some consistency let's try
> >   to follow keep them in order based on the register offset
> 
> In general these functions all run under vblank evasion currently, so
> this won't have a visible effect on atomicity unless we fail the
> evasion, right?

Yes.

> Is the longer-term goal here to eventually pull a bunch
> of the register writing out and only evade around the actual arming
> registers?

That has been on my mind off and on. But I haven't actually
measured how much we'd gain. So not sure if it's worth the hassle
currently. We may need to think much harder on this when our mmio
becomes more expensive...

> 
> > 
> > v2: Rebase due to input CSC
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c |  40 +++++----
> >  drivers/gpu/drm/i915/intel_sprite.c  | 120 +++++++++++++++------------
> >  2 files changed, 89 insertions(+), 71 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index ae6d58dbf1ed..ac46497cfc52 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3313,7 +3313,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
> >  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> >  	u32 linear_offset;
> >  	u32 dspcntr = plane_state->ctl;
> > -	i915_reg_t reg = DSPCNTR(i9xx_plane);
> >  	int x = plane_state->color_plane[0].x;
> >  	int y = plane_state->color_plane[0].y;
> >  	unsigned long irqflags;
> > @@ -3328,41 +3327,45 @@ static void i9xx_update_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
> > +
> >  	if (INTEL_GEN(dev_priv) < 4) {
> >  		/* pipesrc and dspsize control the size that is scaled from,
> >  		 * which should always be the user's requested size.
> >  		 */
> > +		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
> >  		I915_WRITE_FW(DSPSIZE(i9xx_plane),
> >  			      ((crtc_state->pipe_src_h - 1) << 16) |
> >  			      (crtc_state->pipe_src_w - 1));
> > -		I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
> >  	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
> > +		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
> >  		I915_WRITE_FW(PRIMSIZE(i9xx_plane),
> >  			      ((crtc_state->pipe_src_h - 1) << 16) |
> >  			      (crtc_state->pipe_src_w - 1));
> > -		I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
> >  		I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
> >  	}
> >  
> > -	I915_WRITE_FW(reg, dspcntr);
> > -
> > -	I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
> >  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> > -		I915_WRITE_FW(DSPSURF(i9xx_plane),
> > -			      intel_plane_ggtt_offset(plane_state) +
> > -			      dspaddr_offset);
> >  		I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
> >  	} else if (INTEL_GEN(dev_priv) >= 4) {
> > +		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> > +		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> > +	}
> > +
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> > +	I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
> > +	if (INTEL_GEN(dev_priv) >= 4)
> >  		I915_WRITE_FW(DSPSURF(i9xx_plane),
> >  			      intel_plane_ggtt_offset(plane_state) +
> >  			      dspaddr_offset);
> > -		I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
> > -		I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
> > -	} else {
> > +	else
> >  		I915_WRITE_FW(DSPADDR(i9xx_plane),
> >  			      intel_plane_ggtt_offset(plane_state) +
> >  			      dspaddr_offset);
> > -	}
> >  
> >  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> >  }
> > @@ -10013,8 +10016,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  	 * On some platforms writing CURCNTR first will also
> >  	 * cause CURPOS to be armed by the CURBASE write.
> >  	 * Without the CURCNTR write the CURPOS write would
> > -	 * arm itself. Thus we always start the full update
> > -	 * with a CURCNTR write.
> > +	 * arm itself. Thus we always update CURCNTR before
> > +	 * CURPOS.
> >  	 *
> >  	 * On other platforms CURPOS always requires the
> >  	 * CURBASE write to arm the update. Additonally
> > @@ -10024,15 +10027,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  	 * cursor that doesn't appear to move, or even change
> >  	 * shape. Thus we always write CURBASE.
> >  	 *
> > -	 * CURCNTR and CUR_FBC_CTL are always
> > -	 * armed by the CURBASE write only.
> > +	 * The other registers are armed by by the CURBASE write
> > +	 * except when the plane is getting enabled at which time
> > +	 * the CURCNTR write arms the update.
> >  	 */
> >  	if (plane->cursor.base != base ||
> >  	    plane->cursor.size != fbc_ctl ||
> >  	    plane->cursor.cntl != cntl) {
> > -		I915_WRITE_FW(CURCNTR(pipe), cntl);
> >  		if (HAS_CUR_FBC(dev_priv))
> >  			I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
> > +		I915_WRITE_FW(CURCNTR(pipe), cntl);
> >  		I915_WRITE_FW(CURPOS(pipe), pos);
> >  		I915_WRITE_FW(CURBASE(pipe), base);
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index facf7ca8f14f..be6e3c3de1ff 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -500,27 +500,12 @@ skl_program_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> > -		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> > -			      plane_state->color_ctl);
> > -
> > -	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
> > -		icl_program_input_csc_coeff(crtc_state, plane_state);
> > -
> > -	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> > -	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> > -	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> > -
> > -	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
> >  	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
> > +	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> >  	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
> >  	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
> > -		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
> > -
> > -	if (INTEL_GEN(dev_priv) < 11)
> > -		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> > -			      (plane_state->color_plane[1].y << 16) |
> > -			       plane_state->color_plane[1].x);
> > +		      (plane_state->color_plane[1].offset - surf_addr) |
> > +		      aux_stride);
> >  
> >  	if (icl_is_hdr_plane(plane)) {
> >  		u32 cus_ctl = 0;
> > @@ -543,15 +528,36 @@ skl_program_plane(struct intel_plane *plane,
> >  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
> >  	}
> >  
> > -	if (!slave && plane_state->scaler_id >= 0)
> > -		skl_program_scaler(plane, crtc_state, plane_state);
> > +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> > +		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> > +			      plane_state->color_ctl);
> >  
> > -	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> > +	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
> > +		icl_program_input_csc_coeff(crtc_state, plane_state);
> > +
> > +	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> > +	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> > +	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> 
> You mentioned above that you wanted to follow register offset ordering
> where possible, so I believe MSK should come before MAX here.  Same
> comment for the vlv and g4x functions farther down.
> 
> > +
> > +	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
> > +
> > +	if (INTEL_GEN(dev_priv) < 11)
> > +		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
> > +			      (plane_state->color_plane[1].y << 16) |
> > +			      plane_state->color_plane[1].x);
> >  
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
> >  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
> >  		      intel_plane_ggtt_offset(plane_state) + surf_addr);
> >  
> > +	if (!slave && plane_state->scaler_id >= 0)
> > +		skl_program_scaler(plane, crtc_state, plane_state);
> > +
> >  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> >  }
> >  
> > @@ -789,7 +795,6 @@ vlv_update_plane(struct intel_plane *plane,
> >  		 const struct intel_plane_state *plane_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > -	const struct drm_framebuffer *fb = plane_state->base.fb;
> >  	enum pipe pipe = plane->pipe;
> >  	enum plane_id plane_id = plane->id;
> >  	u32 sprctl = plane_state->ctl;
> > @@ -814,6 +819,12 @@ vlv_update_plane(struct intel_plane *plane,
> >  
> >  	vlv_update_clrc(plane_state);
> >  
> > +	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> > +		      plane_state->color_plane[0].stride);
> > +	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> > +	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> > +
> >  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
> >  		chv_update_csc(plane_state);
> >  
> > @@ -822,18 +833,15 @@ vlv_update_plane(struct intel_plane *plane,
> >  		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
> >  		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
> >  	}
> > -	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
> > -		      plane_state->color_plane[0].stride);
> > -	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> > -
> > -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> > -		I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> > -	else
> > -		I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
> >  
> > -	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
> > +	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
> > +	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
> 
> I think you already indicated you were going to pull the "ignore tiling
> and just write both offset registers" out into a separate patch, but
> these are another case where you might want to flip the order to match
> register offset (linear < tiled).

Sure. It looks like my ocd wasn't quite strong enough to follow
my own rule 100% :)

> 
> 
> Matt
> 
> >  
> > -	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
> >  	I915_WRITE_FW(SPSURF(pipe, plane_id),
> >  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> > @@ -947,7 +955,6 @@ ivb_update_plane(struct intel_plane *plane,
> >  		 const struct intel_plane_state *plane_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > -	const struct drm_framebuffer *fb = plane_state->base.fb;
> >  	enum pipe pipe = plane->pipe;
> >  	u32 sprctl = plane_state->ctl, sprscale = 0;
> >  	u32 sprsurf_offset = plane_state->color_plane[0].offset;
> > @@ -976,27 +983,32 @@ ivb_update_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> > +	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> > +	if (IS_IVYBRIDGE(dev_priv))
> > +		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> > +
> >  	if (key->flags) {
> >  		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
> >  		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
> >  		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
> >  	}
> >  
> > -	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
> > -	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
> > -
> >  	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
> >  	 * register */
> > -	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> > +	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> >  		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
> > -	else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> > +	} else {
> >  		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
> > -	else
> >  		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
> > +	}
> >  
> > -	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
> > -	if (IS_IVYBRIDGE(dev_priv))
> > -		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(SPRCTL(pipe), sprctl);
> >  	I915_WRITE_FW(SPRSURF(pipe),
> >  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
> > @@ -1014,7 +1026,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> >  	I915_WRITE_FW(SPRCTL(pipe), 0);
> > -	/* Can't leave the scaler enabled... */
> > +	/* Disable the scaler */
> >  	if (IS_IVYBRIDGE(dev_priv))
> >  		I915_WRITE_FW(SPRSCALE(pipe), 0);
> >  	I915_WRITE_FW(SPRSURF(pipe), 0);
> > @@ -1116,7 +1128,6 @@ g4x_update_plane(struct intel_plane *plane,
> >  		 const struct intel_plane_state *plane_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > -	const struct drm_framebuffer *fb = plane_state->base.fb;
> >  	enum pipe pipe = plane->pipe;
> >  	u32 dvscntr = plane_state->ctl, dvsscale = 0;
> >  	u32 dvssurf_offset = plane_state->color_plane[0].offset;
> > @@ -1145,22 +1156,25 @@ g4x_update_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> > +	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> > +	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> > +
> >  	if (key->flags) {
> >  		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
> >  		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
> >  		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
> >  	}
> >  
> > -	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
> > -	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
> > +	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> > +	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
> >  
> > -	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
> > -		I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
> > -	else
> > -		I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
> > -
> > -	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
> > -	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
> > +	/*
> > +	 * The control register self-arms if the plane was previously
> > +	 * disabled. Try to make the plane enable atomic by writing
> > +	 * the control register just before the surface register.
> > +	 */
> >  	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
> >  	I915_WRITE_FW(DVSSURF(pipe),
> >  		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

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

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

* Re: [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end
  2018-11-01 15:05 ` [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end Ville Syrjala
  2018-11-07 21:26   ` Rodrigo Vivi
@ 2018-11-08 22:06   ` Matt Roper
  2018-11-09 13:55     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Matt Roper @ 2018-11-08 22:06 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:05:58PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> The plane color correction registers are single buffered. So
> ideally we would write them at the start of vblank just after the
> double buffered plane registers have been latched. Since we have
> no convenient way to do that for now let's at least move the
> single buffered register writes to happen after the double
> buffered registers have been written.

Should we move this all the way out of the vblank evasion?  I realize
that vlv is only two registers total so it's not a big deal, but I know
Uma is working on the plane color management stuff for later platforms
where we have a bunch of registers to write, so maybe we should setup
the callsite now?

On a similar note, I notice our single-buffered pipe-level color
management registers are written before evasion right now...should we
move that to after the evasion as well?


Matt

> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 455b2d0cbaa6..84c5f532fba5 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -718,8 +718,6 @@ vlv_update_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> -	vlv_update_clrc(plane_state);
> -
>  	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
>  		      plane_state->color_plane[0].stride);
>  	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
> @@ -747,6 +745,8 @@ vlv_update_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(SPSURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
>  
> +	vlv_update_clrc(plane_state);
> +
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://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
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask
  2018-11-01 15:06 ` [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask Ville Syrjala
  2018-11-07 21:49   ` Rodrigo Vivi
@ 2018-11-08 23:22   ` Matt Roper
  2018-11-09 13:57     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Matt Roper @ 2018-11-08 23:22 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:06:00PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Keep track which planes need updating during the commit. For now this
> is just (was_visible || is_visible) but I'll have need to update

When gen11 nv12 is in use, it also contains was_slave || is_slave as
well, right?

> invisible planes later on for skl plane ddbs and for pre-skl pipe
> gamma/csc control (which lives in the primary plane control register).
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c       | 1 +
>  drivers/gpu/drm/i915/intel_atomic_plane.c | 8 ++++----
>  drivers/gpu/drm/i915/intel_display.c      | 5 ++++-
>  drivers/gpu/drm/i915/intel_drv.h          | 3 +++
>  4 files changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index a5a2c8fe58a7..8cb02f28d30c 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -184,6 +184,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	crtc_state->fifo_changed = false;
>  	crtc_state->wm.need_postvbl_update = false;
>  	crtc_state->fb_bits = 0;
> +	crtc_state->update_planes = 0;
>  
>  	return &crtc_state->base;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index 7d3685075201..010269a12390 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -137,6 +137,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  	if (state->visible && state->fb->format->format == DRM_FORMAT_NV12)
>  		crtc_state->nv12_planes |= BIT(intel_plane->id);
>  
> +	if (state->visible || old_plane_state->base.visible)
> +		crtc_state->update_planes |= BIT(intel_plane->id);
> +
>  	return intel_plane_atomic_calc_changes(old_crtc_state,
>  					       &crtc_state->base,
>  					       old_plane_state,
> @@ -171,14 +174,11 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>  				 struct intel_crtc_state *old_crtc_state,
>  				 struct intel_crtc_state *new_crtc_state)
>  {
> +	u32 update_mask = new_crtc_state->update_planes;
>  	struct intel_plane_state *new_plane_state;
>  	struct intel_plane *plane;
> -	u32 update_mask;
>  	int i;
>  
> -	update_mask = old_crtc_state->active_planes;
> -	update_mask |= new_crtc_state->active_planes;
> -
>  	for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) {
>  		if (crtc->pipe != plane->pipe ||
>  		    !(update_mask & BIT(plane->id)))
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 852b5897e80b..33d73915b73e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10797,8 +10797,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  			continue;
>  
>  		plane_state->linked_plane = NULL;
> -		if (plane_state->slave && !plane_state->base.visible)
> +		if (plane_state->slave && !plane_state->base.visible) {
>  			crtc_state->active_planes &= ~BIT(plane->id);
> +			crtc_state->update_planes |= BIT(plane->id);

Just to clarify, this is to ensure that we clear out the register
programming of a plane that was an nv12 slave on the previous frame, but
isn't any longer on the current frame, and ...


> +		}
>  
>  		plane_state->slave = false;
>  	}
> @@ -10839,6 +10841,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  		linked_state->slave = true;
>  		linked_state->linked_plane = plane;
>  		crtc_state->active_planes |= BIT(linked->id);
> +		crtc_state->update_planes |= BIT(linked->id);

... this is to ensure we setup the programming for any new slave planes?


Matt

>  		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 5331bbed5e8c..7a55f5921d34 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -925,6 +925,9 @@ struct intel_crtc_state {
>  	u8 active_planes;
>  	u8 nv12_planes;
>  
> +	/* bitmask of planes that will be updated during the commit */
> +	u8 update_planes;
> +
>  	/* HDMI scrambling status */
>  	bool hdmi_scrambling;
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://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
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane()
  2018-11-01 15:06 ` [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane() Ville Syrjala
  2018-11-07 22:08   ` Rodrigo Vivi
@ 2018-11-08 23:52   ` Matt Roper
  2018-11-09 14:32     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Matt Roper @ 2018-11-08 23:52 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:06:01PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We're going to need access to the new crtc state in ->disable_plane()
> for SKL+ wm/ddb programming and pre-skl pipe gamma/csc control. Pass
> the crtc state down.
> 
> We'll also try to make intel_crtc_disable_planes() drtr as much as

What does "drtr" stand for?

The main behavioral change I see in that function is that we don't do
frontbuffer tracking for nv12 slave planes anymore (and in the future
won't do it for other planes that weren't visible, but you still want to
reprogram them in some way).


Matt

> it's possible. The fact that we don't have a separate crtc state
> for the disabled state when we're going to re-enable the crtc later
> means we might end up poking at a few extra planes in there. But
> that's harmless. I suppose one migth argue that we wouldn't have to
> care about proper ddb/wm/csc/gamma if the pipe is going to permanently
> disable anyway, but the state checker probably cares so we should try
> our best to make sure everything is programmed correctly even in that
> case.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  2 +-
>  drivers/gpu/drm/i915/intel_display.c      | 39 ++++++++++++++---------
>  drivers/gpu/drm/i915/intel_display.h      |  8 +++++
>  drivers/gpu/drm/i915/intel_drv.h          |  2 +-
>  drivers/gpu/drm/i915/intel_sprite.c       | 12 ++++---
>  5 files changed, 42 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index 010269a12390..69fc7010190c 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -210,7 +210,7 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>  		} else {
>  			trace_intel_disable_plane(&plane->base, crtc);
>  
> -			plane->disable_plane(plane, crtc);
> +			plane->disable_plane(plane, new_crtc_state);
>  		}
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 33d73915b73e..6088ae554e56 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2781,7 +2781,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
>  		intel_pre_disable_primary_noatomic(&crtc->base);
>  
>  	trace_intel_disable_plane(&plane->base, crtc);
> -	plane->disable_plane(plane, crtc);
> +	plane->disable_plane(plane, crtc_state);
>  }
>  
>  static void
> @@ -3386,7 +3386,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  }
>  
>  static void i9xx_disable_plane(struct intel_plane *plane,
> -			       struct intel_crtc *crtc)
> +			       const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> @@ -5421,23 +5421,32 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>  		intel_update_watermarks(crtc);
>  }
>  
> -static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask)
> +static void intel_crtc_disable_planes(struct intel_atomic_state *state,
> +				      struct intel_crtc *crtc)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	const struct intel_crtc_state *new_crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	unsigned int update_mask = new_crtc_state->update_planes;
> +	const struct intel_plane_state *old_plane_state;
>  	struct intel_plane *plane;
>  	unsigned fb_bits = 0;
> +	int i;
>  
>  	intel_crtc_dpms_overlay_disable(crtc);
>  
> -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> -		if (plane_mask & BIT(plane->id)) {
> -			plane->disable_plane(plane, crtc);
> +	for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
> +		if (crtc->pipe != plane->pipe ||
> +		    !(update_mask & BIT(plane->id)))
> +			continue;
> +
> +		plane->disable_plane(plane, new_crtc_state);
>  
> +		if (old_plane_state->base.visible)
>  			fb_bits |= plane->frontbuffer_bit;
> -		}
>  	}
>  
> -	intel_frontbuffer_flip(to_i915(dev), fb_bits);
> +	intel_frontbuffer_flip(dev_priv, fb_bits);
>  }
>  
>  static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc,
> @@ -9855,9 +9864,9 @@ static void i845_update_cursor(struct intel_plane *plane,
>  }
>  
>  static void i845_disable_cursor(struct intel_plane *plane,
> -				struct intel_crtc *crtc)
> +				const struct intel_crtc_state *crtc_state)
>  {
> -	i845_update_cursor(plane, NULL, NULL);
> +	i845_update_cursor(plane, crtc_state, NULL);
>  }
>  
>  static bool i845_cursor_get_hw_state(struct intel_plane *plane,
> @@ -10084,9 +10093,9 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  }
>  
>  static void i9xx_disable_cursor(struct intel_plane *plane,
> -				struct intel_crtc *crtc)
> +				const struct intel_crtc_state *crtc_state)
>  {
> -	i9xx_update_cursor(plane, NULL, NULL);
> +	i9xx_update_cursor(plane, crtc_state, NULL);
>  }
>  
>  static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
> @@ -12840,7 +12849,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
>  		intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state);
>  
>  		if (old_crtc_state->active) {
> -			intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes);
> +			intel_crtc_disable_planes(intel_state, intel_crtc);
>  
>  			/*
>  			 * We need to disable pipe CRC before disabling the pipe,
> @@ -13695,7 +13704,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
>  					  to_intel_plane_state(plane->state));
>  	} else {
>  		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> -		intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
> +		intel_plane->disable_plane(intel_plane, crtc_state);
>  	}
>  
>  	intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
> diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
> index 5d50decbcbb5..df9e6ebb27de 100644
> --- a/drivers/gpu/drm/i915/intel_display.h
> +++ b/drivers/gpu/drm/i915/intel_display.h
> @@ -382,6 +382,14 @@ struct intel_link_m_n {
>  	for_each_power_well_rev(__dev_priv, __power_well)		        \
>  		for_each_if((__power_well)->desc->domains & (__domain_mask))
>  
> +#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> +		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
> +		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
> +	     (__i)++) \
> +		for_each_if(plane)
> +
>  #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \
>  	for ((__i) = 0; \
>  	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7a55f5921d34..facd5cb0b540 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1015,7 +1015,7 @@ struct intel_plane {
>  			     const struct intel_crtc_state *crtc_state,
>  			     const struct intel_plane_state *plane_state);
>  	void (*disable_plane)(struct intel_plane *plane,
> -			      struct intel_crtc *crtc);
> +			      const struct intel_crtc_state *crtc_state);
>  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
>  	int (*check_plane)(struct intel_crtc_state *crtc_state,
>  			   struct intel_plane_state *plane_state);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 84c5f532fba5..2f97a298c24e 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -488,7 +488,8 @@ icl_update_slave(struct intel_plane *plane,
>  }
>  
>  static void
> -skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +skl_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum plane_id plane_id = plane->id;
> @@ -751,7 +752,8 @@ vlv_update_plane(struct intel_plane *plane,
>  }
>  
>  static void
> -vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +vlv_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
> @@ -918,7 +920,8 @@ ivb_update_plane(struct intel_plane *plane,
>  }
>  
>  static void
> -ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +ivb_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
> @@ -1084,7 +1087,8 @@ g4x_update_plane(struct intel_plane *plane,
>  }
>  
>  static void
> -g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> +g4x_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum pipe pipe = plane->pipe;
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://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
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+
  2018-11-01 15:06 ` [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+ Ville Syrjala
  2018-11-07 22:09   ` Rodrigo Vivi
@ 2018-11-09  0:01   ` Matt Roper
  2018-11-09 14:34     ` Ville Syrjälä
  1 sibling, 1 reply; 57+ messages in thread
From: Matt Roper @ 2018-11-09  0:01 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Nov 01, 2018 at 05:06:02PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> If the level 0 latency is 0 we can't do anything. Return an error
> rather than success.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Is it possible to get 0 latency here?  I thought we increased the
latency to 2us if punit told us that level0=0 (WaWmMemoryReadLatency)?


Matt

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 6fa1634e2db5..bd5f16bc7e08 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4703,8 +4703,10 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
>  	uint32_t min_disp_buf_needed;
>  
> -	if (latency == 0 ||
> -	    !intel_wm_plane_visible(cstate, intel_pstate)) {
> +	if (latency == 0)
> +		return level == 0 ? -EINVAL : 0;
> +
> +	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
>  		result->plane_en = false;
>  		return 0;
>  	}
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://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
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
  2018-11-07 18:44   ` [PATCH v2 " Ville Syrjala
@ 2018-11-09  1:38     ` Matt Roper
  2018-11-09 14:53       ` Ville Syrjälä
  0 siblings, 1 reply; 57+ messages in thread
From: Matt Roper @ 2018-11-09  1:38 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 08:44:30PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> On SKL+ the plane WM/BUF_CFG registers are a proper part of each
> plane's register set. That means accessing them will cancel any
> pending plane update, and we would need a PLANE_SURF register write
> to arm the wm/ddb change as well.
> 
> To avoid all the problems with that let's just move the wm/ddb
> programming into the plane update/disable hooks. Now all plane
> registers get written in one (hopefully atomic) operation.
> 
> To make that feasible we'll move the plane ddb tracking into
> the crtc state. Watermarks were already tracked there.
> 
> v2: Rebase due to input CSC
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c  |  21 +-
>  drivers/gpu/drm/i915/i915_drv.h      |   3 -
>  drivers/gpu/drm/i915/intel_display.c |  16 +-
>  drivers/gpu/drm/i915/intel_display.h |  11 +-
>  drivers/gpu/drm/i915/intel_drv.h     |   9 +
>  drivers/gpu/drm/i915/intel_pm.c      | 450 ++++++++++++---------------
>  drivers/gpu/drm/i915/intel_sprite.c  |   4 +
>  7 files changed, 250 insertions(+), 264 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index f60485906f7e..3e80a04d2790 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -3437,31 +3437,32 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
>  {
>  	struct drm_i915_private *dev_priv = node_to_i915(m->private);
>  	struct drm_device *dev = &dev_priv->drm;
> -	struct skl_ddb_allocation *ddb;
>  	struct skl_ddb_entry *entry;
> -	enum pipe pipe;
> -	int plane;
> +	struct intel_crtc *crtc;
>  
>  	if (INTEL_GEN(dev_priv) < 9)
>  		return -ENODEV;
>  
>  	drm_modeset_lock_all(dev);
>  
> -	ddb = &dev_priv->wm.skl_hw.ddb;
> -
>  	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
>  
> -	for_each_pipe(dev_priv, pipe) {
> +	for_each_intel_crtc(&dev_priv->drm, crtc) {
> +		struct intel_crtc_state *crtc_state =
> +			to_intel_crtc_state(crtc->base.state);
> +		enum pipe pipe = crtc->pipe;
> +		enum plane_id plane_id;
> +
>  		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
>  
> -		for_each_universal_plane(dev_priv, pipe, plane) {
> -			entry = &ddb->plane[pipe][plane];
> -			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
> +		for_each_plane_id_on_crtc(crtc, plane_id) {
> +			entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
> +			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
>  				   entry->start, entry->end,
>  				   skl_ddb_entry_size(entry));
>  		}
>  
> -		entry = &ddb->plane[pipe][PLANE_CURSOR];
> +		entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
>  		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 2a88a7eb871b..17023a869091 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1236,9 +1236,6 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
>  }
>  
>  struct skl_ddb_allocation {
> -	/* packed/y */
> -	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> -	struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
>  	u8 enabled_slices; /* GEN11 has configurable 2 slices */
>  };

Now that we're down to a single field here, there isn't really a need to
wrap it in a struct.  Can we just eliminate the structure?

>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ac3687a0245d..f497bb521baf 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10040,6 +10040,10 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  	 * except when the plane is getting enabled at which time
>  	 * the CURCNTR write arms the update.
>  	 */
> +
> +	if (INTEL_GEN(dev_priv) >= 9)
> +		skl_write_cursor_wm(plane, crtc_state);
> +
>  	if (plane->cursor.base != base ||
>  	    plane->cursor.size != fbc_ctl ||
>  	    plane->cursor.cntl != cntl) {
> @@ -11829,6 +11833,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
>  	struct skl_pipe_wm hw_wm, *sw_wm;
>  	struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
>  	struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
> +	struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES];
> +	struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES];
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	const enum pipe pipe = intel_crtc->pipe;
>  	int plane, level, max_level = ilk_wm_max_level(dev_priv);
> @@ -11839,6 +11845,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
>  	skl_pipe_wm_get_hw_state(crtc, &hw_wm);
>  	sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal;
>  
> +	skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv);
> +

I notice we've never been verifying the UV ddb entries; should we be
(maybe in a separate patch)?


>  	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
>  	sw_ddb = &dev_priv->wm.skl_hw.ddb;
>  
> @@ -11881,8 +11889,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
>  		}
>  
>  		/* DDB */
> -		hw_ddb_entry = &hw_ddb.plane[pipe][plane];
> -		sw_ddb_entry = &sw_ddb->plane[pipe][plane];
> +		hw_ddb_entry = &hw_ddb_y[plane];
> +		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane];
>  
>  		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
>  			DRM_ERROR("mismatch in DDB state pipe %c plane %d (expected (%u,%u), found (%u,%u))\n",
> @@ -11931,8 +11939,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
>  		}
>  
>  		/* DDB */
> -		hw_ddb_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
> -		sw_ddb_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
> +		hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR];
> +		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR];
>  
>  		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
>  			DRM_ERROR("mismatch in DDB state pipe %c cursor (expected (%u,%u), found (%u,%u))\n",
> diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
> index df9e6ebb27de..078406dc65e5 100644
> --- a/drivers/gpu/drm/i915/intel_display.h
> +++ b/drivers/gpu/drm/i915/intel_display.h
> @@ -319,7 +319,7 @@ struct intel_link_m_n {
>  			    &(dev)->mode_config.plane_list,		\
>  			    base.head)					\
>  		for_each_if((plane_mask) &				\
> -			    drm_plane_mask(&intel_plane->base)))
> +			    drm_plane_mask(&intel_plane->base))
>  

Looks like this is an independent fix for 40560e26dc45e ("drm/i915: Use
drm_plane_mask() & co.").  Apparently we haven't actually been using
that macro, but we don't start using it in this patch, so it should
probably be fixed separately.

>  #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
>  	list_for_each_entry(intel_plane,				\
> @@ -415,6 +415,15 @@ struct intel_link_m_n {
>  	     (__i)++) \
>  		for_each_if(plane)
>  
> +#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
> +		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
> +		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
> +		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
> +	     (__i)++) \
> +		for_each_if(crtc)
> +
>  void intel_link_compute_m_n(int bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
>  			    struct intel_link_m_n *m_n,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index fae8c8f6d009..64ee84c6ee09 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -705,6 +705,8 @@ struct intel_crtc_wm_state {
>  			/* gen9+ only needs 1-step wm programming */
>  			struct skl_pipe_wm optimal;
>  			struct skl_ddb_entry ddb;
> +			struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
> +			struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES];
>  		} skl;
>  
>  		struct {
> @@ -2183,6 +2185,9 @@ void g4x_wm_get_hw_state(struct drm_device *dev);
>  void vlv_wm_get_hw_state(struct drm_device *dev);
>  void ilk_wm_get_hw_state(struct drm_device *dev);
>  void skl_wm_get_hw_state(struct drm_device *dev);
> +void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
> +			       struct skl_ddb_entry *ddb_y,
> +			       struct skl_ddb_entry *ddb_uv);
>  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
>  			  struct skl_ddb_allocation *ddb /* out */);
>  void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
> @@ -2197,6 +2202,10 @@ bool skl_wm_level_equals(const struct skl_wm_level *l1,
>  bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
>  				 const struct skl_ddb_entry entries[],
>  				 int num_entries, int ignore_idx);
> +void skl_write_plane_wm(struct intel_plane *plane,
> +			const struct intel_crtc_state *crtc_state);
> +void skl_write_cursor_wm(struct intel_plane *plane,
> +			 const struct intel_crtc_state *crtc_state);
>  bool ilk_disable_lp_wm(struct drm_device *dev);
>  int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  				  struct intel_crtc_state *cstate);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 749e8d814ce5..40406cc0d40b 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3911,68 +3911,70 @@ static void
>  skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
>  			   const enum pipe pipe,
>  			   const enum plane_id plane_id,
> -			   struct skl_ddb_allocation *ddb /* out */)
> +			   struct skl_ddb_entry *ddb_y,
> +			   struct skl_ddb_entry *ddb_uv)
>  {
> -	u32 val, val2 = 0;
> -	int fourcc, pixel_format;
> +	u32 val, val2;
> +	u32 fourcc = 0;
>  
>  	/* Cursor doesn't support NV12/planar, so no extra calculation needed */
>  	if (plane_id == PLANE_CURSOR) {
>  		val = I915_READ(CUR_BUF_CFG(pipe));
> -		skl_ddb_entry_init_from_hw(dev_priv,
> -					   &ddb->plane[pipe][plane_id], val);
> +		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
>  		return;
>  	}
>  
>  	val = I915_READ(PLANE_CTL(pipe, plane_id));
>  
>  	/* No DDB allocated for disabled planes */

The code flow below no longer matches this comment...we now only skip
fourcc lookup for disabled planes, but still read the buf registers and
fill in the ddb entry structures.  Was this change intentional?  I'd
expect the registers to probably give us zero'd entries when we read
them, but I'm not sure if that's actually true when reading in the
initial BIOS state.

> -	if (!(val & PLANE_CTL_ENABLE))
> -		return;
> -
> -	pixel_format = val & PLANE_CTL_FORMAT_MASK;
> -	fourcc = skl_format_to_fourcc(pixel_format,
> -				      val & PLANE_CTL_ORDER_RGBX,
> -				      val & PLANE_CTL_ALPHA_MASK);
> +	if (val & PLANE_CTL_ENABLE)
> +		fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK,
> +					      val & PLANE_CTL_ORDER_RGBX,
> +					      val & PLANE_CTL_ALPHA_MASK);
>  
> -	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
> -	if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) {
> +	if (INTEL_GEN(dev_priv) >= 11) {
> +		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
> +		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
> +	} else {
> +		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
>  		val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
>  
> -		skl_ddb_entry_init_from_hw(dev_priv,
> -					   &ddb->plane[pipe][plane_id], val2);
> -		skl_ddb_entry_init_from_hw(dev_priv,
> -					   &ddb->uv_plane[pipe][plane_id], val);
> -	} else {
> -		skl_ddb_entry_init_from_hw(dev_priv,
> -					   &ddb->plane[pipe][plane_id], val);
> +		if (fourcc == DRM_FORMAT_NV12)
> +			swap(val, val2);
> +
> +		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
> +		skl_ddb_entry_init_from_hw(dev_priv, ddb_uv, val2);
>  	}
>  }
>  
> -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> -			  struct skl_ddb_allocation *ddb /* out */)
> +void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
> +			       struct skl_ddb_entry *ddb_y,
> +			       struct skl_ddb_entry *ddb_uv)
>  {
> -	struct intel_crtc *crtc;
> -
> -	memset(ddb, 0, sizeof(*ddb));
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum intel_display_power_domain power_domain;
> +	enum pipe pipe = crtc->pipe;
> +	enum plane_id plane_id;
>  
> -	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
> +	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> +		return;
>  
> -	for_each_intel_crtc(&dev_priv->drm, crtc) {
> -		enum intel_display_power_domain power_domain;
> -		enum plane_id plane_id;
> -		enum pipe pipe = crtc->pipe;
> +	for_each_plane_id_on_crtc(crtc, plane_id)
> +		skl_ddb_get_hw_plane_state(dev_priv, pipe,
> +					   plane_id,
> +					   &ddb_y[plane_id],
> +					   &ddb_uv[plane_id]);
>  
> -		power_domain = POWER_DOMAIN_PIPE(pipe);
> -		if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> -			continue;
> +	intel_display_power_put(dev_priv, power_domain);
> +}
>  
> -		for_each_plane_id_on_crtc(crtc, plane_id)
> -			skl_ddb_get_hw_plane_state(dev_priv, pipe,
> -						   plane_id, ddb);
> +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> +			  struct skl_ddb_allocation *ddb /* out */)
> +{
> +	memset(ddb, 0, sizeof(*ddb));

The only thing left in the structure is 'enabled_slices' which we set
directly below, so I think this memset is unnecessary.  Although as
noted above, it would be better to just eliminate the structure itself.

>  
> -		intel_display_power_put(dev_priv, power_domain);
> -	}
> +	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
>  }
>  
>  /*
> @@ -4370,7 +4372,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	struct drm_crtc *crtc = cstate->base.crtc;
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum pipe pipe = intel_crtc->pipe;
>  	struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
>  	uint16_t alloc_size, start;
>  	uint16_t minimum[I915_MAX_PLANES] = {};
> @@ -4383,8 +4384,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	uint16_t total_min_blocks = 0;
>  
>  	/* Clear the partitioning for disabled planes. */
> -	memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
> -	memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
> +	memset(cstate->wm.skl.plane_ddb_y, 0, sizeof(cstate->wm.skl.plane_ddb_y));
> +	memset(cstate->wm.skl.plane_ddb_uv, 0, sizeof(cstate->wm.skl.plane_ddb_uv));
>  
>  	if (WARN_ON(!state))
>  		return 0;
> @@ -4431,8 +4432,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	}
>  
>  	alloc_size -= total_min_blocks;
> -	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
> -	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
> +	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
> +	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end;
>  
>  	/*
>  	 * 2. Distribute the remaining space in proportion to the amount of
> @@ -4463,8 +4464,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  
>  		/* Leave disabled planes at (0,0) */
>  		if (data_rate) {
> -			ddb->plane[pipe][plane_id].start = start;
> -			ddb->plane[pipe][plane_id].end = start + plane_blocks;
> +			cstate->wm.skl.plane_ddb_y[plane_id].start = start;
> +			cstate->wm.skl.plane_ddb_y[plane_id].end = start + plane_blocks;
>  		}
>  
>  		start += plane_blocks;
> @@ -4479,8 +4480,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks);
>  
>  		if (uv_data_rate) {
> -			ddb->uv_plane[pipe][plane_id].start = start;
> -			ddb->uv_plane[pipe][plane_id].end =
> +			cstate->wm.skl.plane_ddb_uv[plane_id].start = start;
> +			cstate->wm.skl.plane_ddb_uv[plane_id].end =
>  				start + uv_plane_blocks;
>  		}
>  
> @@ -4590,9 +4591,6 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
>  		to_intel_atomic_state(cstate->base.state);
>  	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
>  
> -	if (!intel_wm_plane_visible(cstate, intel_pstate))
> -		return 0;
> -

It's not clear to me why we remove this?  Can't we still get here for
disabled planes (where fb is NULL)?  

>  	/* only NV12 format has two planes */
>  	if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) {
>  		DRM_DEBUG_KMS("Non NV12 format have single plane\n");
> @@ -4706,9 +4704,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	if (latency == 0)
>  		return level == 0 ? -EINVAL : 0;
>  
> -	if (!intel_wm_plane_visible(cstate, intel_pstate))
> -		return 0;
> -

Unlike above, I think we always have a valid fb here.  But I don't see
how this relates to what the rest of the patch is trying to do?  In fact
from this point on, I'm getting a bit lost in a lot of codeflow changes
on the 'check' part of the transaction that don't seem like it's
directly related to state goal of writing watermarks as part of the main
plane register update (which should be mostly on the 'commit' side) or
moving ddb into cstate.  

It feels like we're also tackling a lot of nv12 watermark behavior
changes with this patch; is it possible to separate that out into a
separate patch?


Matt

>  	/* Display WA #1141: kbl,cfl */
>  	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
>  	    IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) &&
> @@ -4831,21 +4826,16 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  
>  static int
>  skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
> -		      struct skl_ddb_allocation *ddb,
>  		      const struct intel_crtc_state *cstate,
>  		      const struct intel_plane_state *intel_pstate,
>  		      uint16_t ddb_blocks,
>  		      const struct skl_wm_params *wm_params,
> -		      struct skl_plane_wm *wm,
>  		      struct skl_wm_level *levels)
>  {
>  	int level, max_level = ilk_wm_max_level(dev_priv);
>  	struct skl_wm_level *result_prev = &levels[0];
>  	int ret;
>  
> -	if (WARN_ON(!intel_pstate->base.fb))
> -		return -EINVAL;
> -
>  	for (level = 0; level <= max_level; level++) {
>  		struct skl_wm_level *result = &levels[level];
>  
> @@ -4863,9 +4853,6 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
>  		result_prev = result;
>  	}
>  
> -	if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
> -		wm->is_planar = true;
> -
>  	return 0;
>  }
>  
> @@ -4893,10 +4880,9 @@ skl_compute_linetime_wm(const struct intel_crtc_state *cstate)
>  }
>  
>  static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> -				      struct skl_wm_params *wp,
> -				      struct skl_wm_level *wm_l0,
> -				      uint16_t ddb_allocation,
> -				      struct skl_wm_level *trans_wm /* out */)
> +				      const struct skl_wm_params *wp,
> +				      struct skl_plane_wm *wm,
> +				      uint16_t ddb_allocation)
>  {
>  	struct drm_device *dev = cstate->base.crtc->dev;
>  	const struct drm_i915_private *dev_priv = to_i915(dev);
> @@ -4904,9 +4890,6 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
>  	const uint16_t trans_amount = 10; /* This is configurable amount */
>  	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
>  
> -	if (!cstate->base.active)
> -		return;
> -
>  	/* Transition WM are not recommended by HW team for GEN9 */
>  	if (INTEL_GEN(dev_priv) <= 9)
>  		return;
> @@ -4931,7 +4914,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
>  	 * Result Blocks is Result Blocks minus 1 and it should work for the
>  	 * current platforms.
>  	 */
> -	wm0_sel_res_b = wm_l0->plane_res_b - 1;
> +	wm0_sel_res_b = wm->wm[0].plane_res_b - 1;
>  
>  	if (wp->y_tiled) {
>  		trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2,
> @@ -4950,23 +4933,19 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
>  	res_blocks += 1;
>  
>  	if (res_blocks < ddb_allocation) {
> -		trans_wm->plane_res_b = res_blocks;
> -		trans_wm->plane_en = true;
> +		wm->trans_wm.plane_res_b = res_blocks;
> +		wm->trans_wm.plane_en = true;
>  	}
>  }
>  
> -static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> -				       struct skl_pipe_wm *pipe_wm,
> -				       enum plane_id plane_id,
> -				       const struct intel_crtc_state *cstate,
> -				       const struct intel_plane_state *pstate,
> -				       int color_plane)
> +static int skl_build_plane_wm_single(struct intel_crtc_state *cstate,
> +				     const struct intel_plane_state *pstate,
> +				     enum plane_id plane_id, int color_plane)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
> -	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
> -	enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe;
> +	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
> +	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_y[plane_id]);
>  	struct skl_wm_params wm_params;
> -	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
>  	int ret;
>  
>  	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
> @@ -4974,79 +4953,105 @@ static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
>  	if (ret)
>  		return ret;
>  
> -	ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
> -				    ddb_blocks, &wm_params, wm, wm->wm);
> -
> +	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
> +				    ddb_blocks, &wm_params, wm->wm);
>  	if (ret)
>  		return ret;
>  
> -	skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
> -				  ddb_blocks, &wm->trans_wm);
> +	skl_compute_transition_wm(cstate, &wm_params, wm, ddb_blocks);
>  
>  	return 0;
>  }
>  
> -static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> -				     struct skl_pipe_wm *pipe_wm,
> -				     const struct intel_crtc_state *cstate,
> -				     const struct intel_plane_state *pstate)
> +static int skl_build_plane_wm_uv(struct intel_crtc_state *cstate,
> +				 const struct intel_plane_state *pstate,
> +				 enum plane_id plane_id)
>  {
> -	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
> +	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
> +	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
> +	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_uv[plane_id]);
> +	struct skl_wm_params wm_params;
> +	int ret;
> +
> +	wm->is_planar = true;
>  
> -	return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
> +	/* uv plane watermarks must also be validated for NV12/Planar */
> +	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
> +					  &wm_params, 1);
> +	if (ret)
> +		return ret;
> +
> +	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
> +				    ddb_blocks, &wm_params, wm->uv_wm);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
>  }
>  
> -static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
> -				     struct skl_pipe_wm *pipe_wm,
> -				     const struct intel_crtc_state *cstate,
> -				     const struct intel_plane_state *pstate)
> +static int skl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
> +			      struct intel_crtc_state *cstate,
> +			      const struct intel_plane_state *pstate)
>  {
>  	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	const struct drm_framebuffer *fb = pstate->base.fb;
>  	enum plane_id plane_id = plane->id;
> -	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
> -	struct skl_wm_params wm_params;
> -	enum pipe pipe = plane->pipe;
> -	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
>  	int ret;
>  
> -	ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
> -	if (ret)
> -		return ret;
> -
> -	/* uv plane watermarks must also be validated for NV12/Planar */
> -	ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]);
> +	if (!intel_wm_plane_visible(cstate, pstate))
> +		return 0;
>  
> -	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1);
> +	ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
>  	if (ret)
>  		return ret;
>  
> -	return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
> -				     ddb_blocks, &wm_params, wm, wm->uv_wm);
> +	if (fb->format->is_yuv && fb->format->num_planes > 1) {
> +		ret = skl_build_plane_wm_uv(cstate, pstate, plane_id);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
>  }
>  
> -static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
> -				     struct skl_pipe_wm *pipe_wm,
> -				     const struct intel_crtc_state *cstate,
> -				     const struct intel_plane_state *pstate)
> +static int icl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
> +			      struct intel_crtc_state *cstate,
> +			      const struct intel_plane_state *pstate)
>  {
> +	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
>  	int ret;
> -	enum plane_id y_plane_id = pstate->linked_plane->id;
> -	enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id;
>  
> -	ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id,
> -					  cstate, pstate, 0);
> -	if (ret)
> -		return ret;
> +	/* Watermarks calculated in master */
> +	if (pstate->slave)
> +		return 0;
> +
> +	if (pstate->linked_plane) {
> +		const struct drm_framebuffer *fb = pstate->base.fb;
> +		enum plane_id y_plane_id = pstate->linked_plane->id;
> +
> +		WARN_ON(!fb->format->is_yuv ||
> +			fb->format->num_planes == 1);
> +
> +		ret = skl_build_plane_wm_single(cstate, pstate, y_plane_id, 0);
> +		if (ret)
> +			return ret;
>  
> -	return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id,
> -					   cstate, pstate, 1);
> +		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 1);
> +		if (ret)
> +			return ret;
> +	} else if (intel_wm_plane_visible(cstate, pstate)) {
> +		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
>  }
>  
>  static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
> -			     struct skl_ddb_allocation *ddb,
>  			     struct skl_pipe_wm *pipe_wm)
>  {
> +	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
>  	struct drm_crtc_state *crtc_state = &cstate->base;
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *pstate;
> @@ -5062,18 +5067,10 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
>  		const struct intel_plane_state *intel_pstate =
>  						to_intel_plane_state(pstate);
>  
> -		/* Watermarks calculated in master */
> -		if (intel_pstate->slave)
> -			continue;
> -
> -		if (intel_pstate->linked_plane)
> -			ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
> -		else if (intel_pstate->base.fb &&
> -			 intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
> -			ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
> +		if (INTEL_GEN(dev_priv) >= 11)
> +			ret = icl_build_plane_wm(pipe_wm, cstate, intel_pstate);
>  		else
> -			ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate);
> -
> +			ret = skl_build_plane_wm(pipe_wm, cstate, intel_pstate);
>  		if (ret)
>  			return ret;
>  	}
> @@ -5088,9 +5085,9 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
>  				const struct skl_ddb_entry *entry)
>  {
>  	if (entry->end)
> -		I915_WRITE(reg, (entry->end - 1) << 16 | entry->start);
> +		I915_WRITE_FW(reg, (entry->end - 1) << 16 | entry->start);
>  	else
> -		I915_WRITE(reg, 0);
> +		I915_WRITE_FW(reg, 0);
>  }
>  
>  static void skl_write_wm_level(struct drm_i915_private *dev_priv,
> @@ -5105,19 +5102,22 @@ static void skl_write_wm_level(struct drm_i915_private *dev_priv,
>  		val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
>  	}
>  
> -	I915_WRITE(reg, val);
> +	I915_WRITE_FW(reg, val);
>  }
>  
> -static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> -			       const struct skl_plane_wm *wm,
> -			       const struct skl_ddb_allocation *ddb,
> -			       enum plane_id plane_id)
> +void skl_write_plane_wm(struct intel_plane *plane,
> +			const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_crtc *crtc = &intel_crtc->base;
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	int level, max_level = ilk_wm_max_level(dev_priv);
> -	enum pipe pipe = intel_crtc->pipe;
> +	enum plane_id plane_id = plane->id;
> +	enum pipe pipe = plane->pipe;
> +	const struct skl_plane_wm *wm =
> +		&crtc_state->wm.skl.optimal.planes[plane_id];
> +	const struct skl_ddb_entry *ddb_y =
> +		&crtc_state->wm.skl.plane_ddb_y[plane_id];
> +	const struct skl_ddb_entry *ddb_uv =
> +		&crtc_state->wm.skl.plane_ddb_uv[plane_id];
>  
>  	for (level = 0; level <= max_level; level++) {
>  		skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level),
> @@ -5126,29 +5126,32 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
>  	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
>  			   &wm->trans_wm);
>  
> -	if (wm->is_planar && INTEL_GEN(dev_priv) < 11) {
> -		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
> -				    &ddb->uv_plane[pipe][plane_id]);
> +	if (INTEL_GEN(dev_priv) >= 11) {
>  		skl_ddb_entry_write(dev_priv,
> -				    PLANE_NV12_BUF_CFG(pipe, plane_id),
> -				    &ddb->plane[pipe][plane_id]);
> -	} else {
> -		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
> -				    &ddb->plane[pipe][plane_id]);
> -		if (INTEL_GEN(dev_priv) < 11)
> -			I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
> +				    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
> +		return;
>  	}
> +
> +	if (wm->is_planar)
> +		swap(ddb_y, ddb_uv);
> +
> +	skl_ddb_entry_write(dev_priv,
> +			    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
> +	skl_ddb_entry_write(dev_priv,
> +			    PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv);
>  }
>  
> -static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> -				const struct skl_plane_wm *wm,
> -				const struct skl_ddb_allocation *ddb)
> +void skl_write_cursor_wm(struct intel_plane *plane,
> +			 const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_crtc *crtc = &intel_crtc->base;
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	int level, max_level = ilk_wm_max_level(dev_priv);
> -	enum pipe pipe = intel_crtc->pipe;
> +	enum plane_id plane_id = plane->id;
> +	enum pipe pipe = plane->pipe;
> +	const struct skl_plane_wm *wm =
> +		&crtc_state->wm.skl.optimal.planes[plane_id];
> +	const struct skl_ddb_entry *ddb =
> +		&crtc_state->wm.skl.plane_ddb_y[plane_id];
>  
>  	for (level = 0; level <= max_level; level++) {
>  		skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
> @@ -5156,8 +5159,7 @@ static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
>  	}
>  	skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm);
>  
> -	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
> -			    &ddb->plane[pipe][PLANE_CURSOR]);
> +	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb);
>  }
>  
>  bool skl_wm_level_equals(const struct skl_wm_level *l1,
> @@ -5198,13 +5200,12 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
>  static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
>  			      const struct skl_pipe_wm *old_pipe_wm,
>  			      struct skl_pipe_wm *pipe_wm, /* out */
> -			      struct skl_ddb_allocation *ddb, /* out */
>  			      bool *changed /* out */)
>  {
>  	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
>  	int ret;
>  
> -	ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
> +	ret = skl_build_pipe_wm(intel_cstate, pipe_wm);
>  	if (ret)
>  		return ret;
>  
> @@ -5230,42 +5231,29 @@ pipes_modified(struct drm_atomic_state *state)
>  }
>  
>  static int
> -skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
> +skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
> +			    struct intel_crtc_state *new_crtc_state)
>  {
> -	struct drm_atomic_state *state = cstate->base.state;
> -	struct drm_device *dev = state->dev;
> -	struct drm_crtc *crtc = cstate->base.crtc;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> -	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
> -	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> -	struct drm_plane *plane;
> -	enum pipe pipe = intel_crtc->pipe;
> +	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	struct intel_plane *plane;
>  
> -	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
> -		struct drm_plane_state *plane_state;
> -		struct intel_plane *linked;
> -		enum plane_id plane_id = to_intel_plane(plane)->id;
> +	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> +		struct intel_plane_state *plane_state;
> +		enum plane_id plane_id = plane->id;
>  
> -		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
> -					&new_ddb->plane[pipe][plane_id]) &&
> -		    skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
> -					&new_ddb->uv_plane[pipe][plane_id]))
> +		if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
> +					&new_crtc_state->wm.skl.plane_ddb_y[plane_id]) &&
> +		    skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id],
> +					&new_crtc_state->wm.skl.plane_ddb_uv[plane_id]))
>  			continue;
>  
> -		plane_state = drm_atomic_get_plane_state(state, plane);
> +		plane_state = intel_atomic_get_plane_state(state, plane);
>  		if (IS_ERR(plane_state))
>  			return PTR_ERR(plane_state);
>  
> -		/* Make sure linked plane is updated too */
> -		linked = to_intel_plane_state(plane_state)->linked_plane;
> -		if (!linked)
> -			continue;
> -
> -		plane_state = drm_atomic_get_plane_state(state, &linked->base);
> -		if (IS_ERR(plane_state))
> -			return PTR_ERR(plane_state);
> +		new_crtc_state->update_planes |= BIT(plane_id);
>  	}
>  
>  	return 0;
> @@ -5277,18 +5265,21 @@ skl_compute_ddb(struct drm_atomic_state *state)
>  	const struct drm_i915_private *dev_priv = to_i915(state->dev);
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
> +	struct intel_crtc_state *old_crtc_state;
> +	struct intel_crtc_state *new_crtc_state;
>  	struct intel_crtc *crtc;
> -	struct intel_crtc_state *cstate;
>  	int ret, i;
>  
>  	memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
>  
> -	for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) {
> -		ret = skl_allocate_pipe_ddb(cstate, ddb);
> +	for_each_oldnew_intel_crtc_in_state(intel_state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		ret = skl_allocate_pipe_ddb(new_crtc_state, ddb);
>  		if (ret)
>  			return ret;
>  
> -		ret = skl_ddb_add_affected_planes(cstate);
> +		ret = skl_ddb_add_affected_planes(old_crtc_state,
> +						  new_crtc_state);
>  		if (ret)
>  			return ret;
>  	}
> @@ -5297,36 +5288,29 @@ skl_compute_ddb(struct drm_atomic_state *state)
>  }
>  
>  static void
> -skl_print_wm_changes(const struct drm_atomic_state *state)
> +skl_print_wm_changes(struct intel_atomic_state *state)
>  {
> -	const struct drm_device *dev = state->dev;
> -	const struct drm_i915_private *dev_priv = to_i915(dev);
> -	const struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(state);
> -	const struct drm_crtc *crtc;
> -	const struct drm_crtc_state *cstate;
> -	const struct intel_plane *intel_plane;
> -	const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb;
> -	const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	const struct intel_crtc_state *old_crtc_state;
> +	const struct intel_crtc_state *new_crtc_state;
> +	struct intel_plane *plane;
> +	struct intel_crtc *crtc;
>  	int i;
>  
> -	for_each_new_crtc_in_state(state, crtc, cstate, i) {
> -		const struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -		enum pipe pipe = intel_crtc->pipe;
> -
> -		for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> -			enum plane_id plane_id = intel_plane->id;
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> +			enum plane_id plane_id = plane->id;
>  			const struct skl_ddb_entry *old, *new;
>  
> -			old = &old_ddb->plane[pipe][plane_id];
> -			new = &new_ddb->plane[pipe][plane_id];
> +			old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id];
> +			new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id];
>  
>  			if (skl_ddb_entry_equal(old, new))
>  				continue;
>  
>  			DRM_DEBUG_KMS("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n",
> -				      intel_plane->base.base.id,
> -				      intel_plane->base.name,
> +				      plane->base.base.id, plane->base.name,
>  				      old->start, old->end,
>  				      new->start, new->end);
>  		}
> @@ -5462,8 +5446,7 @@ skl_compute_wm(struct drm_atomic_state *state)
>  			&to_intel_crtc_state(crtc->state)->wm.skl.optimal;
>  
>  		pipe_wm = &intel_cstate->wm.skl.optimal;
> -		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm,
> -					 &results->ddb, &changed);
> +		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, &changed);
>  		if (ret)
>  			return ret;
>  
> @@ -5477,7 +5460,7 @@ skl_compute_wm(struct drm_atomic_state *state)
>  		intel_cstate->update_wm_pre = true;
>  	}
>  
> -	skl_print_wm_changes(state);
> +	skl_print_wm_changes(intel_state);
>  
>  	return 0;
>  }
> @@ -5488,23 +5471,12 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
>  	struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
> -	const struct skl_ddb_allocation *ddb = &state->wm_results.ddb;
>  	enum pipe pipe = crtc->pipe;
> -	enum plane_id plane_id;
>  
>  	if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base)))
>  		return;
>  
>  	I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime);
> -
> -	for_each_plane_id_on_crtc(crtc, plane_id) {
> -		if (plane_id != PLANE_CURSOR)
> -			skl_write_plane_wm(crtc, &pipe_wm->planes[plane_id],
> -					   ddb, plane_id);
> -		else
> -			skl_write_cursor_wm(crtc, &pipe_wm->planes[plane_id],
> -					    ddb);
> -	}
>  }
>  
>  static void skl_initial_wm(struct intel_atomic_state *state,
> @@ -5514,8 +5486,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct skl_ddb_values *results = &state->wm_results;
> -	struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw;
> -	enum pipe pipe = intel_crtc->pipe;
>  
>  	if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0)
>  		return;
> @@ -5525,11 +5495,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
>  	if (cstate->base.active_changed)
>  		skl_atomic_update_crtc_wm(state, cstate);
>  
> -	memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe],
> -	       sizeof(hw_vals->ddb.uv_plane[pipe]));
> -	memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe],
> -	       sizeof(hw_vals->ddb.plane[pipe]));
> -
>  	mutex_unlock(&dev_priv->wm.wm_mutex);
>  }
>  
> @@ -5680,13 +5645,6 @@ void skl_wm_get_hw_state(struct drm_device *dev)
>  	if (dev_priv->active_crtcs) {
>  		/* Fully recompute DDB on first atomic commit */
>  		dev_priv->wm.distrust_bios_wm = true;
> -	} else {
> -		/*
> -		 * Easy/common case; just sanitize DDB now if everything off
> -		 * Keep dbuf slice info intact
> -		 */
> -		memset(ddb->plane, 0, sizeof(ddb->plane));
> -		memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane));
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 99d4396cac00..126a51a7b376 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -535,6 +535,8 @@ skl_program_plane(struct intel_plane *plane,
>  	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
>  		icl_program_input_csc_coeff(crtc_state, plane_state);
>  
> +	skl_write_plane_wm(plane, crtc_state);
> +
>  	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
>  	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
>  	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> @@ -597,6 +599,8 @@ skl_disable_plane(struct intel_plane *plane,
>  
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
> +	skl_write_plane_wm(plane, crtc_state);
> +
>  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
>  
> -- 
> 2.18.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://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
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end
  2018-11-08 22:06   ` Matt Roper
@ 2018-11-09 13:55     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-09 13:55 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Thu, Nov 08, 2018 at 02:06:52PM -0800, Matt Roper wrote:
> On Thu, Nov 01, 2018 at 05:05:58PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > The plane color correction registers are single buffered. So
> > ideally we would write them at the start of vblank just after the
> > double buffered plane registers have been latched. Since we have
> > no convenient way to do that for now let's at least move the
> > single buffered register writes to happen after the double
> > buffered registers have been written.
> 
> Should we move this all the way out of the vblank evasion?  I realize
> that vlv is only two registers total so it's not a big deal, but I know
> Uma is working on the plane color management stuff for later platforms
> where we have a bunch of registers to write, so maybe we should setup
> the callsite now?

I didn't want to pile on too much work in this series. For the
plane color management we might need to think how to do this
properly as otherwise it's may end up being too ugly to actually
use.

I also have a branch somewhere with fp16 scanout support, and on
ivb that requires playing around with the plane gamma as well.
So that could be another natural point when we might come up with
a better mechanism for single buffered registers. Although I'm 
not sure we can land fp16 any time soon though since there is no
userspace currently. I implemented it just so that I could test
the higher precision pipe gamma modes.

> 
> On a similar note, I notice our single-buffered pipe-level color
> management registers are written before evasion right now...should we
> move that to after the evasion as well?

Yes. I have that actually implemented on a branch that reworks the
pipe color management stuff quite a bit. I'm actually moving it to
happen after the vblank waits in the sequence, but I didn't add any
kind of proper vblank worker etc. so I expect it's still likely to
tear :( But at least it's a bit closer to where it really should be.

I'm planning to post that series after this stuff lands as there
is a slight dependency on the update_planes stuff and whatnot.

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

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

* Re: [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask
  2018-11-08 23:22   ` Matt Roper
@ 2018-11-09 13:57     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-09 13:57 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Thu, Nov 08, 2018 at 03:22:27PM -0800, Matt Roper wrote:
> On Thu, Nov 01, 2018 at 05:06:00PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Keep track which planes need updating during the commit. For now this
> > is just (was_visible || is_visible) but I'll have need to update
> 
> When gen11 nv12 is in use, it also contains was_slave || is_slave as
> well, right?
> 
> > invisible planes later on for skl plane ddbs and for pre-skl pipe
> > gamma/csc control (which lives in the primary plane control register).
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c       | 1 +
> >  drivers/gpu/drm/i915/intel_atomic_plane.c | 8 ++++----
> >  drivers/gpu/drm/i915/intel_display.c      | 5 ++++-
> >  drivers/gpu/drm/i915/intel_drv.h          | 3 +++
> >  4 files changed, 12 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> > index a5a2c8fe58a7..8cb02f28d30c 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -184,6 +184,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
> >  	crtc_state->fifo_changed = false;
> >  	crtc_state->wm.need_postvbl_update = false;
> >  	crtc_state->fb_bits = 0;
> > +	crtc_state->update_planes = 0;
> >  
> >  	return &crtc_state->base;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > index 7d3685075201..010269a12390 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > @@ -137,6 +137,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
> >  	if (state->visible && state->fb->format->format == DRM_FORMAT_NV12)
> >  		crtc_state->nv12_planes |= BIT(intel_plane->id);
> >  
> > +	if (state->visible || old_plane_state->base.visible)
> > +		crtc_state->update_planes |= BIT(intel_plane->id);
> > +
> >  	return intel_plane_atomic_calc_changes(old_crtc_state,
> >  					       &crtc_state->base,
> >  					       old_plane_state,
> > @@ -171,14 +174,11 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
> >  				 struct intel_crtc_state *old_crtc_state,
> >  				 struct intel_crtc_state *new_crtc_state)
> >  {
> > +	u32 update_mask = new_crtc_state->update_planes;
> >  	struct intel_plane_state *new_plane_state;
> >  	struct intel_plane *plane;
> > -	u32 update_mask;
> >  	int i;
> >  
> > -	update_mask = old_crtc_state->active_planes;
> > -	update_mask |= new_crtc_state->active_planes;
> > -
> >  	for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) {
> >  		if (crtc->pipe != plane->pipe ||
> >  		    !(update_mask & BIT(plane->id)))
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 852b5897e80b..33d73915b73e 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10797,8 +10797,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> >  			continue;
> >  
> >  		plane_state->linked_plane = NULL;
> > -		if (plane_state->slave && !plane_state->base.visible)
> > +		if (plane_state->slave && !plane_state->base.visible) {
> >  			crtc_state->active_planes &= ~BIT(plane->id);
> > +			crtc_state->update_planes |= BIT(plane->id);
> 
> Just to clarify, this is to ensure that we clear out the register
> programming of a plane that was an nv12 slave on the previous frame, but
> isn't any longer on the current frame, and ...
> 
> 
> > +		}
> >  
> >  		plane_state->slave = false;
> >  	}
> > @@ -10839,6 +10841,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> >  		linked_state->slave = true;
> >  		linked_state->linked_plane = plane;
> >  		crtc_state->active_planes |= BIT(linked->id);
> > +		crtc_state->update_planes |= BIT(linked->id);
> 
> ... this is to ensure we setup the programming for any new slave planes?

Yes.

> 
> 
> Matt
> 
> >  		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 5331bbed5e8c..7a55f5921d34 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -925,6 +925,9 @@ struct intel_crtc_state {
> >  	u8 active_planes;
> >  	u8 nv12_planes;
> >  
> > +	/* bitmask of planes that will be updated during the commit */
> > +	u8 update_planes;
> > +
> >  	/* HDMI scrambling status */
> >  	bool hdmi_scrambling;
> >  
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

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

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

* Re: [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane()
  2018-11-08 23:52   ` Matt Roper
@ 2018-11-09 14:32     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-09 14:32 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Thu, Nov 08, 2018 at 03:52:02PM -0800, Matt Roper wrote:
> On Thu, Nov 01, 2018 at 05:06:01PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > We're going to need access to the new crtc state in ->disable_plane()
> > for SKL+ wm/ddb programming and pre-skl pipe gamma/csc control. Pass
> > the crtc state down.
> > 
> > We'll also try to make intel_crtc_disable_planes() drtr as much as
> 
> What does "drtr" stand for?

Should have been "dtrt" as in "do the right thing".

> 
> The main behavioral change I see in that function is that we don't do
> frontbuffer tracking for nv12 slave planes anymore (and in the future
> won't do it for other planes that weren't visible, but you still want to
> reprogram them in some way).

So intel_post_plane_update() calls
frontbuffer_flip(pipe_config->fb_bits), pipe_config->fb_bits is
populated by intel_plane_atomic_calc_changes() based on the
old+new plane visibility, hence new slave planes won't be set in
that bitmask, unless they were previosuly used as non-slave
planes. So I think that does agree with my new code pretty well.

However, thinking a bit more what the frontbuffer tracking is trying
to achieve, maybe we should always include every visible plane that
is being reprogrammed. Eg. if we have to reprogram plane 1A on account
of a ddb change the resulting flip does cause an fbc nuke, which
could be used by the frontbuffer tracking to re-enable fbc if it
had been previosuly invalidated. But this probably needs more thought
so should be done later (if ever).

> 
> 
> Matt
> 
> > it's possible. The fact that we don't have a separate crtc state
> > for the disabled state when we're going to re-enable the crtc later
> > means we might end up poking at a few extra planes in there. But
> > that's harmless. I suppose one migth argue that we wouldn't have to
> > care about proper ddb/wm/csc/gamma if the pipe is going to permanently
> > disable anyway, but the state checker probably cares so we should try
> > our best to make sure everything is programmed correctly even in that
> > case.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic_plane.c |  2 +-
> >  drivers/gpu/drm/i915/intel_display.c      | 39 ++++++++++++++---------
> >  drivers/gpu/drm/i915/intel_display.h      |  8 +++++
> >  drivers/gpu/drm/i915/intel_drv.h          |  2 +-
> >  drivers/gpu/drm/i915/intel_sprite.c       | 12 ++++---
> >  5 files changed, 42 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > index 010269a12390..69fc7010190c 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > @@ -210,7 +210,7 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
> >  		} else {
> >  			trace_intel_disable_plane(&plane->base, crtc);
> >  
> > -			plane->disable_plane(plane, crtc);
> > +			plane->disable_plane(plane, new_crtc_state);
> >  		}
> >  	}
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 33d73915b73e..6088ae554e56 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2781,7 +2781,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
> >  		intel_pre_disable_primary_noatomic(&crtc->base);
> >  
> >  	trace_intel_disable_plane(&plane->base, crtc);
> > -	plane->disable_plane(plane, crtc);
> > +	plane->disable_plane(plane, crtc_state);
> >  }
> >  
> >  static void
> > @@ -3386,7 +3386,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void i9xx_disable_plane(struct intel_plane *plane,
> > -			       struct intel_crtc *crtc)
> > +			       const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> > @@ -5421,23 +5421,32 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
> >  		intel_update_watermarks(crtc);
> >  }
> >  
> > -static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask)
> > +static void intel_crtc_disable_planes(struct intel_atomic_state *state,
> > +				      struct intel_crtc *crtc)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	const struct intel_crtc_state *new_crtc_state =
> > +		intel_atomic_get_new_crtc_state(state, crtc);
> > +	unsigned int update_mask = new_crtc_state->update_planes;
> > +	const struct intel_plane_state *old_plane_state;
> >  	struct intel_plane *plane;
> >  	unsigned fb_bits = 0;
> > +	int i;
> >  
> >  	intel_crtc_dpms_overlay_disable(crtc);
> >  
> > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > -		if (plane_mask & BIT(plane->id)) {
> > -			plane->disable_plane(plane, crtc);
> > +	for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
> > +		if (crtc->pipe != plane->pipe ||
> > +		    !(update_mask & BIT(plane->id)))
> > +			continue;
> > +
> > +		plane->disable_plane(plane, new_crtc_state);
> >  
> > +		if (old_plane_state->base.visible)
> >  			fb_bits |= plane->frontbuffer_bit;
> > -		}
> >  	}
> >  
> > -	intel_frontbuffer_flip(to_i915(dev), fb_bits);
> > +	intel_frontbuffer_flip(dev_priv, fb_bits);
> >  }
> >  
> >  static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc,
> > @@ -9855,9 +9864,9 @@ static void i845_update_cursor(struct intel_plane *plane,
> >  }
> >  
> >  static void i845_disable_cursor(struct intel_plane *plane,
> > -				struct intel_crtc *crtc)
> > +				const struct intel_crtc_state *crtc_state)
> >  {
> > -	i845_update_cursor(plane, NULL, NULL);
> > +	i845_update_cursor(plane, crtc_state, NULL);
> >  }
> >  
> >  static bool i845_cursor_get_hw_state(struct intel_plane *plane,
> > @@ -10084,9 +10093,9 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  }
> >  
> >  static void i9xx_disable_cursor(struct intel_plane *plane,
> > -				struct intel_crtc *crtc)
> > +				const struct intel_crtc_state *crtc_state)
> >  {
> > -	i9xx_update_cursor(plane, NULL, NULL);
> > +	i9xx_update_cursor(plane, crtc_state, NULL);
> >  }
> >  
> >  static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
> > @@ -12840,7 +12849,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
> >  		intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state);
> >  
> >  		if (old_crtc_state->active) {
> > -			intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes);
> > +			intel_crtc_disable_planes(intel_state, intel_crtc);
> >  
> >  			/*
> >  			 * We need to disable pipe CRC before disabling the pipe,
> > @@ -13695,7 +13704,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
> >  					  to_intel_plane_state(plane->state));
> >  	} else {
> >  		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> > -		intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
> > +		intel_plane->disable_plane(intel_plane, crtc_state);
> >  	}
> >  
> >  	intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
> > diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
> > index 5d50decbcbb5..df9e6ebb27de 100644
> > --- a/drivers/gpu/drm/i915/intel_display.h
> > +++ b/drivers/gpu/drm/i915/intel_display.h
> > @@ -382,6 +382,14 @@ struct intel_link_m_n {
> >  	for_each_power_well_rev(__dev_priv, __power_well)		        \
> >  		for_each_if((__power_well)->desc->domains & (__domain_mask))
> >  
> > +#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
> > +	for ((__i) = 0; \
> > +	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> > +		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
> > +		      (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \
> > +	     (__i)++) \
> > +		for_each_if(plane)
> > +
> >  #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \
> >  	for ((__i) = 0; \
> >  	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 7a55f5921d34..facd5cb0b540 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1015,7 +1015,7 @@ struct intel_plane {
> >  			     const struct intel_crtc_state *crtc_state,
> >  			     const struct intel_plane_state *plane_state);
> >  	void (*disable_plane)(struct intel_plane *plane,
> > -			      struct intel_crtc *crtc);
> > +			      const struct intel_crtc_state *crtc_state);
> >  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
> >  	int (*check_plane)(struct intel_crtc_state *crtc_state,
> >  			   struct intel_plane_state *plane_state);
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 84c5f532fba5..2f97a298c24e 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -488,7 +488,8 @@ icl_update_slave(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +skl_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum plane_id plane_id = plane->id;
> > @@ -751,7 +752,8 @@ vlv_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +vlv_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> > @@ -918,7 +920,8 @@ ivb_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +ivb_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> > @@ -1084,7 +1087,8 @@ g4x_update_plane(struct intel_plane *plane,
> >  }
> >  
> >  static void
> > -g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
> > +g4x_disable_plane(struct intel_plane *plane,
> > +		  const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	enum pipe pipe = plane->pipe;
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

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

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

* Re: [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+
  2018-11-09  0:01   ` Matt Roper
@ 2018-11-09 14:34     ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-09 14:34 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Thu, Nov 08, 2018 at 04:01:18PM -0800, Matt Roper wrote:
> On Thu, Nov 01, 2018 at 05:06:02PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > If the level 0 latency is 0 we can't do anything. Return an error
> > rather than success.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Is it possible to get 0 latency here?  I thought we increased the
> latency to 2us if punit told us that level0=0 (WaWmMemoryReadLatency)?

Yeah, under normal circumstances this shouldn't happen. But you
can zero out the level 0 latency via debugfs. Should probably note
that in the commit message.

> 
> 
> Matt
> 
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 6fa1634e2db5..bd5f16bc7e08 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -4703,8 +4703,10 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> >  	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
> >  	uint32_t min_disp_buf_needed;
> >  
> > -	if (latency == 0 ||
> > -	    !intel_wm_plane_visible(cstate, intel_pstate)) {
> > +	if (latency == 0)
> > +		return level == 0 ? -EINVAL : 0;
> > +
> > +	if (!intel_wm_plane_visible(cstate, intel_pstate)) {
> >  		result->plane_en = false;
> >  		return 0;
> >  	}
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

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

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

* Re: [PATCH v2 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+
  2018-11-09  1:38     ` Matt Roper
@ 2018-11-09 14:53       ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-09 14:53 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Thu, Nov 08, 2018 at 05:38:37PM -0800, Matt Roper wrote:
> On Wed, Nov 07, 2018 at 08:44:30PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > On SKL+ the plane WM/BUF_CFG registers are a proper part of each
> > plane's register set. That means accessing them will cancel any
> > pending plane update, and we would need a PLANE_SURF register write
> > to arm the wm/ddb change as well.
> > 
> > To avoid all the problems with that let's just move the wm/ddb
> > programming into the plane update/disable hooks. Now all plane
> > registers get written in one (hopefully atomic) operation.
> > 
> > To make that feasible we'll move the plane ddb tracking into
> > the crtc state. Watermarks were already tracked there.
> > 
> > v2: Rebase due to input CSC
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_debugfs.c  |  21 +-
> >  drivers/gpu/drm/i915/i915_drv.h      |   3 -
> >  drivers/gpu/drm/i915/intel_display.c |  16 +-
> >  drivers/gpu/drm/i915/intel_display.h |  11 +-
> >  drivers/gpu/drm/i915/intel_drv.h     |   9 +
> >  drivers/gpu/drm/i915/intel_pm.c      | 450 ++++++++++++---------------
> >  drivers/gpu/drm/i915/intel_sprite.c  |   4 +
> >  7 files changed, 250 insertions(+), 264 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> > index f60485906f7e..3e80a04d2790 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -3437,31 +3437,32 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
> >  {
> >  	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> >  	struct drm_device *dev = &dev_priv->drm;
> > -	struct skl_ddb_allocation *ddb;
> >  	struct skl_ddb_entry *entry;
> > -	enum pipe pipe;
> > -	int plane;
> > +	struct intel_crtc *crtc;
> >  
> >  	if (INTEL_GEN(dev_priv) < 9)
> >  		return -ENODEV;
> >  
> >  	drm_modeset_lock_all(dev);
> >  
> > -	ddb = &dev_priv->wm.skl_hw.ddb;
> > -
> >  	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
> >  
> > -	for_each_pipe(dev_priv, pipe) {
> > +	for_each_intel_crtc(&dev_priv->drm, crtc) {
> > +		struct intel_crtc_state *crtc_state =
> > +			to_intel_crtc_state(crtc->base.state);
> > +		enum pipe pipe = crtc->pipe;
> > +		enum plane_id plane_id;
> > +
> >  		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
> >  
> > -		for_each_universal_plane(dev_priv, pipe, plane) {
> > -			entry = &ddb->plane[pipe][plane];
> > -			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
> > +		for_each_plane_id_on_crtc(crtc, plane_id) {
> > +			entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
> > +			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
> >  				   entry->start, entry->end,
> >  				   skl_ddb_entry_size(entry));
> >  		}
> >  
> > -		entry = &ddb->plane[pipe][PLANE_CURSOR];
> > +		entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
> >  		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 2a88a7eb871b..17023a869091 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1236,9 +1236,6 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
> >  }
> >  
> >  struct skl_ddb_allocation {
> > -	/* packed/y */
> > -	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> > -	struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
> >  	u8 enabled_slices; /* GEN11 has configurable 2 slices */
> >  };
> 
> Now that we're down to a single field here, there isn't really a need to
> wrap it in a struct.  Can we just eliminate the structure?

Probably. The enabled_slices thing is a bit busted anyway at the moment.
A few people have noticed that we try to reprogram the slice count even
all pipes are off which leads to a warning about a missing rpma reference.
Whoever fixes that should probably figure out where this thing should
live as well.

> 
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index ac3687a0245d..f497bb521baf 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10040,6 +10040,10 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  	 * except when the plane is getting enabled at which time
> >  	 * the CURCNTR write arms the update.
> >  	 */
> > +
> > +	if (INTEL_GEN(dev_priv) >= 9)
> > +		skl_write_cursor_wm(plane, crtc_state);
> > +
> >  	if (plane->cursor.base != base ||
> >  	    plane->cursor.size != fbc_ctl ||
> >  	    plane->cursor.cntl != cntl) {
> > @@ -11829,6 +11833,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
> >  	struct skl_pipe_wm hw_wm, *sw_wm;
> >  	struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
> >  	struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
> > +	struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES];
> > +	struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES];
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >  	const enum pipe pipe = intel_crtc->pipe;
> >  	int plane, level, max_level = ilk_wm_max_level(dev_priv);
> > @@ -11839,6 +11845,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
> >  	skl_pipe_wm_get_hw_state(crtc, &hw_wm);
> >  	sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal;
> >  
> > +	skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv);
> > +
> 
> I notice we've never been verifying the UV ddb entries; should we be
> (maybe in a separate patch)?

Seems like good idea. We're also using a >1KiB of stack here (32bit
builds are complaining about that). So probably need to rework this
code more extensively.

> 
> 
> >  	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
> >  	sw_ddb = &dev_priv->wm.skl_hw.ddb;
> >  
> > @@ -11881,8 +11889,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
> >  		}
> >  
> >  		/* DDB */
> > -		hw_ddb_entry = &hw_ddb.plane[pipe][plane];
> > -		sw_ddb_entry = &sw_ddb->plane[pipe][plane];
> > +		hw_ddb_entry = &hw_ddb_y[plane];
> > +		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane];
> >  
> >  		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
> >  			DRM_ERROR("mismatch in DDB state pipe %c plane %d (expected (%u,%u), found (%u,%u))\n",
> > @@ -11931,8 +11939,8 @@ static void verify_wm_state(struct drm_crtc *crtc,
> >  		}
> >  
> >  		/* DDB */
> > -		hw_ddb_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
> > -		sw_ddb_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
> > +		hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR];
> > +		sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR];
> >  
> >  		if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
> >  			DRM_ERROR("mismatch in DDB state pipe %c cursor (expected (%u,%u), found (%u,%u))\n",
> > diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
> > index df9e6ebb27de..078406dc65e5 100644
> > --- a/drivers/gpu/drm/i915/intel_display.h
> > +++ b/drivers/gpu/drm/i915/intel_display.h
> > @@ -319,7 +319,7 @@ struct intel_link_m_n {
> >  			    &(dev)->mode_config.plane_list,		\
> >  			    base.head)					\
> >  		for_each_if((plane_mask) &				\
> > -			    drm_plane_mask(&intel_plane->base)))
> > +			    drm_plane_mask(&intel_plane->base))
> >  
> 
> Looks like this is an independent fix for 40560e26dc45e ("drm/i915: Use
> drm_plane_mask() & co.").  Apparently we haven't actually been using
> that macro, but we don't start using it in this patch, so it should
> probably be fixed separately.

Oh. I think I was using it and then the build obviously failed. But
maybe I reworked something and stopped using it. I'll have another
look and split this out if it's not needed.

> 
> >  #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
> >  	list_for_each_entry(intel_plane,				\
> > @@ -415,6 +415,15 @@ struct intel_link_m_n {
> >  	     (__i)++) \
> >  		for_each_if(plane)
> >  
> > +#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
> > +	for ((__i) = 0; \
> > +	     (__i) < (__state)->base.dev->mode_config.num_crtc && \
> > +		     ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
> > +		      (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
> > +		      (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
> > +	     (__i)++) \
> > +		for_each_if(crtc)
> > +
> >  void intel_link_compute_m_n(int bpp, int nlanes,
> >  			    int pixel_clock, int link_clock,
> >  			    struct intel_link_m_n *m_n,
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index fae8c8f6d009..64ee84c6ee09 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -705,6 +705,8 @@ struct intel_crtc_wm_state {
> >  			/* gen9+ only needs 1-step wm programming */
> >  			struct skl_pipe_wm optimal;
> >  			struct skl_ddb_entry ddb;
> > +			struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
> > +			struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES];
> >  		} skl;
> >  
> >  		struct {
> > @@ -2183,6 +2185,9 @@ void g4x_wm_get_hw_state(struct drm_device *dev);
> >  void vlv_wm_get_hw_state(struct drm_device *dev);
> >  void ilk_wm_get_hw_state(struct drm_device *dev);
> >  void skl_wm_get_hw_state(struct drm_device *dev);
> > +void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
> > +			       struct skl_ddb_entry *ddb_y,
> > +			       struct skl_ddb_entry *ddb_uv);
> >  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> >  			  struct skl_ddb_allocation *ddb /* out */);
> >  void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
> > @@ -2197,6 +2202,10 @@ bool skl_wm_level_equals(const struct skl_wm_level *l1,
> >  bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
> >  				 const struct skl_ddb_entry entries[],
> >  				 int num_entries, int ignore_idx);
> > +void skl_write_plane_wm(struct intel_plane *plane,
> > +			const struct intel_crtc_state *crtc_state);
> > +void skl_write_cursor_wm(struct intel_plane *plane,
> > +			 const struct intel_crtc_state *crtc_state);
> >  bool ilk_disable_lp_wm(struct drm_device *dev);
> >  int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
> >  				  struct intel_crtc_state *cstate);
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 749e8d814ce5..40406cc0d40b 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3911,68 +3911,70 @@ static void
> >  skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
> >  			   const enum pipe pipe,
> >  			   const enum plane_id plane_id,
> > -			   struct skl_ddb_allocation *ddb /* out */)
> > +			   struct skl_ddb_entry *ddb_y,
> > +			   struct skl_ddb_entry *ddb_uv)
> >  {
> > -	u32 val, val2 = 0;
> > -	int fourcc, pixel_format;
> > +	u32 val, val2;
> > +	u32 fourcc = 0;
> >  
> >  	/* Cursor doesn't support NV12/planar, so no extra calculation needed */
> >  	if (plane_id == PLANE_CURSOR) {
> >  		val = I915_READ(CUR_BUF_CFG(pipe));
> > -		skl_ddb_entry_init_from_hw(dev_priv,
> > -					   &ddb->plane[pipe][plane_id], val);
> > +		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
> >  		return;
> >  	}
> >  
> >  	val = I915_READ(PLANE_CTL(pipe, plane_id));
> >  
> >  	/* No DDB allocated for disabled planes */
> 
> The code flow below no longer matches this comment...we now only skip
> fourcc lookup for disabled planes, but still read the buf registers and
> fill in the ddb entry structures.  Was this change intentional?

Yeah, since we now program them from .disable_plane() as well I wanted
to make sure we're always programming them consistently.

> I'd
> expect the registers to probably give us zero'd entries when we read
> them, but I'm not sure if that's actually true when reading in the
> initial BIOS state.

We should clean up whatever mess the BIOS left us. Doing the readout
unconditionally should make that happen as we'll note the inconsistency
between the calculated and current ddb allocation and force a plane
update where needed.

> 
> > -	if (!(val & PLANE_CTL_ENABLE))
> > -		return;
> > -
> > -	pixel_format = val & PLANE_CTL_FORMAT_MASK;
> > -	fourcc = skl_format_to_fourcc(pixel_format,
> > -				      val & PLANE_CTL_ORDER_RGBX,
> > -				      val & PLANE_CTL_ALPHA_MASK);
> > +	if (val & PLANE_CTL_ENABLE)
> > +		fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK,
> > +					      val & PLANE_CTL_ORDER_RGBX,
> > +					      val & PLANE_CTL_ALPHA_MASK);
> >  
> > -	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
> > -	if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) {
> > +	if (INTEL_GEN(dev_priv) >= 11) {
> > +		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
> > +		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
> > +	} else {
> > +		val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
> >  		val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
> >  
> > -		skl_ddb_entry_init_from_hw(dev_priv,
> > -					   &ddb->plane[pipe][plane_id], val2);
> > -		skl_ddb_entry_init_from_hw(dev_priv,
> > -					   &ddb->uv_plane[pipe][plane_id], val);
> > -	} else {
> > -		skl_ddb_entry_init_from_hw(dev_priv,
> > -					   &ddb->plane[pipe][plane_id], val);
> > +		if (fourcc == DRM_FORMAT_NV12)
> > +			swap(val, val2);
> > +
> > +		skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
> > +		skl_ddb_entry_init_from_hw(dev_priv, ddb_uv, val2);
> >  	}
> >  }
> >  
> > -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> > -			  struct skl_ddb_allocation *ddb /* out */)
> > +void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
> > +			       struct skl_ddb_entry *ddb_y,
> > +			       struct skl_ddb_entry *ddb_uv)
> >  {
> > -	struct intel_crtc *crtc;
> > -
> > -	memset(ddb, 0, sizeof(*ddb));
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	enum intel_display_power_domain power_domain;
> > +	enum pipe pipe = crtc->pipe;
> > +	enum plane_id plane_id;
> >  
> > -	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
> > +	power_domain = POWER_DOMAIN_PIPE(pipe);
> > +	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> > +		return;
> >  
> > -	for_each_intel_crtc(&dev_priv->drm, crtc) {
> > -		enum intel_display_power_domain power_domain;
> > -		enum plane_id plane_id;
> > -		enum pipe pipe = crtc->pipe;
> > +	for_each_plane_id_on_crtc(crtc, plane_id)
> > +		skl_ddb_get_hw_plane_state(dev_priv, pipe,
> > +					   plane_id,
> > +					   &ddb_y[plane_id],
> > +					   &ddb_uv[plane_id]);
> >  
> > -		power_domain = POWER_DOMAIN_PIPE(pipe);
> > -		if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> > -			continue;
> > +	intel_display_power_put(dev_priv, power_domain);
> > +}
> >  
> > -		for_each_plane_id_on_crtc(crtc, plane_id)
> > -			skl_ddb_get_hw_plane_state(dev_priv, pipe,
> > -						   plane_id, ddb);
> > +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> > +			  struct skl_ddb_allocation *ddb /* out */)
> > +{
> > +	memset(ddb, 0, sizeof(*ddb));
> 
> The only thing left in the structure is 'enabled_slices' which we set
> directly below, so I think this memset is unnecessary.  Although as
> noted above, it would be better to just eliminate the structure itself.
> 
> >  
> > -		intel_display_power_put(dev_priv, power_domain);
> > -	}
> > +	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
> >  }
> >  
> >  /*
> > @@ -4370,7 +4372,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  	struct drm_crtc *crtc = cstate->base.crtc;
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -	enum pipe pipe = intel_crtc->pipe;
> >  	struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
> >  	uint16_t alloc_size, start;
> >  	uint16_t minimum[I915_MAX_PLANES] = {};
> > @@ -4383,8 +4384,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  	uint16_t total_min_blocks = 0;
> >  
> >  	/* Clear the partitioning for disabled planes. */
> > -	memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
> > -	memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
> > +	memset(cstate->wm.skl.plane_ddb_y, 0, sizeof(cstate->wm.skl.plane_ddb_y));
> > +	memset(cstate->wm.skl.plane_ddb_uv, 0, sizeof(cstate->wm.skl.plane_ddb_uv));
> >  
> >  	if (WARN_ON(!state))
> >  		return 0;
> > @@ -4431,8 +4432,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  	}
> >  
> >  	alloc_size -= total_min_blocks;
> > -	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
> > -	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
> > +	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
> > +	cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end;
> >  
> >  	/*
> >  	 * 2. Distribute the remaining space in proportion to the amount of
> > @@ -4463,8 +4464,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  
> >  		/* Leave disabled planes at (0,0) */
> >  		if (data_rate) {
> > -			ddb->plane[pipe][plane_id].start = start;
> > -			ddb->plane[pipe][plane_id].end = start + plane_blocks;
> > +			cstate->wm.skl.plane_ddb_y[plane_id].start = start;
> > +			cstate->wm.skl.plane_ddb_y[plane_id].end = start + plane_blocks;
> >  		}
> >  
> >  		start += plane_blocks;
> > @@ -4479,8 +4480,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  		WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks);
> >  
> >  		if (uv_data_rate) {
> > -			ddb->uv_plane[pipe][plane_id].start = start;
> > -			ddb->uv_plane[pipe][plane_id].end =
> > +			cstate->wm.skl.plane_ddb_uv[plane_id].start = start;
> > +			cstate->wm.skl.plane_ddb_uv[plane_id].end =
> >  				start + uv_plane_blocks;
> >  		}
> >  
> > @@ -4590,9 +4591,6 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
> >  		to_intel_atomic_state(cstate->base.state);
> >  	bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
> >  
> > -	if (!intel_wm_plane_visible(cstate, intel_pstate))
> > -		return 0;
> > -
> 
> It's not clear to me why we remove this?  Can't we still get here for
> disabled planes (where fb is NULL)?  

I moved these checks higher up (skl_build_plane_wm() and
icl_build_plane_wm()).

> 
> >  	/* only NV12 format has two planes */
> >  	if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) {
> >  		DRM_DEBUG_KMS("Non NV12 format have single plane\n");
> > @@ -4706,9 +4704,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> >  	if (latency == 0)
> >  		return level == 0 ? -EINVAL : 0;
> >  
> > -	if (!intel_wm_plane_visible(cstate, intel_pstate))
> > -		return 0;
> > -
> 
> Unlike above, I think we always have a valid fb here.  But I don't see
> how this relates to what the rest of the patch is trying to do?  In fact
> from this point on, I'm getting a bit lost in a lot of codeflow changes
> on the 'check' part of the transaction that don't seem like it's
> directly related to state goal of writing watermarks as part of the main
> plane register update (which should be mostly on the 'commit' side) or
> moving ddb into cstate.  

I think the code ended up super messy with trying to minimize
the changes related to using the crtc state. But a lot of that
could have just been due to the code being messy in the first
place. You are totally right that the patch did end looking
like crap :(

> 
> It feels like we're also tackling a lot of nv12 watermark behavior
> changes with this patch; is it possible to separate that out into a
> separate patch?

Yeah. I'll try to split into smaller pieces.

> 
> 
> Matt
> 
> >  	/* Display WA #1141: kbl,cfl */
> >  	if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
> >  	    IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) &&
> > @@ -4831,21 +4826,16 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> >  
> >  static int
> >  skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
> > -		      struct skl_ddb_allocation *ddb,
> >  		      const struct intel_crtc_state *cstate,
> >  		      const struct intel_plane_state *intel_pstate,
> >  		      uint16_t ddb_blocks,
> >  		      const struct skl_wm_params *wm_params,
> > -		      struct skl_plane_wm *wm,
> >  		      struct skl_wm_level *levels)
> >  {
> >  	int level, max_level = ilk_wm_max_level(dev_priv);
> >  	struct skl_wm_level *result_prev = &levels[0];
> >  	int ret;
> >  
> > -	if (WARN_ON(!intel_pstate->base.fb))
> > -		return -EINVAL;
> > -
> >  	for (level = 0; level <= max_level; level++) {
> >  		struct skl_wm_level *result = &levels[level];
> >  
> > @@ -4863,9 +4853,6 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
> >  		result_prev = result;
> >  	}
> >  
> > -	if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
> > -		wm->is_planar = true;
> > -
> >  	return 0;
> >  }
> >  
> > @@ -4893,10 +4880,9 @@ skl_compute_linetime_wm(const struct intel_crtc_state *cstate)
> >  }
> >  
> >  static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> > -				      struct skl_wm_params *wp,
> > -				      struct skl_wm_level *wm_l0,
> > -				      uint16_t ddb_allocation,
> > -				      struct skl_wm_level *trans_wm /* out */)
> > +				      const struct skl_wm_params *wp,
> > +				      struct skl_plane_wm *wm,
> > +				      uint16_t ddb_allocation)
> >  {
> >  	struct drm_device *dev = cstate->base.crtc->dev;
> >  	const struct drm_i915_private *dev_priv = to_i915(dev);
> > @@ -4904,9 +4890,6 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> >  	const uint16_t trans_amount = 10; /* This is configurable amount */
> >  	uint16_t wm0_sel_res_b, trans_offset_b, res_blocks;
> >  
> > -	if (!cstate->base.active)
> > -		return;
> > -
> >  	/* Transition WM are not recommended by HW team for GEN9 */
> >  	if (INTEL_GEN(dev_priv) <= 9)
> >  		return;
> > @@ -4931,7 +4914,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> >  	 * Result Blocks is Result Blocks minus 1 and it should work for the
> >  	 * current platforms.
> >  	 */
> > -	wm0_sel_res_b = wm_l0->plane_res_b - 1;
> > +	wm0_sel_res_b = wm->wm[0].plane_res_b - 1;
> >  
> >  	if (wp->y_tiled) {
> >  		trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2,
> > @@ -4950,23 +4933,19 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
> >  	res_blocks += 1;
> >  
> >  	if (res_blocks < ddb_allocation) {
> > -		trans_wm->plane_res_b = res_blocks;
> > -		trans_wm->plane_en = true;
> > +		wm->trans_wm.plane_res_b = res_blocks;
> > +		wm->trans_wm.plane_en = true;
> >  	}
> >  }
> >  
> > -static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> > -				       struct skl_pipe_wm *pipe_wm,
> > -				       enum plane_id plane_id,
> > -				       const struct intel_crtc_state *cstate,
> > -				       const struct intel_plane_state *pstate,
> > -				       int color_plane)
> > +static int skl_build_plane_wm_single(struct intel_crtc_state *cstate,
> > +				     const struct intel_plane_state *pstate,
> > +				     enum plane_id plane_id, int color_plane)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
> > -	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
> > -	enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe;
> > +	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
> > +	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_y[plane_id]);
> >  	struct skl_wm_params wm_params;
> > -	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
> >  	int ret;
> >  
> >  	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
> > @@ -4974,79 +4953,105 @@ static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> >  	if (ret)
> >  		return ret;
> >  
> > -	ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
> > -				    ddb_blocks, &wm_params, wm, wm->wm);
> > -
> > +	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
> > +				    ddb_blocks, &wm_params, wm->wm);
> >  	if (ret)
> >  		return ret;
> >  
> > -	skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
> > -				  ddb_blocks, &wm->trans_wm);
> > +	skl_compute_transition_wm(cstate, &wm_params, wm, ddb_blocks);
> >  
> >  	return 0;
> >  }
> >  
> > -static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> > -				     struct skl_pipe_wm *pipe_wm,
> > -				     const struct intel_crtc_state *cstate,
> > -				     const struct intel_plane_state *pstate)
> > +static int skl_build_plane_wm_uv(struct intel_crtc_state *cstate,
> > +				 const struct intel_plane_state *pstate,
> > +				 enum plane_id plane_id)
> >  {
> > -	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
> > +	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
> > +	struct skl_plane_wm *wm = &cstate->wm.skl.optimal.planes[plane_id];
> > +	u16 ddb_blocks = skl_ddb_entry_size(&cstate->wm.skl.plane_ddb_uv[plane_id]);
> > +	struct skl_wm_params wm_params;
> > +	int ret;
> > +
> > +	wm->is_planar = true;
> >  
> > -	return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
> > +	/* uv plane watermarks must also be validated for NV12/Planar */
> > +	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
> > +					  &wm_params, 1);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = skl_compute_wm_levels(dev_priv, cstate, pstate,
> > +				    ddb_blocks, &wm_params, wm->uv_wm);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> >  }
> >  
> > -static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
> > -				     struct skl_pipe_wm *pipe_wm,
> > -				     const struct intel_crtc_state *cstate,
> > -				     const struct intel_plane_state *pstate)
> > +static int skl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
> > +			      struct intel_crtc_state *cstate,
> > +			      const struct intel_plane_state *pstate)
> >  {
> >  	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
> > -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > +	const struct drm_framebuffer *fb = pstate->base.fb;
> >  	enum plane_id plane_id = plane->id;
> > -	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
> > -	struct skl_wm_params wm_params;
> > -	enum pipe pipe = plane->pipe;
> > -	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
> >  	int ret;
> >  
> > -	ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
> > -	if (ret)
> > -		return ret;
> > -
> > -	/* uv plane watermarks must also be validated for NV12/Planar */
> > -	ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]);
> > +	if (!intel_wm_plane_visible(cstate, pstate))
> > +		return 0;
> >  
> > -	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1);
> > +	ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
> >  	if (ret)
> >  		return ret;
> >  
> > -	return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
> > -				     ddb_blocks, &wm_params, wm, wm->uv_wm);
> > +	if (fb->format->is_yuv && fb->format->num_planes > 1) {
> > +		ret = skl_build_plane_wm_uv(cstate, pstate, plane_id);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return 0;
> >  }
> >  
> > -static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
> > -				     struct skl_pipe_wm *pipe_wm,
> > -				     const struct intel_crtc_state *cstate,
> > -				     const struct intel_plane_state *pstate)
> > +static int icl_build_plane_wm(struct skl_pipe_wm *pipe_wm,
> > +			      struct intel_crtc_state *cstate,
> > +			      const struct intel_plane_state *pstate)
> >  {
> > +	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
> >  	int ret;
> > -	enum plane_id y_plane_id = pstate->linked_plane->id;
> > -	enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id;
> >  
> > -	ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id,
> > -					  cstate, pstate, 0);
> > -	if (ret)
> > -		return ret;
> > +	/* Watermarks calculated in master */
> > +	if (pstate->slave)
> > +		return 0;
> > +
> > +	if (pstate->linked_plane) {
> > +		const struct drm_framebuffer *fb = pstate->base.fb;
> > +		enum plane_id y_plane_id = pstate->linked_plane->id;
> > +
> > +		WARN_ON(!fb->format->is_yuv ||
> > +			fb->format->num_planes == 1);
> > +
> > +		ret = skl_build_plane_wm_single(cstate, pstate, y_plane_id, 0);
> > +		if (ret)
> > +			return ret;
> >  
> > -	return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id,
> > -					   cstate, pstate, 1);
> > +		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 1);
> > +		if (ret)
> > +			return ret;
> > +	} else if (intel_wm_plane_visible(cstate, pstate)) {
> > +		ret = skl_build_plane_wm_single(cstate, pstate, plane_id, 0);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return 0;
> >  }
> >  
> >  static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
> > -			     struct skl_ddb_allocation *ddb,
> >  			     struct skl_pipe_wm *pipe_wm)
> >  {
> > +	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
> >  	struct drm_crtc_state *crtc_state = &cstate->base;
> >  	struct drm_plane *plane;
> >  	const struct drm_plane_state *pstate;
> > @@ -5062,18 +5067,10 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
> >  		const struct intel_plane_state *intel_pstate =
> >  						to_intel_plane_state(pstate);
> >  
> > -		/* Watermarks calculated in master */
> > -		if (intel_pstate->slave)
> > -			continue;
> > -
> > -		if (intel_pstate->linked_plane)
> > -			ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
> > -		else if (intel_pstate->base.fb &&
> > -			 intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
> > -			ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
> > +		if (INTEL_GEN(dev_priv) >= 11)
> > +			ret = icl_build_plane_wm(pipe_wm, cstate, intel_pstate);
> >  		else
> > -			ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate);
> > -
> > +			ret = skl_build_plane_wm(pipe_wm, cstate, intel_pstate);
> >  		if (ret)
> >  			return ret;
> >  	}
> > @@ -5088,9 +5085,9 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
> >  				const struct skl_ddb_entry *entry)
> >  {
> >  	if (entry->end)
> > -		I915_WRITE(reg, (entry->end - 1) << 16 | entry->start);
> > +		I915_WRITE_FW(reg, (entry->end - 1) << 16 | entry->start);
> >  	else
> > -		I915_WRITE(reg, 0);
> > +		I915_WRITE_FW(reg, 0);
> >  }
> >  
> >  static void skl_write_wm_level(struct drm_i915_private *dev_priv,
> > @@ -5105,19 +5102,22 @@ static void skl_write_wm_level(struct drm_i915_private *dev_priv,
> >  		val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
> >  	}
> >  
> > -	I915_WRITE(reg, val);
> > +	I915_WRITE_FW(reg, val);
> >  }
> >  
> > -static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> > -			       const struct skl_plane_wm *wm,
> > -			       const struct skl_ddb_allocation *ddb,
> > -			       enum plane_id plane_id)
> > +void skl_write_plane_wm(struct intel_plane *plane,
> > +			const struct intel_crtc_state *crtc_state)
> >  {
> > -	struct drm_crtc *crtc = &intel_crtc->base;
> > -	struct drm_device *dev = crtc->dev;
> > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	int level, max_level = ilk_wm_max_level(dev_priv);
> > -	enum pipe pipe = intel_crtc->pipe;
> > +	enum plane_id plane_id = plane->id;
> > +	enum pipe pipe = plane->pipe;
> > +	const struct skl_plane_wm *wm =
> > +		&crtc_state->wm.skl.optimal.planes[plane_id];
> > +	const struct skl_ddb_entry *ddb_y =
> > +		&crtc_state->wm.skl.plane_ddb_y[plane_id];
> > +	const struct skl_ddb_entry *ddb_uv =
> > +		&crtc_state->wm.skl.plane_ddb_uv[plane_id];
> >  
> >  	for (level = 0; level <= max_level; level++) {
> >  		skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level),
> > @@ -5126,29 +5126,32 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> >  	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
> >  			   &wm->trans_wm);
> >  
> > -	if (wm->is_planar && INTEL_GEN(dev_priv) < 11) {
> > -		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
> > -				    &ddb->uv_plane[pipe][plane_id]);
> > +	if (INTEL_GEN(dev_priv) >= 11) {
> >  		skl_ddb_entry_write(dev_priv,
> > -				    PLANE_NV12_BUF_CFG(pipe, plane_id),
> > -				    &ddb->plane[pipe][plane_id]);
> > -	} else {
> > -		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
> > -				    &ddb->plane[pipe][plane_id]);
> > -		if (INTEL_GEN(dev_priv) < 11)
> > -			I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
> > +				    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
> > +		return;
> >  	}
> > +
> > +	if (wm->is_planar)
> > +		swap(ddb_y, ddb_uv);
> > +
> > +	skl_ddb_entry_write(dev_priv,
> > +			    PLANE_BUF_CFG(pipe, plane_id), ddb_y);
> > +	skl_ddb_entry_write(dev_priv,
> > +			    PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv);
> >  }
> >  
> > -static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> > -				const struct skl_plane_wm *wm,
> > -				const struct skl_ddb_allocation *ddb)
> > +void skl_write_cursor_wm(struct intel_plane *plane,
> > +			 const struct intel_crtc_state *crtc_state)
> >  {
> > -	struct drm_crtc *crtc = &intel_crtc->base;
> > -	struct drm_device *dev = crtc->dev;
> > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> >  	int level, max_level = ilk_wm_max_level(dev_priv);
> > -	enum pipe pipe = intel_crtc->pipe;
> > +	enum plane_id plane_id = plane->id;
> > +	enum pipe pipe = plane->pipe;
> > +	const struct skl_plane_wm *wm =
> > +		&crtc_state->wm.skl.optimal.planes[plane_id];
> > +	const struct skl_ddb_entry *ddb =
> > +		&crtc_state->wm.skl.plane_ddb_y[plane_id];
> >  
> >  	for (level = 0; level <= max_level; level++) {
> >  		skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
> > @@ -5156,8 +5159,7 @@ static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> >  	}
> >  	skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm);
> >  
> > -	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
> > -			    &ddb->plane[pipe][PLANE_CURSOR]);
> > +	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb);
> >  }
> >  
> >  bool skl_wm_level_equals(const struct skl_wm_level *l1,
> > @@ -5198,13 +5200,12 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
> >  static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
> >  			      const struct skl_pipe_wm *old_pipe_wm,
> >  			      struct skl_pipe_wm *pipe_wm, /* out */
> > -			      struct skl_ddb_allocation *ddb, /* out */
> >  			      bool *changed /* out */)
> >  {
> >  	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
> >  	int ret;
> >  
> > -	ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
> > +	ret = skl_build_pipe_wm(intel_cstate, pipe_wm);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -5230,42 +5231,29 @@ pipes_modified(struct drm_atomic_state *state)
> >  }
> >  
> >  static int
> > -skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
> > +skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
> > +			    struct intel_crtc_state *new_crtc_state)
> >  {
> > -	struct drm_atomic_state *state = cstate->base.state;
> > -	struct drm_device *dev = state->dev;
> > -	struct drm_crtc *crtc = cstate->base.crtc;
> > -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > -	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> > -	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
> > -	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> > -	struct drm_plane *plane;
> > -	enum pipe pipe = intel_crtc->pipe;
> > +	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
> > +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct intel_plane *plane;
> >  
> > -	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
> > -		struct drm_plane_state *plane_state;
> > -		struct intel_plane *linked;
> > -		enum plane_id plane_id = to_intel_plane(plane)->id;
> > +	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> > +		struct intel_plane_state *plane_state;
> > +		enum plane_id plane_id = plane->id;
> >  
> > -		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
> > -					&new_ddb->plane[pipe][plane_id]) &&
> > -		    skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
> > -					&new_ddb->uv_plane[pipe][plane_id]))
> > +		if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
> > +					&new_crtc_state->wm.skl.plane_ddb_y[plane_id]) &&
> > +		    skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id],
> > +					&new_crtc_state->wm.skl.plane_ddb_uv[plane_id]))
> >  			continue;
> >  
> > -		plane_state = drm_atomic_get_plane_state(state, plane);
> > +		plane_state = intel_atomic_get_plane_state(state, plane);
> >  		if (IS_ERR(plane_state))
> >  			return PTR_ERR(plane_state);
> >  
> > -		/* Make sure linked plane is updated too */
> > -		linked = to_intel_plane_state(plane_state)->linked_plane;
> > -		if (!linked)
> > -			continue;
> > -
> > -		plane_state = drm_atomic_get_plane_state(state, &linked->base);
> > -		if (IS_ERR(plane_state))
> > -			return PTR_ERR(plane_state);
> > +		new_crtc_state->update_planes |= BIT(plane_id);
> >  	}
> >  
> >  	return 0;
> > @@ -5277,18 +5265,21 @@ skl_compute_ddb(struct drm_atomic_state *state)
> >  	const struct drm_i915_private *dev_priv = to_i915(state->dev);
> >  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> >  	struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
> > +	struct intel_crtc_state *old_crtc_state;
> > +	struct intel_crtc_state *new_crtc_state;
> >  	struct intel_crtc *crtc;
> > -	struct intel_crtc_state *cstate;
> >  	int ret, i;
> >  
> >  	memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
> >  
> > -	for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) {
> > -		ret = skl_allocate_pipe_ddb(cstate, ddb);
> > +	for_each_oldnew_intel_crtc_in_state(intel_state, crtc, old_crtc_state,
> > +					    new_crtc_state, i) {
> > +		ret = skl_allocate_pipe_ddb(new_crtc_state, ddb);
> >  		if (ret)
> >  			return ret;
> >  
> > -		ret = skl_ddb_add_affected_planes(cstate);
> > +		ret = skl_ddb_add_affected_planes(old_crtc_state,
> > +						  new_crtc_state);
> >  		if (ret)
> >  			return ret;
> >  	}
> > @@ -5297,36 +5288,29 @@ skl_compute_ddb(struct drm_atomic_state *state)
> >  }
> >  
> >  static void
> > -skl_print_wm_changes(const struct drm_atomic_state *state)
> > +skl_print_wm_changes(struct intel_atomic_state *state)
> >  {
> > -	const struct drm_device *dev = state->dev;
> > -	const struct drm_i915_private *dev_priv = to_i915(dev);
> > -	const struct intel_atomic_state *intel_state =
> > -		to_intel_atomic_state(state);
> > -	const struct drm_crtc *crtc;
> > -	const struct drm_crtc_state *cstate;
> > -	const struct intel_plane *intel_plane;
> > -	const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb;
> > -	const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
> > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > +	const struct intel_crtc_state *old_crtc_state;
> > +	const struct intel_crtc_state *new_crtc_state;
> > +	struct intel_plane *plane;
> > +	struct intel_crtc *crtc;
> >  	int i;
> >  
> > -	for_each_new_crtc_in_state(state, crtc, cstate, i) {
> > -		const struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -		enum pipe pipe = intel_crtc->pipe;
> > -
> > -		for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> > -			enum plane_id plane_id = intel_plane->id;
> > +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> > +					    new_crtc_state, i) {
> > +		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> > +			enum plane_id plane_id = plane->id;
> >  			const struct skl_ddb_entry *old, *new;
> >  
> > -			old = &old_ddb->plane[pipe][plane_id];
> > -			new = &new_ddb->plane[pipe][plane_id];
> > +			old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id];
> > +			new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id];
> >  
> >  			if (skl_ddb_entry_equal(old, new))
> >  				continue;
> >  
> >  			DRM_DEBUG_KMS("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n",
> > -				      intel_plane->base.base.id,
> > -				      intel_plane->base.name,
> > +				      plane->base.base.id, plane->base.name,
> >  				      old->start, old->end,
> >  				      new->start, new->end);
> >  		}
> > @@ -5462,8 +5446,7 @@ skl_compute_wm(struct drm_atomic_state *state)
> >  			&to_intel_crtc_state(crtc->state)->wm.skl.optimal;
> >  
> >  		pipe_wm = &intel_cstate->wm.skl.optimal;
> > -		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm,
> > -					 &results->ddb, &changed);
> > +		ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, &changed);
> >  		if (ret)
> >  			return ret;
> >  
> > @@ -5477,7 +5460,7 @@ skl_compute_wm(struct drm_atomic_state *state)
> >  		intel_cstate->update_wm_pre = true;
> >  	}
> >  
> > -	skl_print_wm_changes(state);
> > +	skl_print_wm_changes(intel_state);
> >  
> >  	return 0;
> >  }
> > @@ -5488,23 +5471,12 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
> >  	struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
> >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> >  	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
> > -	const struct skl_ddb_allocation *ddb = &state->wm_results.ddb;
> >  	enum pipe pipe = crtc->pipe;
> > -	enum plane_id plane_id;
> >  
> >  	if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base)))
> >  		return;
> >  
> >  	I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime);
> > -
> > -	for_each_plane_id_on_crtc(crtc, plane_id) {
> > -		if (plane_id != PLANE_CURSOR)
> > -			skl_write_plane_wm(crtc, &pipe_wm->planes[plane_id],
> > -					   ddb, plane_id);
> > -		else
> > -			skl_write_cursor_wm(crtc, &pipe_wm->planes[plane_id],
> > -					    ddb);
> > -	}
> >  }
> >  
> >  static void skl_initial_wm(struct intel_atomic_state *state,
> > @@ -5514,8 +5486,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
> >  	struct drm_device *dev = intel_crtc->base.dev;
> >  	struct drm_i915_private *dev_priv = to_i915(dev);
> >  	struct skl_ddb_values *results = &state->wm_results;
> > -	struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw;
> > -	enum pipe pipe = intel_crtc->pipe;
> >  
> >  	if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0)
> >  		return;
> > @@ -5525,11 +5495,6 @@ static void skl_initial_wm(struct intel_atomic_state *state,
> >  	if (cstate->base.active_changed)
> >  		skl_atomic_update_crtc_wm(state, cstate);
> >  
> > -	memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe],
> > -	       sizeof(hw_vals->ddb.uv_plane[pipe]));
> > -	memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe],
> > -	       sizeof(hw_vals->ddb.plane[pipe]));
> > -
> >  	mutex_unlock(&dev_priv->wm.wm_mutex);
> >  }
> >  
> > @@ -5680,13 +5645,6 @@ void skl_wm_get_hw_state(struct drm_device *dev)
> >  	if (dev_priv->active_crtcs) {
> >  		/* Fully recompute DDB on first atomic commit */
> >  		dev_priv->wm.distrust_bios_wm = true;
> > -	} else {
> > -		/*
> > -		 * Easy/common case; just sanitize DDB now if everything off
> > -		 * Keep dbuf slice info intact
> > -		 */
> > -		memset(ddb->plane, 0, sizeof(ddb->plane));
> > -		memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane));
> >  	}
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 99d4396cac00..126a51a7b376 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -535,6 +535,8 @@ skl_program_plane(struct intel_plane *plane,
> >  	if (fb->format->is_yuv && icl_is_hdr_plane(plane))
> >  		icl_program_input_csc_coeff(crtc_state, plane_state);
> >  
> > +	skl_write_plane_wm(plane, crtc_state);
> > +
> >  	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
> >  	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
> >  	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
> > @@ -597,6 +599,8 @@ skl_disable_plane(struct intel_plane *plane,
> >  
> >  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> >  
> > +	skl_write_plane_wm(plane, crtc_state);
> > +
> >  	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
> >  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
> >  
> > -- 
> > 2.18.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

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

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

* Re: [PATCH v2 02/14] drm/i915: Clean up skl_program_scaler()
  2018-11-07 18:29       ` Ville Syrjälä
@ 2018-11-09 17:24         ` Ville Syrjälä
  0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2018-11-09 17:24 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Nov 07, 2018 at 08:29:53PM +0200, Ville Syrjälä wrote:
> On Thu, Nov 01, 2018 at 11:13:50AM -0700, Rodrigo Vivi wrote:
> > On Thu, Nov 01, 2018 at 05:17:36PM +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Remove the "sizes are 0 based" stuff that is not even true for the
> > > scaler.
> > > 
> > > v2: Rebase
> > > 
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> Thanks. First two patches pushed.

And now also 3-5 and 8. The rest had some amount of discussion still
happening, so I'll refrain from pushing more until I address Matt's
comments and repost the remaining patches.

Thanks for the reviews so far.

> 
> > 
> > > ---
> > >  drivers/gpu/drm/i915/intel_sprite.c | 18 +++++-------------
> > >  1 file changed, 5 insertions(+), 13 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > > index 30b7485f1992..a77a17fda692 100644
> > > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > > @@ -310,12 +310,11 @@ skl_plane_max_stride(struct intel_plane *plane,
> > >  }
> > >  
> > >  static void
> > > -skl_program_scaler(struct drm_i915_private *dev_priv,
> > > -		   struct intel_plane *plane,
> > > +skl_program_scaler(struct intel_plane *plane,
> > >  		   const struct intel_crtc_state *crtc_state,
> > >  		   const struct intel_plane_state *plane_state)
> > >  {
> > > -	enum plane_id plane_id = plane->id;
> > > +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > >  	enum pipe pipe = plane->pipe;
> > >  	int scaler_id = plane_state->scaler_id;
> > >  	const struct intel_scaler *scaler =
> > > @@ -327,10 +326,6 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
> > >  	u16 y_hphase, uv_rgb_hphase;
> > >  	u16 y_vphase, uv_rgb_vphase;
> > >  
> > > -	/* Sizes are 0 based */
> > > -	crtc_w--;
> > > -	crtc_h--;
> > > -
> > >  	/* TODO: handle sub-pixel coordinates */
> > >  	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
> > >  	    !icl_is_hdr_plane(plane)) {
> > > @@ -350,15 +345,14 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
> > >  	}
> > >  
> > >  	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
> > > -		      PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
> > > +		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
> > >  	I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> > >  	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
> > >  		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
> > >  	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
> > >  		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
> > >  	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
> > > -	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
> > > -		      ((crtc_w + 1) << 16)|(crtc_h + 1));
> > > +	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
> > >  }
> > >  
> > >  static void
> > > @@ -441,11 +435,9 @@ skl_program_plane(struct intel_plane *plane,
> > >  		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
> > >  	}
> > >  
> > > -	/* program plane scaler */
> > >  	if (plane_state->scaler_id >= 0) {
> > >  		if (!slave)
> > > -			skl_program_scaler(dev_priv, plane,
> > > -					   crtc_state, plane_state);
> > > +			skl_program_scaler(plane, crtc_state, plane_state);
> > >  
> > >  		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
> > >  	} else {
> > > -- 
> > > 2.18.1
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

end of thread, other threads:[~2018-11-09 17:24 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-01 15:05 [PATCH 00/14] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
2018-11-01 15:05 ` [PATCH 01/14] drm/i915: Nuke posting reads from plane update/disable funcs Ville Syrjala
2018-11-01 18:08   ` Rodrigo Vivi
2018-11-01 15:05 ` [PATCH 02/14] drm/i915: Clean up skl_program_scaler() Ville Syrjala
2018-11-01 15:17   ` [PATCH v2 " Ville Syrjala
2018-11-01 18:13     ` Rodrigo Vivi
2018-11-07 18:29       ` Ville Syrjälä
2018-11-09 17:24         ` Ville Syrjälä
2018-11-01 15:05 ` [PATCH 03/14] drm/i915: Remove the PS_PWR_GATE write from skl_program_scaler() Ville Syrjala
2018-11-07 18:53   ` Rodrigo Vivi
2018-11-01 15:05 ` [PATCH 04/14] drm/i915: Polish the skl+ plane keyval/msk/max register setup Ville Syrjala
2018-11-07 18:41   ` [PATCH v2 " Ville Syrjala
2018-11-07 19:55   ` [PATCH " Rodrigo Vivi
2018-11-07 20:56     ` Ville Syrjälä
2018-11-01 15:05 ` [PATCH 05/14] drm/i915: Clean up skl+ PLANE_POS vs. scaler handling Ville Syrjala
2018-11-07 19:56   ` Rodrigo Vivi
2018-11-01 15:05 ` [PATCH 06/14] drm/i915: Reorganize plane register writes to make them more atomic Ville Syrjala
2018-11-07 18:42   ` [PATCH v2 " Ville Syrjala
2018-11-08 19:30     ` Matt Roper
2018-11-08 19:48       ` Ville Syrjälä
2018-11-07 21:26   ` [PATCH " Rodrigo Vivi
2018-11-07 21:38     ` Ville Syrjälä
2018-11-01 15:05 ` [PATCH 07/14] drm/i915: Move single buffered plane register writes to the end Ville Syrjala
2018-11-07 21:26   ` Rodrigo Vivi
2018-11-08 22:06   ` Matt Roper
2018-11-09 13:55     ` Ville Syrjälä
2018-11-01 15:05 ` [PATCH 08/14] drm/i915: Generalize skl_ddb_allocation_overlaps() Ville Syrjala
2018-11-07 21:28   ` Rodrigo Vivi
2018-11-01 15:06 ` [PATCH 09/14] drm/i915: Introduce crtc_state->update_planes bitmask Ville Syrjala
2018-11-07 21:49   ` Rodrigo Vivi
2018-11-08 11:32     ` Ville Syrjälä
2018-11-08 23:22   ` Matt Roper
2018-11-09 13:57     ` Ville Syrjälä
2018-11-01 15:06 ` [PATCH 10/14] drm/i915: Pass the new crtc_state to ->disable_plane() Ville Syrjala
2018-11-07 22:08   ` Rodrigo Vivi
2018-11-08 11:43     ` Ville Syrjälä
2018-11-08 23:52   ` Matt Roper
2018-11-09 14:32     ` Ville Syrjälä
2018-11-01 15:06 ` [PATCH 11/14] drm/i915: Fix latency==0 handling for level 0 watermark on skl+ Ville Syrjala
2018-11-07 22:09   ` Rodrigo Vivi
2018-11-09  0:01   ` Matt Roper
2018-11-09 14:34     ` Ville Syrjälä
2018-11-01 15:06 ` [PATCH 12/14] drm/i915: Remove some useless zeroing on skl+ wm calculations Ville Syrjala
2018-11-07 18:43   ` [PATCH v2 " Ville Syrjala
2018-11-07 22:11   ` [PATCH " Rodrigo Vivi
2018-11-08 11:46     ` Ville Syrjälä
2018-11-01 15:06 ` [PATCH 13/14] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+ Ville Syrjala
2018-11-07 18:44   ` [PATCH v2 " Ville Syrjala
2018-11-09  1:38     ` Matt Roper
2018-11-09 14:53       ` Ville Syrjälä
2018-11-01 15:06 ` [PATCH 14/14] drm/i915: Commit skl+ planes in an order that avoids ddb overlaps Ville Syrjala
2018-11-01 15:08 ` ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully Patchwork
2018-11-01 16:04 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev2) Patchwork
2018-11-01 16:09 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-11-01 16:26 ` ✓ Fi.CI.BAT: success " Patchwork
2018-11-01 18:13 ` ✓ Fi.CI.IGT: " Patchwork
2018-11-07 19:01 ` ✗ Fi.CI.BAT: failure for drm/i915: Program SKL+ watermarks/ddb more carefully (rev6) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.