All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v2 11/13] drm/i915: Commit skl+ planes in an order that avoids ddb overlaps
Date: Wed, 14 Nov 2018 23:07:27 +0200	[thread overview]
Message-ID: <20181114210729.16185-12-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20181114210729.16185-1-ville.syrjala@linux.intel.com>

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 2981cea3704a..114b2f3c6274 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12661,7 +12661,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 =
@@ -12684,8 +12683,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 4a9af09c483a..2af994942fa7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2299,10 +2299,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

  parent reply	other threads:[~2018-11-14 21:08 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-14 21:07 [PATCH v2 00/13] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjala
2018-11-14 21:07 ` [PATCH v2 01/13] drm/i915: Reorganize plane register writes to make them more atomic Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 02/13] drm/i915: Move single buffered plane register writes to the end Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 03/13] drm/i915: Introduce crtc_state->update_planes bitmask Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-21 19:10     ` Ville Syrjälä
2018-11-27 16:37   ` [PATCH v3 " Ville Syrjala
2018-11-14 21:07 ` [PATCH v2 04/13] drm/i915: Pass the new crtc_state to ->disable_plane() Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 05/13] drm/i915: Fix latency==0 handling for level 0 watermark on skl+ Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-21 19:09     ` Ville Syrjälä
2018-11-14 21:07 ` [PATCH v2 06/13] drm/i915: Remove some useless zeroing on skl+ wm calculations Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 07/13] drm/i915: Pass the entire skl_plane_wm to skl_compute_transition_wm() Ville Syrjala
2018-11-19 23:14   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 08/13] drm/i915: Clean up skl+ vs. icl+ watermark computation Ville Syrjala
2018-11-20 22:44   ` Matt Roper
2018-11-21 19:05     ` Ville Syrjälä
2018-11-21 21:05       ` Matt Roper
2018-11-27 16:57   ` [PATCH v3 " Ville Syrjala
2018-11-14 21:07 ` [PATCH v2 09/13] drm/i915: Don't pass dev_priv around so much Ville Syrjala
2018-11-20 22:45   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 10/13] drm/i915: Move ddb/wm programming into plane update/disable hooks on skl+ Ville Syrjala
2018-11-19 18:23   ` [PATCH v4 " Ville Syrjala
2018-11-21  0:48   ` [PATCH v2 " Matt Roper
2018-11-21 19:01     ` Ville Syrjälä
2018-11-27 16:59   ` [PATCH v5 " Ville Syrjala
2018-11-14 21:07 ` Ville Syrjala [this message]
2018-11-26 23:28   ` [PATCH v2 11/13] drm/i915: Commit skl+ planes in an order that avoids ddb overlaps Matt Roper
2018-11-14 21:07 ` [PATCH v2 12/13] drm/i915: Rename the confusing 'plane_id' to 'color_plane' Ville Syrjala
2018-11-26 23:30   ` Matt Roper
2018-11-14 21:07 ` [PATCH v2 13/13] drm/i915: Pass the plane to icl_program_input_csc_coeff() Ville Syrjala
2018-11-15 11:18   ` Shankar, Uma
2018-11-15 12:37   ` Maarten Lankhorst
2018-11-26 23:38   ` Matt Roper
2018-11-14 21:15 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev7) Patchwork
2018-11-14 21:19 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-11-14 21:36 ` ✓ Fi.CI.BAT: success " Patchwork
2018-11-15  5:21 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-11-15 14:23   ` Ville Syrjälä
2018-11-15 15:23     ` Ville Syrjälä
2018-11-19 18:48 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev8) Patchwork
2018-11-19 18:53 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-11-19 19:07 ` ✓ Fi.CI.BAT: success " Patchwork
2018-11-20  1:52 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-11-20 18:55 ` ✓ Fi.CI.BAT: success " Patchwork
2018-11-21  6:05 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-11-21 19:19   ` Ville Syrjälä
2018-11-23 15:07 ` ✓ Fi.CI.BAT: success " Patchwork
2018-11-23 17:45 ` ✓ Fi.CI.IGT: " Patchwork
2018-11-27 17:44 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Program SKL+ watermarks/ddb more carefully (rev11) Patchwork
2018-11-27 17:48 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-11-27 18:05 ` ✓ Fi.CI.BAT: success " Patchwork
2018-11-28  0:11 ` ✓ Fi.CI.IGT: " Patchwork
2018-11-28 20:18 ` [PATCH v2 00/13] drm/i915: Program SKL+ watermarks/ddb more carefully Ville Syrjälä

Reply instructions:

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

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

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

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

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

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

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