All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] Pre-calculate SKL-style atomic watermarks
@ 2016-04-01  1:46 Matt Roper
  2016-04-01  1:46 ` [PATCH 01/16] drm/i915: Reorganize WM structs/unions in CRTC state Matt Roper
                   ` (16 more replies)
  0 siblings, 17 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

This series moves DDB allocation and watermark calculation for SKL-style
platforms to the atomic 'check' phase.  This is important for two reasons,
described in more detail below.
 1.) It allows us to reject atomic updates that would exceed the watermark
     capabilities of the platform.
 2.) Avoid exponentially redundant computation of watermark values (and
     eliminate the WARN_ON(!wm_changed) errors).


1. Reject invalid configurations

If enough pipes and planes are turned on at the same time, it's possible that
we won't be able to find any valid watermark values that satisfy the display
configuration.  Today we blindly assume that watermark programming will always
succeed (and potentially program the hardware incorrectly).  We should take
advantage of the atomic modesetting design to recognize when a requested
display configuration exceeds our capabilities and reject the display update
before we get to the point of trying to program the hardware.


2. Avoid redundant computation

For historical reasons, our i915 legacy watermark entrypoints operate in a
per-crtc manner.  They're called with a specific CRTC as a parameter that
indicates which CRTC is changing, but they actually wind up calculating and
programming state that can be global in nature on some platforms.  On SKL-style
platforms specifically, calling update_wm on a single CRTC may actually
re-calculate the DDB allocation and watermarks for _all_ CRTC's.  This worked
okay for legacy modesetting where an operation usually only updated a single
CRTC at a time and thus had only a single call into the update_watermarks
entrypoint.  However now that our driver is atomic in nature, a single atomic
transaction may trigger changes to multiple CRTC's; our watermark entrypoints
get called for each CRTC of the transaction.  On SKL, this means that a
transaction touching M crtc's on a platform with N crtc's will potentially call
the update_wm() entrypoint MxN times.  I.e., we're redundantly computing and
programming watermark data more times than we need to.  Effectively the
situation today is:

        for each CRTC in atomic transaction {
                for each affected CRTC {
                        calculate pipe-specific WM data;
                }
                combine per-pipe WM data into global WM data;
                write global WM data;
        }

(due to the nature of DDB programming on SKL-style platforms, the inner loop
may need to recompute for every CRTC on the platform, even if they aren't being
explicitly modified by the update).

Clearly this has a lot of unwanted redundancy (and is the source of the
WARN_ON(!wm_changed) warning that has been haunting the driver for a while
now).  This series allows us to just calculate the necessary watermark data once
for the transaction.



A few notes on the series:
 * This series deals with how watermark programming fits into the atomic design
   of our driver, but doesn't focus on the lower-level computation of watermark
   values (i.e., whether or not we're following the bspec's algorithms
   properly).  I've posted another series at
   https://patchwork.freedesktop.org/series/4197/ (largely originating from
   Mahesh and Shobhit) that implements new hardware workarounds from the bspec
   or fixes bugs in areas where our logic didn't match the latest spec.  That
   series is mostly orthogonal to this series, but is arguably more important
   since it fixes the low-level correctness of the driver whereas this series 
   is focused on higher-level design.

 * This series untangles the computation half of watermarks a bit so that we're
   not redundantly programming, but the final update of the hardware that
   happens during atomic commit is still being performed more times than it
   needs to be.  I'll need to address that in a future patch series.


Kumar, Mahesh (1):
  drm/i915/skl+: Use plane size for relative data rate calculation

Matt Roper (15):
  drm/i915: Reorganize WM structs/unions in CRTC state
  drm/i915: Make skl_plane_relative_data_rate use passed CRTC state
  drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/
  drm/i915/gen9: Allow calculation of data rate for in-flight state
  drm/i915: Ensure intel_state->active_crtcs is always set
  drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight
    state
  drm/i915/gen9: Compute DDB allocation at atomic check time
  drm/i915/gen9: Drop re-allocation of DDB at atomic commit
  drm/i915/gen9: Calculate plane WM's from state
  drm/i915/gen9: Allow watermark calculation on in-flight atomic state
  drm/i915/gen9: Use a bitmask to track dirty pipe watermarks
  drm/i915/gen9: Propagate watermark calculation failures up the call
    chain
  drm/i915/gen9: Calculate watermarks during atomic 'check'
  drm/i915/gen9: Reject display updates that exceed wm limitations
  drm/i915: Remove wm_config from dev_priv/intel_atomic_state

 drivers/gpu/drm/i915/i915_drv.h      |  16 +-
 drivers/gpu/drm/i915/intel_display.c |  44 +---
 drivers/gpu/drm/i915/intel_drv.h     |  86 ++++---
 drivers/gpu/drm/i915/intel_pm.c      | 440 +++++++++++++++++++++--------------
 4 files changed, 344 insertions(+), 242 deletions(-)

-- 
2.1.4

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

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

* [PATCH 01/16] drm/i915: Reorganize WM structs/unions in CRTC state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 02/16] drm/i915: Make skl_plane_relative_data_rate use passed " Matt Roper
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Reorganize the nested structures and unions we have for pipe watermark
data in intel_crtc_state so that platform-specific data can be added in
a more sensible manner (and save a bit of memory at the same time).

The change basically changes the organization from:

        union {
                struct intel_pipe_wm ilk;
                struct intel_pipe_wm skl;
        } optimal;

        struct intel_pipe_wm intermediate /* ILK-only */

to

        union {
                struct {
                        struct intel_pipe_wm intermediate;
                        struct intel_pipe_wm optimal;
                } ilk;

                struct {
                        struct intel_pipe_wm optimal;
                } skl;
        }

There should be no functional change here, but it will allow us to add
more platform-specific fields going forward (and more easily extend to
other platform types like VLV).

While we're at it, let's move the entire watermark substructure out to
its own structure definition to make the code slightly more readable.

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

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6ac46d9..3b9c084 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -404,6 +404,40 @@ struct skl_pipe_wm {
 	uint32_t linetime;
 };
 
+struct intel_crtc_wm_state {
+	union {
+		struct {
+			/*
+			 * Intermediate watermarks; these can be
+			 * programmed immediately since they satisfy
+			 * both the current configuration we're
+			 * switching away from and the new
+			 * configuration we're switching to.
+			 */
+			struct intel_pipe_wm intermediate;
+
+			/*
+			 * Optimal watermarks, programmed post-vblank
+			 * when this state is committed.
+			 */
+			struct intel_pipe_wm optimal;
+		} ilk;
+
+		struct {
+			/* gen9+ only needs 1-step wm programming */
+			struct skl_pipe_wm optimal;
+		} skl;
+	};
+
+	/*
+	 * Platforms with two-step watermark programming will need to
+	 * update watermark programming post-vblank to switch from the
+	 * safe intermediate watermarks to the optimal final
+	 * watermarks.
+	 */
+	bool need_postvbl_update;
+};
+
 struct intel_crtc_state {
 	struct drm_crtc_state base;
 
@@ -552,32 +586,7 @@ struct intel_crtc_state {
 	/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
 	bool disable_lp_wm;
 
-	struct {
-		/*
-		 * Optimal watermarks, programmed post-vblank when this state
-		 * is committed.
-		 */
-		union {
-			struct intel_pipe_wm ilk;
-			struct skl_pipe_wm skl;
-		} optimal;
-
-		/*
-		 * Intermediate watermarks; these can be programmed immediately
-		 * since they satisfy both the current configuration we're
-		 * switching away from and the new configuration we're switching
-		 * to.
-		 */
-		struct intel_pipe_wm intermediate;
-
-		/*
-		 * Platforms with two-step watermark programming will need to
-		 * update watermark programming post-vblank to switch from the
-		 * safe intermediate watermarks to the optimal final
-		 * watermarks.
-		 */
-		bool need_postvbl_update;
-	} wm;
+	struct intel_crtc_wm_state wm;
 
 	/* Gamma mode programmed on the pipe */
 	uint32_t gamma_mode;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9bc9c25..a04e499 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2309,7 +2309,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
 	int level, max_level = ilk_wm_max_level(dev), usable_level;
 	struct ilk_wm_maximums max;
 
-	pipe_wm = &cstate->wm.optimal.ilk;
+	pipe_wm = &cstate->wm.ilk.optimal;
 
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		struct intel_plane_state *ps;
@@ -2391,7 +2391,7 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev,
 				       struct intel_crtc *intel_crtc,
 				       struct intel_crtc_state *newstate)
 {
-	struct intel_pipe_wm *a = &newstate->wm.intermediate;
+	struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate;
 	struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk;
 	int level, max_level = ilk_wm_max_level(dev);
 
@@ -2400,7 +2400,7 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev,
 	 * currently active watermarks to get values that are safe both before
 	 * and after the vblank.
 	 */
-	*a = newstate->wm.optimal.ilk;
+	*a = newstate->wm.ilk.optimal;
 	a->pipe_enabled |= b->pipe_enabled;
 	a->sprites_enabled |= b->sprites_enabled;
 	a->sprites_scaled |= b->sprites_scaled;
@@ -2429,7 +2429,7 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev,
 	 * If our intermediate WM are identical to the final WM, then we can
 	 * omit the post-vblank programming; only update if it's different.
 	 */
-	if (memcmp(a, &newstate->wm.optimal.ilk, sizeof(*a)) == 0)
+	if (memcmp(a, &newstate->wm.ilk.optimal, sizeof(*a)) == 0)
 		newstate->wm.need_postvbl_update = false;
 
 	return 0;
@@ -3664,7 +3664,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct skl_wm_values *results = &dev_priv->wm.skl_results;
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl;
+	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
 
 
 	/* Clear all dirty flags */
@@ -3743,7 +3743,7 @@ static void ilk_initial_watermarks(struct intel_crtc_state *cstate)
 	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
-	intel_crtc->wm.active.ilk = cstate->wm.intermediate;
+	intel_crtc->wm.active.ilk = cstate->wm.ilk.intermediate;
 	ilk_program_watermarks(dev_priv);
 	mutex_unlock(&dev_priv->wm.wm_mutex);
 }
@@ -3755,7 +3755,7 @@ static void ilk_optimize_watermarks(struct intel_crtc_state *cstate)
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
 	if (cstate->wm.need_postvbl_update) {
-		intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
+		intel_crtc->wm.active.ilk = cstate->wm.ilk.optimal;
 		ilk_program_watermarks(dev_priv);
 	}
 	mutex_unlock(&dev_priv->wm.wm_mutex);
@@ -3812,7 +3812,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct skl_pipe_wm *active = &cstate->wm.optimal.skl;
+	struct skl_pipe_wm *active = &cstate->wm.skl.optimal;
 	enum pipe pipe = intel_crtc->pipe;
 	int level, i, max_level;
 	uint32_t temp;
@@ -3878,7 +3878,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	struct ilk_wm_values *hw = &dev_priv->wm.hw;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-	struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
+	struct intel_pipe_wm *active = &cstate->wm.ilk.optimal;
 	enum pipe pipe = intel_crtc->pipe;
 	static const i915_reg_t wm0_pipe_reg[] = {
 		[PIPE_A] = WM0_PIPEA_ILK,
-- 
2.1.4

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

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

* [PATCH 02/16] drm/i915: Make skl_plane_relative_data_rate use passed CRTC state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
  2016-04-01  1:46 ` [PATCH 01/16] drm/i915: Reorganize WM structs/unions in CRTC state Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 03/16] drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/ Matt Roper
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

At the moment the CRTC state passed to skl_plane_relative_data_rate() is
always the committed state so intel_crtc->config and cstate are
equivalent.  However going forward, we'd like to be able to call this
function on in-flight state objects, so make sure we use the parameter.

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

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a04e499..8271b6c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2953,8 +2953,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 	}
 
 	/* for packed formats */
-	return intel_crtc->config->pipe_src_w *
-		intel_crtc->config->pipe_src_h *
+	return cstate->pipe_src_w * cstate->pipe_src_h *
 		drm_format_plane_cpp(fb->pixel_format, 0);
 }
 
-- 
2.1.4

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

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

* [PATCH 03/16] drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
  2016-04-01  1:46 ` [PATCH 01/16] drm/i915: Reorganize WM structs/unions in CRTC state Matt Roper
  2016-04-01  1:46 ` [PATCH 02/16] drm/i915: Make skl_plane_relative_data_rate use passed " Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation Matt Roper
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

When we added atomic watermarks, we added a new display vfunc
'compute_pipe_wm' that is used to compute any pipe-specific watermark
information that we can at atomic check time.  This was a somewhat poor
naming choice since we already had a 'skl_compute_pipe_wm' function that
doesn't quite fit this model --- the existing SKL function is something
that gets used at atomic commit time, after the DDB allocation has been
determined.  Let's rename the existing SKL function to avoid confusion.

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

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8271b6c..c970c4e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3312,9 +3312,9 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
 	}
 }
 
-static void skl_compute_pipe_wm(struct intel_crtc_state *cstate,
-				struct skl_ddb_allocation *ddb,
-				struct skl_pipe_wm *pipe_wm)
+static void skl_build_pipe_wm(struct intel_crtc_state *cstate,
+			      struct skl_ddb_allocation *ddb,
+			      struct skl_pipe_wm *pipe_wm)
 {
 	struct drm_device *dev = cstate->base.crtc->dev;
 	const struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3581,7 +3581,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
 	skl_allocate_pipe_ddb(cstate, ddb);
-	skl_compute_pipe_wm(cstate, ddb, pipe_wm);
+	skl_build_pipe_wm(cstate, ddb, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
 		return false;
-- 
2.1.4

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

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

* [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (2 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 03/16] drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/ Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-06 15:09   ` Imre Deak
  2016-04-01  1:46 ` [PATCH 05/16] drm/i915/gen9: Allow calculation of data rate for in-flight state Matt Roper
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>

Use plane size for relative data rate calculation. don't always use
pipe source width & height.
adjust height & width according to rotation.
use plane size for watermark calculations also.

v2: Address Matt's comments.
    Use intel_plane_state->visible to avoid divide-by-zero error.
    Where FB was present but not visible so causing total data rate to
    be zero, hence divide-by-zero.

Cc: matthew.d.roper@intel.com
Signed-off-by: Kumar, Mahesh <mahesh1.kumar@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 41 ++++++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c970c4e..1c3f772 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2937,24 +2937,28 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 			     const struct drm_plane_state *pstate,
 			     int y)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+	struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
 	struct drm_framebuffer *fb = pstate->fb;
+	uint32_t width = 0, height = 0;
+
+	width = drm_rect_width(&intel_pstate->src) >> 16;
+	height = drm_rect_height(&intel_pstate->src) >> 16;
+
+	if (intel_rotation_90_or_270(pstate->rotation))
+		swap(width, height);
 
 	/* for planar format */
 	if (fb->pixel_format == DRM_FORMAT_NV12) {
 		if (y)  /* y-plane data rate */
-			return intel_crtc->config->pipe_src_w *
-				intel_crtc->config->pipe_src_h *
+			return width * height *
 				drm_format_plane_cpp(fb->pixel_format, 0);
 		else    /* uv-plane data rate */
-			return (intel_crtc->config->pipe_src_w/2) *
-				(intel_crtc->config->pipe_src_h/2) *
+			return (width / 2) * (height / 2) *
 				drm_format_plane_cpp(fb->pixel_format, 1);
 	}
 
 	/* for packed formats */
-	return cstate->pipe_src_w * cstate->pipe_src_h *
-		drm_format_plane_cpp(fb->pixel_format, 0);
+	return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
 }
 
 /*
@@ -3033,8 +3037,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		struct drm_framebuffer *fb = plane->state->fb;
 		int id = skl_wm_plane_id(intel_plane);
 
-		if (fb == NULL)
+		if (!to_intel_plane_state(plane->state)->visible)
 			continue;
+
 		if (plane->type == DRM_PLANE_TYPE_CURSOR)
 			continue;
 
@@ -3060,7 +3065,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		uint16_t plane_blocks, y_plane_blocks = 0;
 		int id = skl_wm_plane_id(intel_plane);
 
-		if (pstate->fb == NULL)
+		if (!to_intel_plane_state(pstate)->visible)
 			continue;
 		if (plane->type == DRM_PLANE_TYPE_CURSOR)
 			continue;
@@ -3183,26 +3188,36 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 {
 	struct drm_plane *plane = &intel_plane->base;
 	struct drm_framebuffer *fb = plane->state->fb;
+	struct intel_plane_state *intel_pstate =
+					to_intel_plane_state(plane->state);
 	uint32_t latency = dev_priv->wm.skl_latency[level];
 	uint32_t method1, method2;
 	uint32_t plane_bytes_per_line, plane_blocks_per_line;
 	uint32_t res_blocks, res_lines;
 	uint32_t selected_result;
 	uint8_t cpp;
+	uint32_t width = 0, height = 0;
 
-	if (latency == 0 || !cstate->base.active || !fb)
+	if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
 		return false;
 
+	width = drm_rect_width(&intel_pstate->src) >> 16;
+	height = drm_rect_height(&intel_pstate->src) >> 16;
+
+	if (intel_rotation_90_or_270(plane->state->rotation))
+		swap(width, height);
+
 	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
 	method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
 				 cpp, latency);
 	method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
 				 cstate->base.adjusted_mode.crtc_htotal,
-				 cstate->pipe_src_w,
-				 cpp, fb->modifier[0],
+				 width,
+				 cpp,
+				 fb->modifier[0],
 				 latency);
 
-	plane_bytes_per_line = cstate->pipe_src_w * cpp;
+	plane_bytes_per_line = width * cpp;
 	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
 
 	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-- 
2.1.4

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

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

* [PATCH 05/16] drm/i915/gen9: Allow calculation of data rate for in-flight state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (3 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 06/16] drm/i915: Ensure intel_state->active_crtcs is always set Matt Roper
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Our skl_get_total_relative_data_rate() function gets passed a crtc state
object to calculate the data rate for, but it currently always looks
up the committed plane states that correspond to that CRTC.  Let's
check whether the CRTC state is an in-flight state (meaning
cstate->state is non-NULL) and if so, use the corresponding in-flight
plane states.

We'll soon be using this function exclusively for in-flight states; at
that time we'll be able to simplify the function a bit, but for now we
allow it to be used in either mode.

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

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1c3f772..e92513e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2969,18 +2969,36 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 static unsigned int
 skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
-	struct drm_device *dev = intel_crtc->base.dev;
-	const struct intel_plane *intel_plane;
+	struct drm_atomic_state *state = cstate->base.state;
+	struct drm_crtc *crtc = cstate->base.crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_plane *plane;
 	unsigned int total_data_rate = 0;
 
-	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
-		const struct drm_plane_state *pstate = intel_plane->base.state;
+	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
+		struct drm_plane_state *pstate;
 
-		if (pstate->fb == NULL)
-			continue;
+		/*
+		 * FIXME: At the moment this function can be called on either
+		 * an in-flight or a committed state object.  If it's in-flight
+		 * we want to also use the in-flight plane state; otherwise
+		 * use the committed plane state.
+		 *
+		 * Once we finish moving our DDB allocation to the atomic check
+		 * phase, we'll only be calling this function on in-flight
+		 * state objects and should never see a NULL state here.
+		 */
+		if (state) {
+			pstate = drm_atomic_get_plane_state(state, plane);
+			if (IS_ERR(pstate))
+				return PTR_ERR(pstate);
+		} else {
+			pstate = plane->state;
+		}
 
-		if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
+		if (!to_intel_plane_state(pstate)->visible)
+			continue;
+		if (plane->type == DRM_PLANE_TYPE_CURSOR)
 			continue;
 
 		/* packed/uv */
@@ -2995,6 +3013,8 @@ skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
 									1);
 	}
 
+	WARN_ON(cstate->base.plane_mask && total_data_rate == 0);
+
 	return total_data_rate;
 }
 
-- 
2.1.4

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

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

* [PATCH 06/16] drm/i915: Ensure intel_state->active_crtcs is always set
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (4 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 05/16] drm/i915/gen9: Allow calculation of data rate for in-flight state Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-05  9:29   ` Maarten Lankhorst
  2016-04-01  1:46 ` [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state Matt Roper
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

We currently only setup intel_state->active_crtcs if we plan to modify
it and write the modification back to dev_priv.  Let's ensure that
this value is always valid, even when it isn't changing as part of an
atomic transaction.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e6b5ee5..ab1fc3d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13185,7 +13185,6 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 	}
 
 	intel_state->modeset = true;
-	intel_state->active_crtcs = dev_priv->active_crtcs;
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		if (crtc_state->active)
@@ -13281,6 +13280,8 @@ static int intel_atomic_check(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	intel_state->active_crtcs = dev_priv->active_crtcs;
+
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		struct intel_crtc_state *pipe_config =
 			to_intel_crtc_state(crtc_state);
-- 
2.1.4

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

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

* [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (5 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 06/16] drm/i915: Ensure intel_state->active_crtcs is always set Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-05  9:35   ` Maarten Lankhorst
  2016-04-01  1:46 ` [PATCH 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time Matt Roper
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

We eventually want to calculate watermark values at atomic 'check' time
instead of atomic 'commit' time so that any requested configurations
that result in impossible watermark requirements are properly rejected.
The first step along this path is to allocate the DDB at atomic 'check'
time.  As we perform this transition, allow the main allocation function
to operate successfully on either an in-flight state or an
already-commited state.  Once we complete the transition in a future
patch, we'll come back and remove the unnecessary logic for the
already-committed case.

Note one other minor change here...when working with the
already-committed state, we pull the active CRTC's from
hweight(dev_priv->active_crtcs) instead of
dev_priv->wm.config.num_pipes_active.  The values should be equivalent,
but dev_priv->wm.config is pretty much unused at this point and it would
be nice to eventually remove it entirely.
---
 drivers/gpu/drm/i915/i915_drv.h |  6 +++
 drivers/gpu/drm/i915/intel_pm.c | 99 ++++++++++++++++++++++++++++++-----------
 2 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d3ebb2f..79f1974 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -318,6 +318,12 @@ struct i915_hotplug {
 			    &dev->mode_config.plane_list,	\
 			    base.head)
 
+#define for_each_intel_plane_mask(dev, intel_plane, plane_mask)		\
+	list_for_each_entry(intel_plane, &dev->mode_config.plane_list,	\
+			    base.head)					\
+		for_each_if ((plane_mask) &				\
+			     (1 << drm_plane_index(&intel_plane->base)))
+
 #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
 	list_for_each_entry(intel_plane,				\
 			    &(dev)->mode_config.plane_list,		\
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e92513e..e0ca2b9 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2849,15 +2849,15 @@ skl_wm_plane_id(const struct intel_plane *plane)
 static void
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 				   const struct intel_crtc_state *cstate,
-				   const struct intel_wm_config *config,
+				   const unsigned active_crtcs,
 				   struct skl_ddb_entry *alloc /* out */)
 {
-	struct drm_crtc *for_crtc = cstate->base.crtc;
-	struct drm_crtc *crtc;
+	struct drm_crtc *crtc = cstate->base.crtc;
 	unsigned int pipe_size, ddb_size;
+	unsigned int num_active = hweight32(active_crtcs);
 	int nth_active_pipe;
 
-	if (!cstate->base.active) {
+	if (!cstate->base.active || WARN_ON(num_active == 0)) {
 		alloc->start = 0;
 		alloc->end = 0;
 		return;
@@ -2870,25 +2870,16 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 
 	ddb_size -= 4; /* 4 blocks for bypass path allocation */
 
-	nth_active_pipe = 0;
-	for_each_crtc(dev, crtc) {
-		if (!to_intel_crtc(crtc)->active)
-			continue;
+	nth_active_pipe = hweight32(active_crtcs & (drm_crtc_mask(crtc) - 1));
 
-		if (crtc == for_crtc)
-			break;
-
-		nth_active_pipe++;
-	}
-
-	pipe_size = ddb_size / config->num_pipes_active;
-	alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
+	pipe_size = ddb_size / num_active;
+	alloc->start = nth_active_pipe * ddb_size / num_active;
 	alloc->end = alloc->start + pipe_size;
 }
 
-static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
+static unsigned int skl_cursor_allocation(const unsigned active_crtcs)
 {
-	if (config->num_pipes_active == 1)
+	if (hweight32(active_crtcs) == 1)
 		return 32;
 
 	return 8;
@@ -3018,14 +3009,13 @@ skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
 	return total_data_rate;
 }
 
-static void
+static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		      struct skl_ddb_allocation *ddb /* out */)
 {
 	struct drm_crtc *crtc = cstate->base.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_wm_config *config = &dev_priv->wm.config;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_plane *intel_plane;
 	enum pipe pipe = intel_crtc->pipe;
@@ -3034,17 +3024,43 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	uint16_t minimum[I915_MAX_PLANES];
 	uint16_t y_minimum[I915_MAX_PLANES];
 	unsigned int total_data_rate;
+	unsigned active_crtcs = 0;
 
-	skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
+	if (!cstate->base.active) {
+		ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
+		memset(ddb->plane[pipe], 0,
+		       I915_MAX_PLANES * sizeof(struct skl_ddb_entry));
+		memset(ddb->y_plane[pipe], 0,
+		       I915_MAX_PLANES * sizeof(struct skl_ddb_entry));
+		return 0;
+	}
+
+	/*
+	 * TODO:  At the moment we might call this on either an in-flight CRTC
+	 * state or an already-committed state, so look up the number of
+	 * active CRTC's accordingly.  Eventually this will only be called
+	 * on in-flight states and we'll be able to drop some of this extra
+	 * logic.
+	 */
+	if (cstate->base.state) {
+		struct intel_atomic_state *intel_state =
+			to_intel_atomic_state(cstate->base.state);
+
+		active_crtcs = intel_state->active_crtcs;
+	} else {
+		active_crtcs = dev_priv->active_crtcs;
+	}
+
+	skl_ddb_get_pipe_allocation_limits(dev, cstate, active_crtcs, alloc);
 	alloc_size = skl_ddb_entry_size(alloc);
 	if (alloc_size == 0) {
 		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
 		memset(&ddb->plane[pipe][PLANE_CURSOR], 0,
 		       sizeof(ddb->plane[pipe][PLANE_CURSOR]));
-		return;
+		return 0;
 	}
 
-	cursor_blocks = skl_cursor_allocation(config);
+	cursor_blocks = skl_cursor_allocation(active_crtcs);
 	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks;
 	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
 
@@ -3054,15 +3070,30 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	/* 1. Allocate the mininum required blocks for each active plane */
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		struct drm_plane *plane = &intel_plane->base;
+		struct drm_plane_state *pstate;
 		struct drm_framebuffer *fb = plane->state->fb;
 		int id = skl_wm_plane_id(intel_plane);
 
-		if (!to_intel_plane_state(plane->state)->visible)
+		/*
+		 * TODO: Remove support for already-committed state once we
+		 * only allocate DDB on in-flight states.
+		 */
+		if (cstate->base.state) {
+			pstate = drm_atomic_get_plane_state(cstate->base.state,
+							    plane);
+			if (IS_ERR(pstate))
+				return PTR_ERR(pstate);
+		} else {
+			pstate = plane->state;
+		}
+
+		if (!to_intel_plane_state(pstate)->visible)
 			continue;
 
 		if (plane->type == DRM_PLANE_TYPE_CURSOR)
 			continue;
 
+		fb = pstate->fb;
 		minimum[id] = 8;
 		alloc_size -= minimum[id];
 		y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
@@ -3078,13 +3109,26 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	total_data_rate = skl_get_total_relative_data_rate(cstate);
 
 	start = alloc->start;
-	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+	for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) {
 		struct drm_plane *plane = &intel_plane->base;
-		struct drm_plane_state *pstate = intel_plane->base.state;
+		struct drm_plane_state *pstate;
 		unsigned int data_rate, y_data_rate;
 		uint16_t plane_blocks, y_plane_blocks = 0;
 		int id = skl_wm_plane_id(intel_plane);
 
+		/*
+		 * TODO: Remove support for already-committed state once we
+		 * only allocate DDB on in-flight states.
+		 */
+		if (cstate->base.state) {
+			pstate = drm_atomic_get_plane_state(cstate->base.state,
+							    plane);
+			if (WARN_ON(IS_ERR(pstate)))
+				return PTR_ERR(pstate);
+		} else {
+			pstate = plane->state;
+		}
+
 		if (!to_intel_plane_state(pstate)->visible)
 			continue;
 		if (plane->type == DRM_PLANE_TYPE_CURSOR)
@@ -3125,6 +3169,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
 	}
 
+	return 0;
 }
 
 static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config)
@@ -3615,7 +3660,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
-	skl_allocate_pipe_ddb(cstate, ddb);
+	WARN_ON(skl_allocate_pipe_ddb(cstate, ddb) != 0);
 	skl_build_pipe_wm(cstate, ddb, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
-- 
2.1.4

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

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

* [PATCH 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (6 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-05  9:45   ` Maarten Lankhorst
  2016-04-01  1:46 ` [PATCH 09/16] drm/i915/gen9: Drop re-allocation of DDB at atomic commit Matt Roper
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Calculate the DDB blocks needed to satisfy the current atomic
transaction at atomic check time.  This is a prerequisite to calculating
SKL watermarks during the 'check' phase and rejecting any configurations
that we can't find valid watermarks for.

Due to the nature of DDB allocation, it's possible for the addition of a
new CRTC to make the watermark configuration already in use on another,
unchanged CRTC become invalid.  A change in which CRTC's are active
triggers a recompute of the entire DDB, which unfortunately means we
need to disallow any other atomic commits from racing with such an
update.  If the active CRTC's change, we need to grab the lock on all
CRTC's and run all CRTC's through their 'check' handler to recompute and
re-check their per-CRTC DDB allocations.

Note that with this patch we only compute the DDB allocation but we
don't actually use the computed values during watermark programming yet.
For ease of review/testing/bisecting, we still recompute the DDB at
watermark programming time and just WARN() if it doesn't match the
precomputed values.  A future patch will switch over to using the
precomputed values once we're sure they're being properly computed.

Another clarifying note:  DDB allocation itself shouldn't ever fail with
the algorithm we use today (i.e., we have enough DDB blocks on BXT to
support the minimum needs of the worst-case scenario of every pipe/plane
enabled at full size).  However the watermarks calculations based on the
DDB may fail and we'll be moving those to the atomic check as well in
future patches.

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

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 79f1974..35cebd4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -333,6 +333,10 @@ struct i915_hotplug {
 #define for_each_intel_crtc(dev, intel_crtc) \
 	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
 
+#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \
+	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) \
+		for_each_if ((crtc_mask) & (1 << drm_crtc_index(&intel_crtc->base)))
+
 #define for_each_intel_encoder(dev, intel_encoder)		\
 	list_for_each_entry(intel_encoder,			\
 			    &(dev)->mode_config.encoder_list,	\
@@ -587,6 +591,7 @@ struct drm_i915_display_funcs {
 				       struct intel_crtc_state *newstate);
 	void (*initial_watermarks)(struct intel_crtc_state *cstate);
 	void (*optimize_watermarks)(struct intel_crtc_state *cstate);
+	int (*compute_global_watermarks)(struct drm_atomic_state *state);
 	void (*update_wm)(struct drm_crtc *crtc);
 	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
 	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ab1fc3d..6bf2ede 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13230,6 +13230,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 static void calc_watermark_data(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *cstate;
@@ -13259,6 +13260,10 @@ static void calc_watermark_data(struct drm_atomic_state *state)
 		    pstate->crtc_h != pstate->src_h >> 16)
 			intel_state->wm_config.sprites_scaled = true;
 	}
+
+	/* Is there platform-specific watermark information to calculate? */
+	if (dev_priv->display.compute_global_watermarks)
+		dev_priv->display.compute_global_watermarks(state);
 }
 
 /**
@@ -13631,6 +13636,19 @@ static int intel_atomic_commit(struct drm_device *dev,
 			modeset_put_power_domains(dev_priv, put_domains[i]);
 	}
 
+	/*
+	 * Temporary sanity check: make sure our pre-computed DDB matches the
+	 * one we actually wind up programming.
+	 *
+	 * Not a great place to put this, but the easiest place we have access
+	 * to both the pre-computed and final DDB's; we'll be removing this
+	 * check in the next patch anyway.
+	 */
+	WARN(IS_GEN9(dev) &&
+	     memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
+		    sizeof(intel_state->ddb)),
+	     "Pre-computed DDB does not match final DDB!\n");
+
 	if (intel_state->modeset)
 		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3b9c084..483261c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -301,6 +301,9 @@ struct intel_atomic_state {
 	 * don't bother calculating intermediate watermarks.
 	 */
 	bool skip_intermediate_wm;
+
+	/* Gen9+ only */
+	struct skl_ddb_allocation ddb;
 };
 
 struct intel_plane_state {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e0ca2b9..8e283cf 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3736,6 +3736,58 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
 
 }
 
+static int
+skl_compute_ddb(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct intel_crtc *intel_crtc;
+	unsigned realloc_pipes = intel_state->active_crtcs;
+	int ret;
+
+	/*
+	 * If the modeset changes which CRTC's are active, we need to
+	 * recompute the DDB allocation for *all* active pipes, even
+	 * those that weren't otherwise being modified in any way by this
+	 * atomic commit.  Due to the shrinking of the per-pipe allocations
+	 * when new active CRTC's are added, it's possible for a pipe that
+	 * we were already using and aren't changing at all here to suddenly
+	 * become invalid if its DDB needs exceeds its new allocation.
+	 *
+	 * Note that if we wind up doing a full DDB recompute, we can't let
+	 * any other display updates race with this transaction, so we need
+	 * to grab the lock on *all* CRTC's.
+	 */
+	if (intel_state->active_crtcs != to_i915(dev)->active_crtcs)
+		realloc_pipes = ~0;
+
+	for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
+		struct intel_crtc_state *cstate;
+
+		cstate = intel_atomic_get_crtc_state(state, intel_crtc);
+		if (IS_ERR(cstate))
+			return PTR_ERR(cstate);
+
+		ret = skl_allocate_pipe_ddb(cstate, &intel_state->ddb);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+skl_compute_wm(struct drm_atomic_state *state)
+{
+	int ret;
+
+	ret = skl_compute_ddb(state);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static void skl_update_wm(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7252,6 +7304,7 @@ void intel_init_pm(struct drm_device *dev)
 	if (INTEL_INFO(dev)->gen >= 9) {
 		skl_setup_wm_latency(dev);
 		dev_priv->display.update_wm = skl_update_wm;
+		dev_priv->display.compute_global_watermarks = skl_compute_wm;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
 
-- 
2.1.4

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

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

* [PATCH 09/16] drm/i915/gen9: Drop re-allocation of DDB at atomic commit
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (7 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 10/16] drm/i915/gen9: Calculate plane WM's from state Matt Roper
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Now that we're properly pre-allocating the DDB during the atomic check
phase and we trust that the allocation is appropriate, let's actually
use the allocation computed and not duplicate that work during the
commit phase.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 14 +-----
 drivers/gpu/drm/i915/intel_pm.c      | 84 ++++++++----------------------------
 2 files changed, 18 insertions(+), 80 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6bf2ede..fa4e5e3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13523,6 +13523,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 
 	drm_atomic_helper_swap_state(dev, state);
 	dev_priv->wm.config = intel_state->wm_config;
+	dev_priv->wm.skl_results.ddb = intel_state->ddb;
 	intel_shared_dpll_commit(state);
 
 	if (intel_state->modeset) {
@@ -13636,19 +13637,6 @@ static int intel_atomic_commit(struct drm_device *dev,
 			modeset_put_power_domains(dev_priv, put_domains[i]);
 	}
 
-	/*
-	 * Temporary sanity check: make sure our pre-computed DDB matches the
-	 * one we actually wind up programming.
-	 *
-	 * Not a great place to put this, but the easiest place we have access
-	 * to both the pre-computed and final DDB's; we'll be removing this
-	 * check in the next patch anyway.
-	 */
-	WARN(IS_GEN9(dev) &&
-	     memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
-		    sizeof(intel_state->ddb)),
-	     "Pre-computed DDB does not match final DDB!\n");
-
 	if (intel_state->modeset)
 		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8e283cf..d58a405 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2966,26 +2966,15 @@ skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
 	struct drm_plane *plane;
 	unsigned int total_data_rate = 0;
 
+	if (WARN_ON(!state))
+		return 0;
+
 	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
 		struct drm_plane_state *pstate;
 
-		/*
-		 * FIXME: At the moment this function can be called on either
-		 * an in-flight or a committed state object.  If it's in-flight
-		 * we want to also use the in-flight plane state; otherwise
-		 * use the committed plane state.
-		 *
-		 * Once we finish moving our DDB allocation to the atomic check
-		 * phase, we'll only be calling this function on in-flight
-		 * state objects and should never see a NULL state here.
-		 */
-		if (state) {
-			pstate = drm_atomic_get_plane_state(state, plane);
-			if (IS_ERR(pstate))
-				return PTR_ERR(pstate);
-		} else {
-			pstate = plane->state;
-		}
+		pstate = drm_atomic_get_plane_state(state, plane);
+		if (IS_ERR(pstate))
+			return PTR_ERR(pstate);
 
 		if (!to_intel_plane_state(pstate)->visible)
 			continue;
@@ -3015,9 +3004,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 {
 	struct drm_crtc *crtc = cstate->base.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_plane *intel_plane;
+	struct intel_atomic_state *intel_state;
 	enum pipe pipe = intel_crtc->pipe;
 	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
 	uint16_t alloc_size, start, cursor_blocks;
@@ -3035,21 +3024,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		return 0;
 	}
 
-	/*
-	 * TODO:  At the moment we might call this on either an in-flight CRTC
-	 * state or an already-committed state, so look up the number of
-	 * active CRTC's accordingly.  Eventually this will only be called
-	 * on in-flight states and we'll be able to drop some of this extra
-	 * logic.
-	 */
-	if (cstate->base.state) {
-		struct intel_atomic_state *intel_state =
-			to_intel_atomic_state(cstate->base.state);
+	if (WARN_ON(!cstate->base.state))
+		return 0;
 
-		active_crtcs = intel_state->active_crtcs;
-	} else {
-		active_crtcs = dev_priv->active_crtcs;
-	}
+	intel_state = to_intel_atomic_state(cstate->base.state);
+	active_crtcs = intel_state->active_crtcs;
 
 	skl_ddb_get_pipe_allocation_limits(dev, cstate, active_crtcs, alloc);
 	alloc_size = skl_ddb_entry_size(alloc);
@@ -3074,18 +3053,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		struct drm_framebuffer *fb = plane->state->fb;
 		int id = skl_wm_plane_id(intel_plane);
 
-		/*
-		 * TODO: Remove support for already-committed state once we
-		 * only allocate DDB on in-flight states.
-		 */
-		if (cstate->base.state) {
-			pstate = drm_atomic_get_plane_state(cstate->base.state,
-							    plane);
-			if (IS_ERR(pstate))
-				return PTR_ERR(pstate);
-		} else {
-			pstate = plane->state;
-		}
+		pstate = drm_atomic_get_plane_state(cstate->base.state, plane);
+		if (IS_ERR(pstate))
+			return PTR_ERR(pstate);
 
 		if (!to_intel_plane_state(pstate)->visible)
 			continue;
@@ -3116,18 +3086,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		uint16_t plane_blocks, y_plane_blocks = 0;
 		int id = skl_wm_plane_id(intel_plane);
 
-		/*
-		 * TODO: Remove support for already-committed state once we
-		 * only allocate DDB on in-flight states.
-		 */
-		if (cstate->base.state) {
-			pstate = drm_atomic_get_plane_state(cstate->base.state,
-							    plane);
-			if (WARN_ON(IS_ERR(pstate)))
-				return PTR_ERR(pstate);
-		} else {
-			pstate = plane->state;
-		}
+		pstate = drm_atomic_get_plane_state(cstate->base.state, plane);
+		if (WARN_ON(IS_ERR(pstate)))
+			return PTR_ERR(pstate);
 
 		if (!to_intel_plane_state(pstate)->visible)
 			continue;
@@ -3660,7 +3621,6 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 
-	WARN_ON(skl_allocate_pipe_ddb(cstate, ddb) != 0);
 	skl_build_pipe_wm(cstate, ddb, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
@@ -3724,16 +3684,6 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
 	memset(watermarks->plane_trans[pipe],
 	       0, sizeof(uint32_t) * I915_MAX_PLANES);
 	watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
-
-	/* Clear ddb entries for pipe */
-	memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry));
-	memset(&watermarks->ddb.plane[pipe], 0,
-	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
-	memset(&watermarks->ddb.y_plane[pipe], 0,
-	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
-	memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0,
-	       sizeof(struct skl_ddb_entry));
-
 }
 
 static int
-- 
2.1.4

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

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

* [PATCH 10/16] drm/i915/gen9: Calculate plane WM's from state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (8 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 09/16] drm/i915/gen9: Drop re-allocation of DDB at atomic commit Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state Matt Roper
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

In a future patch we'll want to calculate plane watermarks for in-flight
atomic state rather than the already-committed state.

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

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d58a405..6aafbb1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3206,16 +3206,14 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
 
 static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 				 struct intel_crtc_state *cstate,
-				 struct intel_plane *intel_plane,
+				 struct intel_plane_state *intel_pstate,
 				 uint16_t ddb_allocation,
 				 int level,
 				 uint16_t *out_blocks, /* out */
 				 uint8_t *out_lines /* out */)
 {
-	struct drm_plane *plane = &intel_plane->base;
-	struct drm_framebuffer *fb = plane->state->fb;
-	struct intel_plane_state *intel_pstate =
-					to_intel_plane_state(plane->state);
+	struct drm_plane_state *pstate = &intel_pstate->base;
+	struct drm_framebuffer *fb = pstate->fb;
 	uint32_t latency = dev_priv->wm.skl_latency[level];
 	uint32_t method1, method2;
 	uint32_t plane_bytes_per_line, plane_blocks_per_line;
@@ -3230,7 +3228,7 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	width = drm_rect_width(&intel_pstate->src) >> 16;
 	height = drm_rect_height(&intel_pstate->src) >> 16;
 
-	if (intel_rotation_90_or_270(plane->state->rotation))
+	if (intel_rotation_90_or_270(pstate->rotation))
 		swap(width, height);
 
 	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
@@ -3250,7 +3248,7 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
 		uint32_t min_scanlines = 4;
 		uint32_t y_tile_minimum;
-		if (intel_rotation_90_or_270(plane->state->rotation)) {
+		if (intel_rotation_90_or_270(pstate->rotation)) {
 			int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
 				drm_format_plane_cpp(fb->pixel_format, 1) :
 				drm_format_plane_cpp(fb->pixel_format, 0);
@@ -3304,17 +3302,19 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 	struct drm_device *dev = dev_priv->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
 	struct intel_plane *intel_plane;
+	struct intel_plane_state *intel_pstate;
 	uint16_t ddb_blocks;
 	enum pipe pipe = intel_crtc->pipe;
 
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		int i = skl_wm_plane_id(intel_plane);
 
+		intel_pstate = to_intel_plane_state(intel_plane->base.state);
 		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
 
 		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
 						cstate,
-						intel_plane,
+						intel_pstate,
 						ddb_blocks,
 						level,
 						&result->plane_res_b[i],
-- 
2.1.4

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

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

* [PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (9 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 10/16] drm/i915/gen9: Calculate plane WM's from state Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-05  9:52   ` Maarten Lankhorst
  2016-04-01  1:46 ` [PATCH 12/16] drm/i915/gen9: Use a bitmask to track dirty pipe watermarks Matt Roper
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

In an upcoming patch we'll move this calculation to the atomic 'check'
phase so that the display update can be rejected early if no valid
watermark programming is possible.

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

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 483261c..6471f69 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1667,6 +1667,27 @@ intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
 	return to_intel_plane_state(plane_state);
 }
 
+/*
+ * If cstate is in-flight, return in-flight plane state, otherwise
+ * return committed plane state.
+ */
+static inline struct intel_plane_state *
+intel_pstate_for_cstate_plane(struct intel_crtc_state *cstate,
+			      struct intel_plane *plane)
+{
+	struct drm_atomic_state *state = cstate->base.state;
+	struct drm_plane_state *pstate;
+
+	if (state == NULL)
+		return to_intel_plane_state(plane->base.state);
+
+	pstate = drm_atomic_get_plane_state(state, &plane->base);
+
+	return to_intel_plane_state(pstate);
+}
+
+
+
 int intel_atomic_setup_scalers(struct drm_device *dev,
 	struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6aafbb1..0a7f4d7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3293,11 +3293,12 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	return true;
 }
 
-static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
-				 struct skl_ddb_allocation *ddb,
-				 struct intel_crtc_state *cstate,
-				 int level,
-				 struct skl_wm_level *result)
+static int
+skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+		     struct skl_ddb_allocation *ddb,
+		     struct intel_crtc_state *cstate,
+		     int level,
+		     struct skl_wm_level *result)
 {
 	struct drm_device *dev = dev_priv->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
@@ -3309,7 +3310,11 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		int i = skl_wm_plane_id(intel_plane);
 
-		intel_pstate = to_intel_plane_state(intel_plane->base.state);
+		intel_pstate = intel_pstate_for_cstate_plane(cstate,
+							     intel_plane);
+		if (IS_ERR(intel_pstate))
+			return PTR_ERR(intel_pstate);
+
 		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
 
 		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
@@ -3320,6 +3325,8 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 						&result->plane_res_b[i],
 						&result->plane_res_l[i]);
 	}
+
+	return 0;
 }
 
 static uint32_t
@@ -3614,14 +3621,14 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	}
 }
 
-static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+static bool skl_update_pipe_wm(struct drm_crtc_state *cstate,
 			       struct skl_ddb_allocation *ddb, /* out */
 			       struct skl_pipe_wm *pipe_wm /* out */)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc);
+	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
 
-	skl_build_pipe_wm(cstate, ddb, pipe_wm);
+	skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
 		return false;
@@ -3661,7 +3668,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		if (!intel_crtc->active)
 			continue;
 
-		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
+		wm_changed = skl_update_pipe_wm(intel_crtc->base.state,
 						&r->ddb, &pipe_wm);
 
 		/*
@@ -3753,7 +3760,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
 
 	skl_clear_wm(results, intel_crtc->pipe);
 
-	if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm))
+	if (!skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm))
 		return;
 
 	skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
-- 
2.1.4

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

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

* [PATCH 12/16] drm/i915/gen9: Use a bitmask to track dirty pipe watermarks
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (10 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 13/16] drm/i915/gen9: Propagate watermark calculation failures up the call chain Matt Roper
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Slightly easier to work with than an array of bools.

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

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 35cebd4..34b843d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1575,7 +1575,7 @@ struct skl_ddb_allocation {
 };
 
 struct skl_wm_values {
-	bool dirty[I915_MAX_PIPES];
+	unsigned dirty_pipes;
 	struct skl_ddb_allocation ddb;
 	uint32_t wm_linetime[I915_MAX_PIPES];
 	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0a7f4d7..be7fbff 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3454,7 +3454,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
 		int i, level, max_level = ilk_wm_max_level(dev);
 		enum pipe pipe = crtc->pipe;
 
-		if (!new->dirty[pipe])
+		if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0)
 			continue;
 
 		I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
@@ -3679,7 +3679,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		WARN_ON(!wm_changed);
 
 		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
-		r->dirty[intel_crtc->pipe] = true;
+		r->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
 	}
 }
 
@@ -3756,7 +3756,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
 
 
 	/* Clear all dirty flags */
-	memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES);
+	results->dirty_pipes = 0;
 
 	skl_clear_wm(results, intel_crtc->pipe);
 
@@ -3764,7 +3764,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
 		return;
 
 	skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
-	results->dirty[intel_crtc->pipe] = true;
+	results->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
 
 	skl_update_other_pipe_wm(dev, crtc, results);
 	skl_write_wm_values(dev_priv, results);
@@ -3923,7 +3923,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	if (!intel_crtc->active)
 		return;
 
-	hw->dirty[pipe] = true;
+	hw->dirty_pipes |= drm_crtc_mask(crtc);
 
 	active->linetime = hw->wm_linetime[pipe];
 
-- 
2.1.4

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

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

* [PATCH 13/16] drm/i915/gen9: Propagate watermark calculation failures up the call chain
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (11 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 12/16] drm/i915/gen9: Use a bitmask to track dirty pipe watermarks Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check' Matt Roper
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Once we move watermark calculation to the atomic check phase, we'll want
to start rejecting display configurations that exceed out watermark
limits.  At the moment we just assume that there's always a valid set of
watermarks, even though this may not actually be true.  Let's prepare by
passing return codes up through the call stack in preparation.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 10 ++--
 drivers/gpu/drm/i915/intel_pm.c      | 90 ++++++++++++++++++++++--------------
 2 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fa4e5e3..c514549 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13227,7 +13227,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
  * phase.  The code here should be run after the per-crtc and per-plane 'check'
  * handlers to ensure that all derived state has been updated.
  */
-static void calc_watermark_data(struct drm_atomic_state *state)
+static int calc_watermark_data(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -13263,7 +13263,9 @@ static void calc_watermark_data(struct drm_atomic_state *state)
 
 	/* Is there platform-specific watermark information to calculate? */
 	if (dev_priv->display.compute_global_watermarks)
-		dev_priv->display.compute_global_watermarks(state);
+		return dev_priv->display.compute_global_watermarks(state);
+
+	return 0;
 }
 
 /**
@@ -13349,9 +13351,7 @@ static int intel_atomic_check(struct drm_device *dev,
 		return ret;
 
 	intel_fbc_choose_crtc(dev_priv, state);
-	calc_watermark_data(state);
-
-	return 0;
+	return calc_watermark_data(state);
 }
 
 static int intel_atomic_prepare_commit(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index be7fbff..1bef89a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3204,13 +3204,14 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
 	return false;
 }
 
-static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
-				 struct intel_crtc_state *cstate,
-				 struct intel_plane_state *intel_pstate,
-				 uint16_t ddb_allocation,
-				 int level,
-				 uint16_t *out_blocks, /* out */
-				 uint8_t *out_lines /* out */)
+static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+				struct intel_crtc_state *cstate,
+				struct intel_plane_state *intel_pstate,
+				uint16_t ddb_allocation,
+				int level,
+				uint16_t *out_blocks, /* out */
+				uint8_t *out_lines, /* out */
+				bool *enabled /* out */)
 {
 	struct drm_plane_state *pstate = &intel_pstate->base;
 	struct drm_framebuffer *fb = pstate->fb;
@@ -3222,8 +3223,10 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	uint8_t cpp;
 	uint32_t width = 0, height = 0;
 
-	if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
-		return false;
+	if (latency == 0 || !cstate->base.active || !intel_pstate->visible) {
+		*enabled = false;
+		return 0;
+	}
 
 	width = drm_rect_width(&intel_pstate->src) >> 16;
 	height = drm_rect_height(&intel_pstate->src) >> 16;
@@ -3284,13 +3287,16 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 			res_blocks++;
 	}
 
-	if (res_blocks >= ddb_allocation || res_lines > 31)
-		return false;
+	if (res_blocks >= ddb_allocation || res_lines > 31) {
+		*enabled = false;
+		return 0;
+	}
 
 	*out_blocks = res_blocks;
 	*out_lines = res_lines;
+	*enabled = true;
 
-	return true;
+	return 0;
 }
 
 static int
@@ -3306,6 +3312,7 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 	struct intel_plane_state *intel_pstate;
 	uint16_t ddb_blocks;
 	enum pipe pipe = intel_crtc->pipe;
+	int ret;
 
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		int i = skl_wm_plane_id(intel_plane);
@@ -3317,13 +3324,16 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 
 		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
 
-		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
-						cstate,
-						intel_pstate,
-						ddb_blocks,
-						level,
-						&result->plane_res_b[i],
-						&result->plane_res_l[i]);
+		ret = skl_compute_plane_wm(dev_priv,
+					   cstate,
+					   intel_pstate,
+					   ddb_blocks,
+					   level,
+					   &result->plane_res_b[i],
+					   &result->plane_res_l[i],
+					   &result->plane_en[i]);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -3360,21 +3370,26 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
 	}
 }
 
-static void skl_build_pipe_wm(struct intel_crtc_state *cstate,
-			      struct skl_ddb_allocation *ddb,
-			      struct skl_pipe_wm *pipe_wm)
+static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
+			     struct skl_ddb_allocation *ddb,
+			     struct skl_pipe_wm *pipe_wm)
 {
 	struct drm_device *dev = cstate->base.crtc->dev;
 	const struct drm_i915_private *dev_priv = dev->dev_private;
 	int level, max_level = ilk_wm_max_level(dev);
+	int ret;
 
 	for (level = 0; level <= max_level; level++) {
-		skl_compute_wm_level(dev_priv, ddb, cstate,
-				     level, &pipe_wm->wm[level]);
+		ret = skl_compute_wm_level(dev_priv, ddb, cstate,
+					   level, &pipe_wm->wm[level]);
+		if (ret)
+			return ret;
 	}
 	pipe_wm->linetime = skl_compute_linetime_wm(cstate);
 
 	skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
+
+	return 0;
 }
 
 static void skl_compute_wm_results(struct drm_device *dev,
@@ -3621,21 +3636,27 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	}
 }
 
-static bool skl_update_pipe_wm(struct drm_crtc_state *cstate,
-			       struct skl_ddb_allocation *ddb, /* out */
-			       struct skl_pipe_wm *pipe_wm /* out */)
+static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
+			      struct skl_ddb_allocation *ddb, /* out */
+			      struct skl_pipe_wm *pipe_wm, /* out */
+			      bool *changed /* out */)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc);
 	struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
+	int ret;
 
-	skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
+	ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
+	if (ret)
+		return ret;
 
 	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
-		return false;
+		*changed = false;
+	else
+		*changed = true;
 
 	intel_crtc->wm.active.skl = *pipe_wm;
 
-	return true;
+	return 0;
 }
 
 static void skl_update_other_pipe_wm(struct drm_device *dev,
@@ -3668,8 +3689,8 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		if (!intel_crtc->active)
 			continue;
 
-		wm_changed = skl_update_pipe_wm(intel_crtc->base.state,
-						&r->ddb, &pipe_wm);
+		skl_update_pipe_wm(intel_crtc->base.state,
+				   &r->ddb, &pipe_wm, &wm_changed);
 
 		/*
 		 * If we end up re-computing the other pipe WM values, it's
@@ -3753,14 +3774,15 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	struct skl_wm_values *results = &dev_priv->wm.skl_results;
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
-
+	bool wm_changed;
 
 	/* Clear all dirty flags */
 	results->dirty_pipes = 0;
 
 	skl_clear_wm(results, intel_crtc->pipe);
 
-	if (!skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm))
+	skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm, &wm_changed);
+	if (!wm_changed);
 		return;
 
 	skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
-- 
2.1.4

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

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

* [PATCH 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check'
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (12 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 13/16] drm/i915/gen9: Propagate watermark calculation failures up the call chain Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-05 13:01   ` Patrik Jakobsson
  2016-04-01  1:46 ` [PATCH 15/16] drm/i915/gen9: Reject display updates that exceed wm limitations Matt Roper
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

Moving watermark calculation into the check phase will allow us to to
reject display configurations for which there are no valid watermark
values before we start trying to program the hardware (although those
tests will come in a subsequent patch).

Another advantage of moving this calculation to the check phase is that
we can calculate the watermarks in a single shot as part of the atomic
transaction.  The watermark interfaces we inherited from our legacy
modesetting days are a bit broken in the atomic design because they use
per-crtc entry points but actually re-calculate and re-program something
that is really more of a global state.  That worked okay in the legacy
modesetting world because operations only ever updated a single CRTC at
a time.  However in the atomic world, a transaction can involve multiple
CRTC's, which means we wind up computing and programming the watermarks
NxN times (where N is the number of CRTC's involved).  With this patch
we eliminate the redundant re-calculation of watermark data for atomic
states (which was the cause of the WARN_ON(!wm_changed) problems that
have plagued us for a while).

We still need to work on the 'commit' side of watermark handling so that
we aren't doing redundant NxN programming of watermarks, but that's
content for future patches.

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

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c514549..f1bea9f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13523,7 +13523,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 
 	drm_atomic_helper_swap_state(dev, state);
 	dev_priv->wm.config = intel_state->wm_config;
-	dev_priv->wm.skl_results.ddb = intel_state->ddb;
+	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
 
 	if (intel_state->modeset) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6471f69..3abd394 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -303,7 +303,7 @@ struct intel_atomic_state {
 	bool skip_intermediate_wm;
 
 	/* Gen9+ only */
-	struct skl_ddb_allocation ddb;
+	struct skl_wm_values wm_results;
 };
 
 struct intel_plane_state {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1bef89a..e4de5aa 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3187,23 +3187,6 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
 	return ret;
 }
 
-static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
-				       const struct intel_crtc *intel_crtc)
-{
-	struct drm_device *dev = intel_crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
-
-	/*
-	 * If ddb allocation of pipes changed, it may require recalculation of
-	 * watermarks
-	 */
-	if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
-		return true;
-
-	return false;
-}
-
 static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 				struct intel_crtc_state *cstate,
 				struct intel_plane_state *intel_pstate,
@@ -3654,72 +3637,16 @@ static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
 	else
 		*changed = true;
 
-	intel_crtc->wm.active.skl = *pipe_wm;
-
 	return 0;
 }
 
-static void skl_update_other_pipe_wm(struct drm_device *dev,
-				     struct drm_crtc *crtc,
-				     struct skl_wm_values *r)
-{
-	struct intel_crtc *intel_crtc;
-	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
-
-	/*
-	 * If the WM update hasn't changed the allocation for this_crtc (the
-	 * crtc we are currently computing the new WM values for), other
-	 * enabled crtcs will keep the same allocation and we don't need to
-	 * recompute anything for them.
-	 */
-	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
-		return;
-
-	/*
-	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
-	 * other active pipes need new DDB allocation and WM values.
-	 */
-	for_each_intel_crtc(dev, intel_crtc) {
-		struct skl_pipe_wm pipe_wm = {};
-		bool wm_changed;
-
-		if (this_crtc->pipe == intel_crtc->pipe)
-			continue;
-
-		if (!intel_crtc->active)
-			continue;
-
-		skl_update_pipe_wm(intel_crtc->base.state,
-				   &r->ddb, &pipe_wm, &wm_changed);
-
-		/*
-		 * If we end up re-computing the other pipe WM values, it's
-		 * because it was really needed, so we expect the WM values to
-		 * be different.
-		 */
-		WARN_ON(!wm_changed);
-
-		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
-		r->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
-	}
-}
-
-static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
-{
-	watermarks->wm_linetime[pipe] = 0;
-	memset(watermarks->plane[pipe], 0,
-	       sizeof(uint32_t) * 8 * I915_MAX_PLANES);
-	memset(watermarks->plane_trans[pipe],
-	       0, sizeof(uint32_t) * I915_MAX_PLANES);
-	watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
-}
-
 static int
 skl_compute_ddb(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct intel_crtc *intel_crtc;
+	struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
 	unsigned realloc_pipes = intel_state->active_crtcs;
 	int ret;
 
@@ -3736,8 +3663,10 @@ skl_compute_ddb(struct drm_atomic_state *state)
 	 * any other display updates race with this transaction, so we need
 	 * to grab the lock on *all* CRTC's.
 	 */
-	if (intel_state->active_crtcs != to_i915(dev)->active_crtcs)
+	if (intel_state->active_crtcs != to_i915(dev)->active_crtcs) {
 		realloc_pipes = ~0;
+		intel_state->wm_results.dirty_pipes = ~0;
+	}
 
 	for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
 		struct intel_crtc_state *cstate;
@@ -3746,7 +3675,7 @@ skl_compute_ddb(struct drm_atomic_state *state)
 		if (IS_ERR(cstate))
 			return PTR_ERR(cstate);
 
-		ret = skl_allocate_pipe_ddb(cstate, &intel_state->ddb);
+		ret = skl_allocate_pipe_ddb(cstate, ddb);
 		if (ret)
 			return ret;
 	}
@@ -3757,12 +3686,53 @@ skl_compute_ddb(struct drm_atomic_state *state)
 static int
 skl_compute_wm(struct drm_atomic_state *state)
 {
-	int ret;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *cstate;
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct skl_wm_values *results = &intel_state->wm_results;
+	struct skl_pipe_wm *pipe_wm;
+	bool changed;
+	int ret, i;
+
+	/* Clear all dirty flags */
+	results->dirty_pipes = 0;
 
 	ret = skl_compute_ddb(state);
 	if (ret)
 		return ret;
 
+	/*
+	 * Calculate WM's for all pipes that are part of this transaction.
+	 * Note that the DDB allocation above may have added more CRTC's that
+	 * weren't otherwise being modified (and set bits in dirty_pipes) if
+	 * pipe allocations had to change.
+	 *
+	 * FIXME:  Now that we're doing this in the atomic check phase, we
+	 * should allow skl_update_pipe_wm() to return failure in cases where
+	 * no suitable watermark values can be found.
+	 */
+	for_each_crtc_in_state(state, crtc, cstate, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		struct intel_crtc_state *intel_cstate =
+			to_intel_crtc_state(cstate);
+
+		pipe_wm = &intel_cstate->wm.skl.optimal;
+		ret = skl_update_pipe_wm(cstate, &results->ddb, pipe_wm,
+					 &changed);
+		if (ret)
+			return ret;
+
+		if (changed)
+			results->dirty_pipes |= drm_crtc_mask(crtc);
+
+		if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
+			/* This pipe's WM's did not change */
+			continue;
+
+		intel_cstate->update_wm_pre = true;
+		skl_compute_wm_results(crtc->dev, pipe_wm, results, intel_crtc);
+	}
+
 	return 0;
 }
 
@@ -3774,26 +3744,21 @@ static void skl_update_wm(struct drm_crtc *crtc)
 	struct skl_wm_values *results = &dev_priv->wm.skl_results;
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
-	bool wm_changed;
 
-	/* Clear all dirty flags */
-	results->dirty_pipes = 0;
-
-	skl_clear_wm(results, intel_crtc->pipe);
-
-	skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm, &wm_changed);
-	if (!wm_changed);
+	if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
 		return;
 
-	skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
-	results->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
+	intel_crtc->wm.active.skl = *pipe_wm;
+
+	mutex_lock(&dev_priv->wm.wm_mutex);
 
-	skl_update_other_pipe_wm(dev, crtc, results);
 	skl_write_wm_values(dev_priv, results);
 	skl_flush_wm_values(dev_priv, results);
 
 	/* store the new configuration */
 	dev_priv->wm.skl_hw = *results;
+
+	mutex_unlock(&dev_priv->wm.wm_mutex);
 }
 
 static void ilk_compute_wm_config(struct drm_device *dev,
-- 
2.1.4

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

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

* [PATCH 15/16] drm/i915/gen9: Reject display updates that exceed wm limitations
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (13 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check' Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-01  1:46 ` [PATCH 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state Matt Roper
  2016-04-01  9:36 ` ✗ Fi.CI.BAT: warning for Pre-calculate SKL-style atomic watermarks Patchwork
  16 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

If we can't find any valid level 0 watermark values for the requested
atomic transaction, reject the configuration before we try to start
programming the hardware.

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

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e4de5aa..8370bb5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3272,7 +3272,17 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 
 	if (res_blocks >= ddb_allocation || res_lines > 31) {
 		*enabled = false;
-		return 0;
+
+		/*
+		 * If there are no valid level 0 watermarks, then we can't
+		 * support this display configuration.
+		 */
+		if (level) {
+			return 0;
+		} else {
+			DRM_DEBUG_KMS("Requested display configuration exceeds system watermark limitations\n");
+			return -EINVAL;
+		}
 	}
 
 	*out_blocks = res_blocks;
-- 
2.1.4

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

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

* [PATCH 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (14 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 15/16] drm/i915/gen9: Reject display updates that exceed wm limitations Matt Roper
@ 2016-04-01  1:46 ` Matt Roper
  2016-04-05 10:14   ` Maarten Lankhorst
  2016-04-01  9:36 ` ✗ Fi.CI.BAT: warning for Pre-calculate SKL-style atomic watermarks Patchwork
  16 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-01  1:46 UTC (permalink / raw
  To: intel-gfx

We calculate the watermark config into intel_atomic_state and then save
it into dev_priv, but never actually use it from there.  This is
left-over from some early ILK-style watermark programming designs that
got changed over time.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  3 ---
 drivers/gpu/drm/i915/intel_display.c | 31 -------------------------------
 drivers/gpu/drm/i915/intel_drv.h     |  1 -
 3 files changed, 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 34b843d..044e977 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1937,9 +1937,6 @@ struct drm_i915_private {
 		 */
 		uint16_t skl_latency[8];
 
-		/* Committed wm config */
-		struct intel_wm_config config;
-
 		/*
 		 * The skl_wm_values structure is a bit too big for stack
 		 * allocation, so we keep the staging struct where we store
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f1bea9f..f650e8c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13231,35 +13231,6 @@ static int calc_watermark_data(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-	struct drm_crtc *crtc;
-	struct drm_crtc_state *cstate;
-	struct drm_plane *plane;
-	struct drm_plane_state *pstate;
-
-	/*
-	 * Calculate watermark configuration details now that derived
-	 * plane/crtc state is all properly updated.
-	 */
-	drm_for_each_crtc(crtc, dev) {
-		cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
-			crtc->state;
-
-		if (cstate->active)
-			intel_state->wm_config.num_pipes_active++;
-	}
-	drm_for_each_legacy_plane(plane, dev) {
-		pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
-			plane->state;
-
-		if (!to_intel_plane_state(pstate)->visible)
-			continue;
-
-		intel_state->wm_config.sprites_enabled = true;
-		if (pstate->crtc_w != pstate->src_w >> 16 ||
-		    pstate->crtc_h != pstate->src_h >> 16)
-			intel_state->wm_config.sprites_scaled = true;
-	}
 
 	/* Is there platform-specific watermark information to calculate? */
 	if (dev_priv->display.compute_global_watermarks)
@@ -13522,7 +13493,6 @@ static int intel_atomic_commit(struct drm_device *dev,
 	}
 
 	drm_atomic_helper_swap_state(dev, state);
-	dev_priv->wm.config = intel_state->wm_config;
 	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
 
@@ -15274,7 +15244,6 @@ retry:
 	}
 
 	/* Write calculated watermark values back */
-	to_i915(dev)->wm.config = to_intel_atomic_state(state)->wm_config;
 	for_each_crtc_in_state(state, crtc, cstate, i) {
 		struct intel_crtc_state *cs = to_intel_crtc_state(cstate);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3abd394..a43da8e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -294,7 +294,6 @@ struct intel_atomic_state {
 	unsigned int min_pixclk[I915_MAX_PIPES];
 
 	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
-	struct intel_wm_config wm_config;
 
 	/*
 	 * Current watermarks can't be trusted during hardware readout, so
-- 
2.1.4

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

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

* ✗ Fi.CI.BAT: warning for Pre-calculate SKL-style atomic watermarks
  2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
                   ` (15 preceding siblings ...)
  2016-04-01  1:46 ` [PATCH 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state Matt Roper
@ 2016-04-01  9:36 ` Patchwork
  16 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2016-04-01  9:36 UTC (permalink / raw
  To: Matt Roper; +Cc: intel-gfx

== Series Details ==

Series: Pre-calculate SKL-style atomic watermarks
URL   : https://patchwork.freedesktop.org/series/5158/
State : warning

== Summary ==

Series 5158v1 Pre-calculate SKL-style atomic watermarks
http://patchwork.freedesktop.org/api/1.0/series/5158/revisions/1/mbox/

Test drv_module_reload_basic:
                skip       -> PASS       (skl-nuci5)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-a:
                pass       -> DMESG-WARN (skl-i7k-2)

bdw-nuci7        total:196  pass:184  dwarn:0   dfail:0   fail:0   skip:12 
bdw-ultra        total:196  pass:175  dwarn:0   dfail:0   fail:0   skip:21 
bsw-nuc-2        total:196  pass:159  dwarn:0   dfail:0   fail:0   skip:37 
byt-nuc          total:196  pass:161  dwarn:0   dfail:0   fail:0   skip:35 
hsw-brixbox      total:196  pass:174  dwarn:0   dfail:0   fail:0   skip:22 
hsw-gt2          total:1    pass:0    dwarn:0   dfail:0   fail:0   skip:0  
skl-i7k-2        total:196  pass:172  dwarn:1   dfail:0   fail:0   skip:23 
skl-nuci5        total:196  pass:185  dwarn:0   dfail:0   fail:0   skip:11 
snb-dellxps      total:58   pass:48   dwarn:0   dfail:0   fail:0   skip:9  

Results at /archive/results/CI_IGT_test/Patchwork_1771/

e8d1e8123ef907fc23b53554af9cb99c7f380fb9 drm-intel-nightly: 2016y-04m-01d-07h-26m-00s UTC integration manifest
42a9a414dc6849774f15e64bd0fc9f430e5ffaab drm/i915: Remove wm_config from dev_priv/intel_atomic_state
73c6b5b499d3f7935116986b4c76cbc40520ebd5 drm/i915/gen9: Reject display updates that exceed wm limitations
a202b3d05337a2a146337b7e1791cd2728084a39 drm/i915/gen9: Calculate watermarks during atomic 'check'
430af616cd83f70ed825545101d45facf895ca53 drm/i915/gen9: Propagate watermark calculation failures up the call chain
810ed52d63e0408f5e2a1044e3734e1cf36086f8 drm/i915/gen9: Use a bitmask to track dirty pipe watermarks
0113e600820079cad48bf16ad889a6202a565ace drm/i915/gen9: Allow watermark calculation on in-flight atomic state
011e10c6a2dbcd4e401d362ec4aaf9962732cd45 drm/i915/gen9: Calculate plane WM's from state
95b414b32840b6582f539286287adf635a730939 drm/i915/gen9: Drop re-allocation of DDB at atomic commit
a88f61662f33708ff259ac937ea32d4cdeb3f8da drm/i915/gen9: Compute DDB allocation at atomic check time
cd744977c4d0c8bc5478b8785e37b5a8e89ba93c drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state
3da06009c3643c86472aaf8509e50feaf0394f17 drm/i915: Ensure intel_state->active_crtcs is always set
3a7985f34a63e5a6873e11ca334568db74dfd870 drm/i915/gen9: Allow calculation of data rate for in-flight state
55e1f320ad17a6e04b26fc91ba3b7209f22c3c75 drm/i915/skl+: Use plane size for relative data rate calculation
2611a4351db67518706e1e384133c17bef37c077 drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/
99017ab2b073fe69467f09b18036222157abf59f drm/i915: Make skl_plane_relative_data_rate use passed CRTC state
2a16b40a85792ed4b372f30fb265e90b261aa7c1 drm/i915: Reorganize WM structs/unions in CRTC state

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

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

* Re: [PATCH 06/16] drm/i915: Ensure intel_state->active_crtcs is always set
  2016-04-01  1:46 ` [PATCH 06/16] drm/i915: Ensure intel_state->active_crtcs is always set Matt Roper
@ 2016-04-05  9:29   ` Maarten Lankhorst
  0 siblings, 0 replies; 28+ messages in thread
From: Maarten Lankhorst @ 2016-04-05  9:29 UTC (permalink / raw
  To: Matt Roper, intel-gfx

Op 01-04-16 om 03:46 schreef Matt Roper:
> We currently only setup intel_state->active_crtcs if we plan to modify
> it and write the modification back to dev_priv.  Let's ensure that
> this value is always valid, even when it isn't changing as part of an
> atomic transaction.
It should be noted that make a note that active_crtcs is not completely reliable when connection_mutex is not taken.
A parallel modeset may change this value. That said, looks like patch 9/16 fixes this.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state
  2016-04-01  1:46 ` [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state Matt Roper
@ 2016-04-05  9:35   ` Maarten Lankhorst
  2016-04-14  1:58     ` Matt Roper
  0 siblings, 1 reply; 28+ messages in thread
From: Maarten Lankhorst @ 2016-04-05  9:35 UTC (permalink / raw
  To: Matt Roper, intel-gfx

Op 01-04-16 om 03:46 schreef Matt Roper:
> We eventually want to calculate watermark values at atomic 'check' time
> instead of atomic 'commit' time so that any requested configurations
> that result in impossible watermark requirements are properly rejected.
> The first step along this path is to allocate the DDB at atomic 'check'
> time.  As we perform this transition, allow the main allocation function
> to operate successfully on either an in-flight state or an
> already-commited state.  Once we complete the transition in a future
> patch, we'll come back and remove the unnecessary logic for the
> already-committed case.
>
> Note one other minor change here...when working with the
> already-committed state, we pull the active CRTC's from
> hweight(dev_priv->active_crtcs) instead of
> dev_priv->wm.config.num_pipes_active.  The values should be equivalent,
> but dev_priv->wm.config is pretty much unused at this point and it would
> be nice to eventually remove it entirely.
> ---
>  drivers/gpu/drm/i915/i915_drv.h |  6 +++
>  drivers/gpu/drm/i915/intel_pm.c | 99 ++++++++++++++++++++++++++++++-----------
>  2 files changed, 78 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d3ebb2f..79f1974 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -318,6 +318,12 @@ struct i915_hotplug {
>  			    &dev->mode_config.plane_list,	\
>  			    base.head)
>  
> +#define for_each_intel_plane_mask(dev, intel_plane, plane_mask)		\
> +	list_for_each_entry(intel_plane, &dev->mode_config.plane_list,	\
> +			    base.head)					\
> +		for_each_if ((plane_mask) &				\
> +			     (1 << drm_plane_index(&intel_plane->base)))
> +
>  #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
>  	list_for_each_entry(intel_plane,				\
>  			    &(dev)->mode_config.plane_list,		\
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index e92513e..e0ca2b9 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2849,15 +2849,15 @@ skl_wm_plane_id(const struct intel_plane *plane)
>  static void
>  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  				   const struct intel_crtc_state *cstate,
> -				   const struct intel_wm_config *config,
> +				   const unsigned active_crtcs,
>  				   struct skl_ddb_entry *alloc /* out */)
>  {
> -	struct drm_crtc *for_crtc = cstate->base.crtc;
> -	struct drm_crtc *crtc;
> +	struct drm_crtc *crtc = cstate->base.crtc;
>  	unsigned int pipe_size, ddb_size;
> +	unsigned int num_active = hweight32(active_crtcs);
>  	int nth_active_pipe;
>  
> -	if (!cstate->base.active) {
> +	if (!cstate->base.active || WARN_ON(num_active == 0)) {
>  		alloc->start = 0;
>  		alloc->end = 0;
>  		return;
> @@ -2870,25 +2870,16 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  
>  	ddb_size -= 4; /* 4 blocks for bypass path allocation */
>  
> -	nth_active_pipe = 0;
> -	for_each_crtc(dev, crtc) {
> -		if (!to_intel_crtc(crtc)->active)
> -			continue;
> +	nth_active_pipe = hweight32(active_crtcs & (drm_crtc_mask(crtc) - 1));
>  
> -		if (crtc == for_crtc)
> -			break;
> -
> -		nth_active_pipe++;
> -	}
> -
> -	pipe_size = ddb_size / config->num_pipes_active;
> -	alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
> +	pipe_size = ddb_size / num_active;
> +	alloc->start = nth_active_pipe * ddb_size / num_active;
>  	alloc->end = alloc->start + pipe_size;
>  }
>  
> -static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
> +static unsigned int skl_cursor_allocation(const unsigned active_crtcs)
>  {
> -	if (config->num_pipes_active == 1)
> +	if (hweight32(active_crtcs) == 1)
>  		return 32;
>  
>  	return 8;
> @@ -3018,14 +3009,13 @@ skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
>  	return total_data_rate;
>  }
>  
> -static void
> +static int
>  skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		      struct skl_ddb_allocation *ddb /* out */)
>  {
>  	struct drm_crtc *crtc = cstate->base.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_wm_config *config = &dev_priv->wm.config;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_plane *intel_plane;
>  	enum pipe pipe = intel_crtc->pipe;
> @@ -3034,17 +3024,43 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	uint16_t minimum[I915_MAX_PLANES];
>  	uint16_t y_minimum[I915_MAX_PLANES];
>  	unsigned int total_data_rate;
> +	unsigned active_crtcs = 0;
>  
> -	skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
> +	if (!cstate->base.active) {
> +		ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
> +		memset(ddb->plane[pipe], 0,
> +		       I915_MAX_PLANES * sizeof(struct skl_ddb_entry));
> +		memset(ddb->y_plane[pipe], 0,
> +		       I915_MAX_PLANES * sizeof(struct skl_ddb_entry));
> +		return 0;
> +	}
> +
> +	/*
> +	 * TODO:  At the moment we might call this on either an in-flight CRTC
> +	 * state or an already-committed state, so look up the number of
> +	 * active CRTC's accordingly.  Eventually this will only be called
> +	 * on in-flight states and we'll be able to drop some of this extra
> +	 * logic.
> +	 */
> +	if (cstate->base.state) {
> +		struct intel_atomic_state *intel_state =
> +			to_intel_atomic_state(cstate->base.state);
> +
> +		active_crtcs = intel_state->active_crtcs;
> +	} else {
> +		active_crtcs = dev_priv->active_crtcs;
> +	}
> +
> +	skl_ddb_get_pipe_allocation_limits(dev, cstate, active_crtcs, alloc);
>  	alloc_size = skl_ddb_entry_size(alloc);
>  	if (alloc_size == 0) {
>  		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
>  		memset(&ddb->plane[pipe][PLANE_CURSOR], 0,
>  		       sizeof(ddb->plane[pipe][PLANE_CURSOR]));
> -		return;
> +		return 0;
>  	}
>  
> -	cursor_blocks = skl_cursor_allocation(config);
> +	cursor_blocks = skl_cursor_allocation(active_crtcs);
>  	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks;
>  	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
>  
> @@ -3054,15 +3070,30 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	/* 1. Allocate the mininum required blocks for each active plane */
>  	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
>  		struct drm_plane *plane = &intel_plane->base;
> +		struct drm_plane_state *pstate;
>  		struct drm_framebuffer *fb = plane->state->fb;
>  		int id = skl_wm_plane_id(intel_plane);
>  
> -		if (!to_intel_plane_state(plane->state)->visible)
> +		/*
> +		 * TODO: Remove support for already-committed state once we
> +		 * only allocate DDB on in-flight states.
> +		 */
> +		if (cstate->base.state) {
> +			pstate = drm_atomic_get_plane_state(cstate->base.state,
> +							    plane);
> +			if (IS_ERR(pstate))
> +				return PTR_ERR(pstate);
> +		} else {
> +			pstate = plane->state;
> +		}
> +
> +		if (!to_intel_plane_state(pstate)->visible)
>  			continue;
>  
>  		if (plane->type == DRM_PLANE_TYPE_CURSOR)
>  			continue;
>  
> +		fb = pstate->fb;
>  		minimum[id] = 8;
>  		alloc_size -= minimum[id];
>  		y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
> @@ -3078,13 +3109,26 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	total_data_rate = skl_get_total_relative_data_rate(cstate);
>  
>  	start = alloc->start;
> -	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +	for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) {
>  		struct drm_plane *plane = &intel_plane->base;
> -		struct drm_plane_state *pstate = intel_plane->base.state;
> +		struct drm_plane_state *pstate;
>  		unsigned int data_rate, y_data_rate;
>  		uint16_t plane_blocks, y_plane_blocks = 0;
>  		int id = skl_wm_plane_id(intel_plane);
>  
> +		/*
> +		 * TODO: Remove support for already-committed state once we
> +		 * only allocate DDB on in-flight states.
> +		 */
> +		if (cstate->base.state) {
> +			pstate = drm_atomic_get_plane_state(cstate->base.state,
> +							    plane);
>
Yuck again? :( No way around this by storing data rates for example?

Oh well, at least set cstate->base.planes_changed please.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time
  2016-04-01  1:46 ` [PATCH 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time Matt Roper
@ 2016-04-05  9:45   ` Maarten Lankhorst
  0 siblings, 0 replies; 28+ messages in thread
From: Maarten Lankhorst @ 2016-04-05  9:45 UTC (permalink / raw
  To: Matt Roper, intel-gfx

Op 01-04-16 om 03:46 schreef Matt Roper:
> Calculate the DDB blocks needed to satisfy the current atomic
> transaction at atomic check time.  This is a prerequisite to calculating
> SKL watermarks during the 'check' phase and rejecting any configurations
> that we can't find valid watermarks for.
>
> Due to the nature of DDB allocation, it's possible for the addition of a
> new CRTC to make the watermark configuration already in use on another,
> unchanged CRTC become invalid.  A change in which CRTC's are active
> triggers a recompute of the entire DDB, which unfortunately means we
> need to disallow any other atomic commits from racing with such an
> update.  If the active CRTC's change, we need to grab the lock on all
> CRTC's and run all CRTC's through their 'check' handler to recompute and
> re-check their per-CRTC DDB allocations.
>
> Note that with this patch we only compute the DDB allocation but we
> don't actually use the computed values during watermark programming yet.
> For ease of review/testing/bisecting, we still recompute the DDB at
> watermark programming time and just WARN() if it doesn't match the
> precomputed values.  A future patch will switch over to using the
> precomputed values once we're sure they're being properly computed.
>
> Another clarifying note:  DDB allocation itself shouldn't ever fail with
> the algorithm we use today (i.e., we have enough DDB blocks on BXT to
> support the minimum needs of the worst-case scenario of every pipe/plane
> enabled at full size).  However the watermarks calculations based on the
> DDB may fail and we'll be moving those to the atomic check as well in
> future patches.
>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  5 ++++
>  drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h     |  3 ++
>  drivers/gpu/drm/i915/intel_pm.c      | 53 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 79 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 79f1974..35cebd4 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -333,6 +333,10 @@ struct i915_hotplug {
>  #define for_each_intel_crtc(dev, intel_crtc) \
>  	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
>  
> +#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \
> +	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) \
> +		for_each_if ((crtc_mask) & (1 << drm_crtc_index(&intel_crtc->base)))
> +
>  #define for_each_intel_encoder(dev, intel_encoder)		\
>  	list_for_each_entry(intel_encoder,			\
>  			    &(dev)->mode_config.encoder_list,	\
> @@ -587,6 +591,7 @@ struct drm_i915_display_funcs {
>  				       struct intel_crtc_state *newstate);
>  	void (*initial_watermarks)(struct intel_crtc_state *cstate);
>  	void (*optimize_watermarks)(struct intel_crtc_state *cstate);
> +	int (*compute_global_watermarks)(struct drm_atomic_state *state);
>  	void (*update_wm)(struct drm_crtc *crtc);
>  	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
>  	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ab1fc3d..6bf2ede 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13230,6 +13230,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  static void calc_watermark_data(struct drm_atomic_state *state)
>  {
>  	struct drm_device *dev = state->dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *cstate;
> @@ -13259,6 +13260,10 @@ static void calc_watermark_data(struct drm_atomic_state *state)
>  		    pstate->crtc_h != pstate->src_h >> 16)
>  			intel_state->wm_config.sprites_scaled = true;
>  	}
> +
> +	/* Is there platform-specific watermark information to calculate? */
> +	if (dev_priv->display.compute_global_watermarks)
> +		dev_priv->display.compute_global_watermarks(state);
>  }
>  
>  /**
> @@ -13631,6 +13636,19 @@ static int intel_atomic_commit(struct drm_device *dev,
>  			modeset_put_power_domains(dev_priv, put_domains[i]);
>  	}
>  
> +	/*
> +	 * Temporary sanity check: make sure our pre-computed DDB matches the
> +	 * one we actually wind up programming.
> +	 *
> +	 * Not a great place to put this, but the easiest place we have access
> +	 * to both the pre-computed and final DDB's; we'll be removing this
> +	 * check in the next patch anyway.
> +	 */
> +	WARN(IS_GEN9(dev) &&
> +	     memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
> +		    sizeof(intel_state->ddb)),
> +	     "Pre-computed DDB does not match final DDB!\n");
> +
>  	if (intel_state->modeset)
>  		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 3b9c084..483261c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -301,6 +301,9 @@ struct intel_atomic_state {
>  	 * don't bother calculating intermediate watermarks.
>  	 */
>  	bool skip_intermediate_wm;
> +
> +	/* Gen9+ only */
> +	struct skl_ddb_allocation ddb;
>  };
>  
>  struct intel_plane_state {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index e0ca2b9..8e283cf 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3736,6 +3736,58 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
>  
>  }
>  
> +static int
> +skl_compute_ddb(struct drm_atomic_state *state)
> +{
> +	struct drm_device *dev = state->dev;
> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> +	struct intel_crtc *intel_crtc;
> +	unsigned realloc_pipes = intel_state->active_crtcs;
> +	int ret;
> +
> +	/*
> +	 * If the modeset changes which CRTC's are active, we need to
> +	 * recompute the DDB allocation for *all* active pipes, even
> +	 * those that weren't otherwise being modified in any way by this
> +	 * atomic commit.  Due to the shrinking of the per-pipe allocations
> +	 * when new active CRTC's are added, it's possible for a pipe that
> +	 * we were already using and aren't changing at all here to suddenly
> +	 * become invalid if its DDB needs exceeds its new allocation.
> +	 *
> +	 * Note that if we wind up doing a full DDB recompute, we can't let
> +	 * any other display updates race with this transaction, so we need
> +	 * to grab the lock on *all* CRTC's.
> +	 */
> +	if (intel_state->active_crtcs != to_i915(dev)->active_crtcs)
> +		realloc_pipes = ~0;
> +
As I noted in the previous patch you're not allowed to look at active_crtcs like this.

I would just go with if (intel_state->modeset here), and look only at crtcs part of the state. Not at intel_state->active_crtcs.

If the ddb allocation for any crtc part of the state changes then you would add all acive crtcs. Don't be afraid to just lock all, including the disabled crtcs. :)

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

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

* Re: [PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state
  2016-04-01  1:46 ` [PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state Matt Roper
@ 2016-04-05  9:52   ` Maarten Lankhorst
  0 siblings, 0 replies; 28+ messages in thread
From: Maarten Lankhorst @ 2016-04-05  9:52 UTC (permalink / raw
  To: Matt Roper, intel-gfx

Op 01-04-16 om 03:46 schreef Matt Roper:
> In an upcoming patch we'll move this calculation to the atomic 'check'
> phase so that the display update can be rejected early if no valid
> watermark programming is possible.
>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h | 21 +++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_pm.c  | 31 +++++++++++++++++++------------
>  2 files changed, 40 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 483261c..6471f69 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1667,6 +1667,27 @@ intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
>  	return to_intel_plane_state(plane_state);
>  }
>  
> +/*
> + * If cstate is in-flight, return in-flight plane state, otherwise
> + * return committed plane state.
> + */
> +static inline struct intel_plane_state *
> +intel_pstate_for_cstate_plane(struct intel_crtc_state *cstate,
> +			      struct intel_plane *plane)
> +{
> +	struct drm_atomic_state *state = cstate->base.state;
> +	struct drm_plane_state *pstate;
> +
> +	if (state == NULL)
> +		return to_intel_plane_state(plane->base.state);
> +
> +	pstate = drm_atomic_get_plane_state(state, &plane->base);
> +
> +	return to_intel_plane_state(pstate);
> +}
> +
Don't create a helper please, this should only be done when transitioning code situations.

plane->base.state might not be the right state when we support more than 1 pending atomic commit.

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

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

* Re: [PATCH 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state
  2016-04-01  1:46 ` [PATCH 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state Matt Roper
@ 2016-04-05 10:14   ` Maarten Lankhorst
  0 siblings, 0 replies; 28+ messages in thread
From: Maarten Lankhorst @ 2016-04-05 10:14 UTC (permalink / raw
  To: Matt Roper, intel-gfx

Op 01-04-16 om 03:46 schreef Matt Roper:
> We calculate the watermark config into intel_atomic_state and then save
> it into dev_priv, but never actually use it from there.  This is
> left-over from some early ILK-style watermark programming designs that
> got changed over time.
For patch 1-5, 7, and 12-16:

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Rest just needs to be reworked to zap pstate_for_cstate_plane and mentions of active_crtcs.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check'
  2016-04-01  1:46 ` [PATCH 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check' Matt Roper
@ 2016-04-05 13:01   ` Patrik Jakobsson
  0 siblings, 0 replies; 28+ messages in thread
From: Patrik Jakobsson @ 2016-04-05 13:01 UTC (permalink / raw
  To: Matt Roper; +Cc: intel-gfx

On Thu, Mar 31, 2016 at 06:46:36PM -0700, Matt Roper wrote:
> Moving watermark calculation into the check phase will allow us to to
> reject display configurations for which there are no valid watermark
> values before we start trying to program the hardware (although those
> tests will come in a subsequent patch).
> 
> Another advantage of moving this calculation to the check phase is that
> we can calculate the watermarks in a single shot as part of the atomic
> transaction.  The watermark interfaces we inherited from our legacy
> modesetting days are a bit broken in the atomic design because they use
> per-crtc entry points but actually re-calculate and re-program something
> that is really more of a global state.  That worked okay in the legacy
> modesetting world because operations only ever updated a single CRTC at
> a time.  However in the atomic world, a transaction can involve multiple
> CRTC's, which means we wind up computing and programming the watermarks
> NxN times (where N is the number of CRTC's involved).  With this patch
> we eliminate the redundant re-calculation of watermark data for atomic
> states (which was the cause of the WARN_ON(!wm_changed) problems that
> have plagued us for a while).

This one also fixes: https://bugs.freedesktop.org/show_bug.cgi?id=92181

> 
> We still need to work on the 'commit' side of watermark handling so that
> we aren't doing redundant NxN programming of watermarks, but that's
> content for future patches.
> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c |   2 +-
>  drivers/gpu/drm/i915/intel_drv.h     |   2 +-
>  drivers/gpu/drm/i915/intel_pm.c      | 141 +++++++++++++----------------------
>  3 files changed, 55 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c514549..f1bea9f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13523,7 +13523,7 @@ static int intel_atomic_commit(struct drm_device *dev,
>  
>  	drm_atomic_helper_swap_state(dev, state);
>  	dev_priv->wm.config = intel_state->wm_config;
> -	dev_priv->wm.skl_results.ddb = intel_state->ddb;
> +	dev_priv->wm.skl_results = intel_state->wm_results;
>  	intel_shared_dpll_commit(state);
>  
>  	if (intel_state->modeset) {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 6471f69..3abd394 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -303,7 +303,7 @@ struct intel_atomic_state {
>  	bool skip_intermediate_wm;
>  
>  	/* Gen9+ only */
> -	struct skl_ddb_allocation ddb;
> +	struct skl_wm_values wm_results;
>  };
>  
>  struct intel_plane_state {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 1bef89a..e4de5aa 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3187,23 +3187,6 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
>  	return ret;
>  }
>  
> -static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
> -				       const struct intel_crtc *intel_crtc)
> -{
> -	struct drm_device *dev = intel_crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> -
> -	/*
> -	 * If ddb allocation of pipes changed, it may require recalculation of
> -	 * watermarks
> -	 */
> -	if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
> -		return true;
> -
> -	return false;
> -}
> -
>  static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  				struct intel_crtc_state *cstate,
>  				struct intel_plane_state *intel_pstate,
> @@ -3654,72 +3637,16 @@ static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
>  	else
>  		*changed = true;
>  
> -	intel_crtc->wm.active.skl = *pipe_wm;
> -
>  	return 0;
>  }
>  
> -static void skl_update_other_pipe_wm(struct drm_device *dev,
> -				     struct drm_crtc *crtc,
> -				     struct skl_wm_values *r)
> -{
> -	struct intel_crtc *intel_crtc;
> -	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
> -
> -	/*
> -	 * If the WM update hasn't changed the allocation for this_crtc (the
> -	 * crtc we are currently computing the new WM values for), other
> -	 * enabled crtcs will keep the same allocation and we don't need to
> -	 * recompute anything for them.
> -	 */
> -	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
> -		return;
> -
> -	/*
> -	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
> -	 * other active pipes need new DDB allocation and WM values.
> -	 */
> -	for_each_intel_crtc(dev, intel_crtc) {
> -		struct skl_pipe_wm pipe_wm = {};
> -		bool wm_changed;
> -
> -		if (this_crtc->pipe == intel_crtc->pipe)
> -			continue;
> -
> -		if (!intel_crtc->active)
> -			continue;
> -
> -		skl_update_pipe_wm(intel_crtc->base.state,
> -				   &r->ddb, &pipe_wm, &wm_changed);
> -
> -		/*
> -		 * If we end up re-computing the other pipe WM values, it's
> -		 * because it was really needed, so we expect the WM values to
> -		 * be different.
> -		 */
> -		WARN_ON(!wm_changed);
> -
> -		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
> -		r->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
> -	}
> -}
> -
> -static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
> -{
> -	watermarks->wm_linetime[pipe] = 0;
> -	memset(watermarks->plane[pipe], 0,
> -	       sizeof(uint32_t) * 8 * I915_MAX_PLANES);
> -	memset(watermarks->plane_trans[pipe],
> -	       0, sizeof(uint32_t) * I915_MAX_PLANES);
> -	watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
> -}
> -
>  static int
>  skl_compute_ddb(struct drm_atomic_state *state)
>  {
>  	struct drm_device *dev = state->dev;
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct intel_crtc *intel_crtc;
> +	struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
>  	unsigned realloc_pipes = intel_state->active_crtcs;
>  	int ret;
>  
> @@ -3736,8 +3663,10 @@ skl_compute_ddb(struct drm_atomic_state *state)
>  	 * any other display updates race with this transaction, so we need
>  	 * to grab the lock on *all* CRTC's.
>  	 */
> -	if (intel_state->active_crtcs != to_i915(dev)->active_crtcs)
> +	if (intel_state->active_crtcs != to_i915(dev)->active_crtcs) {
>  		realloc_pipes = ~0;
> +		intel_state->wm_results.dirty_pipes = ~0;
> +	}
>  
>  	for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
>  		struct intel_crtc_state *cstate;
> @@ -3746,7 +3675,7 @@ skl_compute_ddb(struct drm_atomic_state *state)
>  		if (IS_ERR(cstate))
>  			return PTR_ERR(cstate);
>  
> -		ret = skl_allocate_pipe_ddb(cstate, &intel_state->ddb);
> +		ret = skl_allocate_pipe_ddb(cstate, ddb);
>  		if (ret)
>  			return ret;
>  	}
> @@ -3757,12 +3686,53 @@ skl_compute_ddb(struct drm_atomic_state *state)
>  static int
>  skl_compute_wm(struct drm_atomic_state *state)
>  {
> -	int ret;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *cstate;
> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> +	struct skl_wm_values *results = &intel_state->wm_results;
> +	struct skl_pipe_wm *pipe_wm;
> +	bool changed;
> +	int ret, i;
> +
> +	/* Clear all dirty flags */
> +	results->dirty_pipes = 0;
>  
>  	ret = skl_compute_ddb(state);
>  	if (ret)
>  		return ret;
>  
> +	/*
> +	 * Calculate WM's for all pipes that are part of this transaction.
> +	 * Note that the DDB allocation above may have added more CRTC's that
> +	 * weren't otherwise being modified (and set bits in dirty_pipes) if
> +	 * pipe allocations had to change.
> +	 *
> +	 * FIXME:  Now that we're doing this in the atomic check phase, we
> +	 * should allow skl_update_pipe_wm() to return failure in cases where
> +	 * no suitable watermark values can be found.
> +	 */
> +	for_each_crtc_in_state(state, crtc, cstate, i) {
> +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +		struct intel_crtc_state *intel_cstate =
> +			to_intel_crtc_state(cstate);
> +
> +		pipe_wm = &intel_cstate->wm.skl.optimal;
> +		ret = skl_update_pipe_wm(cstate, &results->ddb, pipe_wm,
> +					 &changed);
> +		if (ret)
> +			return ret;
> +
> +		if (changed)
> +			results->dirty_pipes |= drm_crtc_mask(crtc);
> +
> +		if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
> +			/* This pipe's WM's did not change */
> +			continue;
> +
> +		intel_cstate->update_wm_pre = true;
> +		skl_compute_wm_results(crtc->dev, pipe_wm, results, intel_crtc);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -3774,26 +3744,21 @@ static void skl_update_wm(struct drm_crtc *crtc)
>  	struct skl_wm_values *results = &dev_priv->wm.skl_results;
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
>  	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
> -	bool wm_changed;
>  
> -	/* Clear all dirty flags */
> -	results->dirty_pipes = 0;
> -
> -	skl_clear_wm(results, intel_crtc->pipe);
> -
> -	skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm, &wm_changed);
> -	if (!wm_changed);
> +	if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
>  		return;
>  
> -	skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
> -	results->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
> +	intel_crtc->wm.active.skl = *pipe_wm;
> +
> +	mutex_lock(&dev_priv->wm.wm_mutex);
>  
> -	skl_update_other_pipe_wm(dev, crtc, results);
>  	skl_write_wm_values(dev_priv, results);
>  	skl_flush_wm_values(dev_priv, results);
>  
>  	/* store the new configuration */
>  	dev_priv->wm.skl_hw = *results;
> +
> +	mutex_unlock(&dev_priv->wm.wm_mutex);
>  }
>  
>  static void ilk_compute_wm_config(struct drm_device *dev,
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
---
Intel Sweden AB Registered Office: Knarrarnasgatan 15, 164 40 Kista, Stockholm, Sweden Registration Number: 556189-6027 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation
  2016-04-01  1:46 ` [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation Matt Roper
@ 2016-04-06 15:09   ` Imre Deak
  2016-04-06 18:05     ` Matt Roper
  0 siblings, 1 reply; 28+ messages in thread
From: Imre Deak @ 2016-04-06 15:09 UTC (permalink / raw
  To: Matt Roper, intel-gfx

On to, 2016-03-31 at 18:46 -0700, Matt Roper wrote:
> From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>
> 
> Use plane size for relative data rate calculation. don't always use
> pipe source width & height.
> adjust height & width according to rotation.
> use plane size for watermark calculations also.
> 
> v2: Address Matt's comments.
>     Use intel_plane_state->visible to avoid divide-by-zero error.
>     Where FB was present but not visible so causing total data rate
> to
>     be zero, hence divide-by-zero.
> 
> Cc: matthew.d.roper@intel.com
> Signed-off-by: Kumar, Mahesh <mahesh1.kumar@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>

Reference: https://bugs.freedesktop.org/show_bug.cgi?id=93917
Reference: https://bugs.freedesktop.org/show_bug.cgi?id=94044

This patch fixed a screen corruption problem for me with an eDP + DP
config. It somehow made worse by moving the cursor around and I can get
rid of it by switching of the cursor plane.

Matt any chance of getting this merged separately from the rest?

--Imre

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 41 ++++++++++++++++++++++++++++---
> ----------
>  1 file changed, 28 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index c970c4e..1c3f772 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2937,24 +2937,28 @@ skl_plane_relative_data_rate(const struct
> intel_crtc_state *cstate,
>  			     const struct drm_plane_state *pstate,
>  			     int y)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(cstate-
> >base.crtc);
> +	struct intel_plane_state *intel_pstate =
> to_intel_plane_state(pstate);
>  	struct drm_framebuffer *fb = pstate->fb;
> +	uint32_t width = 0, height = 0;
> +
> +	width = drm_rect_width(&intel_pstate->src) >> 16;
> +	height = drm_rect_height(&intel_pstate->src) >> 16;
> +
> +	if (intel_rotation_90_or_270(pstate->rotation))
> +		swap(width, height);
>  
>  	/* for planar format */
>  	if (fb->pixel_format == DRM_FORMAT_NV12) {
>  		if (y)  /* y-plane data rate */
> -			return intel_crtc->config->pipe_src_w *
> -				intel_crtc->config->pipe_src_h *
> +			return width * height *
>  				drm_format_plane_cpp(fb-
> >pixel_format, 0);
>  		else    /* uv-plane data rate */
> -			return (intel_crtc->config->pipe_src_w/2) *
> -				(intel_crtc->config->pipe_src_h/2) *
> +			return (width / 2) * (height / 2) *
>  				drm_format_plane_cpp(fb-
> >pixel_format, 1);
>  	}
>  
>  	/* for packed formats */
> -	return cstate->pipe_src_w * cstate->pipe_src_h *
> -		drm_format_plane_cpp(fb->pixel_format, 0);
> +	return width * height * drm_format_plane_cpp(fb-
> >pixel_format, 0);
>  }
>  
>  /*
> @@ -3033,8 +3037,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state
> *cstate,
>  		struct drm_framebuffer *fb = plane->state->fb;
>  		int id = skl_wm_plane_id(intel_plane);
>  
> -		if (fb == NULL)
> +		if (!to_intel_plane_state(plane->state)->visible)
>  			continue;
> +
>  		if (plane->type == DRM_PLANE_TYPE_CURSOR)
>  			continue;
>  
> @@ -3060,7 +3065,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state
> *cstate,
>  		uint16_t plane_blocks, y_plane_blocks = 0;
>  		int id = skl_wm_plane_id(intel_plane);
>  
> -		if (pstate->fb == NULL)
> +		if (!to_intel_plane_state(pstate)->visible)
>  			continue;
>  		if (plane->type == DRM_PLANE_TYPE_CURSOR)
>  			continue;
> @@ -3183,26 +3188,36 @@ static bool skl_compute_plane_wm(const struct
> drm_i915_private *dev_priv,
>  {
>  	struct drm_plane *plane = &intel_plane->base;
>  	struct drm_framebuffer *fb = plane->state->fb;
> +	struct intel_plane_state *intel_pstate =
> +					to_intel_plane_state(plane-
> >state);
>  	uint32_t latency = dev_priv->wm.skl_latency[level];
>  	uint32_t method1, method2;
>  	uint32_t plane_bytes_per_line, plane_blocks_per_line;
>  	uint32_t res_blocks, res_lines;
>  	uint32_t selected_result;
>  	uint8_t cpp;
> +	uint32_t width = 0, height = 0;
>  
> -	if (latency == 0 || !cstate->base.active || !fb)
> +	if (latency == 0 || !cstate->base.active || !intel_pstate-
> >visible)
>  		return false;
>  
> +	width = drm_rect_width(&intel_pstate->src) >> 16;
> +	height = drm_rect_height(&intel_pstate->src) >> 16;
> +
> +	if (intel_rotation_90_or_270(plane->state->rotation))
> +		swap(width, height);
> +
>  	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
>  	method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
>  				 cpp, latency);
>  	method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
>  				 cstate-
> >base.adjusted_mode.crtc_htotal,
> -				 cstate->pipe_src_w,
> -				 cpp, fb->modifier[0],
> +				 width,
> +				 cpp,
> +				 fb->modifier[0],
>  				 latency);
>  
> -	plane_bytes_per_line = cstate->pipe_src_w * cpp;
> +	plane_bytes_per_line = width * cpp;
>  	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line,
> 512);
>  
>  	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation
  2016-04-06 15:09   ` Imre Deak
@ 2016-04-06 18:05     ` Matt Roper
  0 siblings, 0 replies; 28+ messages in thread
From: Matt Roper @ 2016-04-06 18:05 UTC (permalink / raw
  To: Imre Deak; +Cc: intel-gfx

On Wed, Apr 06, 2016 at 06:09:00PM +0300, Imre Deak wrote:
> On to, 2016-03-31 at 18:46 -0700, Matt Roper wrote:
> > From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>
> > 
> > Use plane size for relative data rate calculation. don't always use
> > pipe source width & height.
> > adjust height & width according to rotation.
> > use plane size for watermark calculations also.
> > 
> > v2: Address Matt's comments.
> >     Use intel_plane_state->visible to avoid divide-by-zero error.
> >     Where FB was present but not visible so causing total data rate
> > to
> >     be zero, hence divide-by-zero.
> > 
> > Cc: matthew.d.roper@intel.com
> > Signed-off-by: Kumar, Mahesh <mahesh1.kumar@intel.com>
> > Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> 
> Reference: https://bugs.freedesktop.org/show_bug.cgi?id=93917
> Reference: https://bugs.freedesktop.org/show_bug.cgi?id=94044
> 
> This patch fixed a screen corruption problem for me with an eDP + DP
> config. It somehow made worse by moving the cursor around and I can get
> rid of it by switching of the cursor plane.
> 
> Matt any chance of getting this merged separately from the rest?
> 
> --Imre

Yep, I'd already reviewed this when Mahesh wrote it a while back so I
just ran this through CI in isolation and it came up clean.  Added
a Cc: -fixes and pushed to dinq.


Matt

> 
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 41 ++++++++++++++++++++++++++++---
> > ----------
> >  1 file changed, 28 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index c970c4e..1c3f772 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2937,24 +2937,28 @@ skl_plane_relative_data_rate(const struct
> > intel_crtc_state *cstate,
> >  			     const struct drm_plane_state *pstate,
> >  			     int y)
> >  {
> > -	struct intel_crtc *intel_crtc = to_intel_crtc(cstate-
> > >base.crtc);
> > +	struct intel_plane_state *intel_pstate =
> > to_intel_plane_state(pstate);
> >  	struct drm_framebuffer *fb = pstate->fb;
> > +	uint32_t width = 0, height = 0;
> > +
> > +	width = drm_rect_width(&intel_pstate->src) >> 16;
> > +	height = drm_rect_height(&intel_pstate->src) >> 16;
> > +
> > +	if (intel_rotation_90_or_270(pstate->rotation))
> > +		swap(width, height);
> >  
> >  	/* for planar format */
> >  	if (fb->pixel_format == DRM_FORMAT_NV12) {
> >  		if (y)  /* y-plane data rate */
> > -			return intel_crtc->config->pipe_src_w *
> > -				intel_crtc->config->pipe_src_h *
> > +			return width * height *
> >  				drm_format_plane_cpp(fb-
> > >pixel_format, 0);
> >  		else    /* uv-plane data rate */
> > -			return (intel_crtc->config->pipe_src_w/2) *
> > -				(intel_crtc->config->pipe_src_h/2) *
> > +			return (width / 2) * (height / 2) *
> >  				drm_format_plane_cpp(fb-
> > >pixel_format, 1);
> >  	}
> >  
> >  	/* for packed formats */
> > -	return cstate->pipe_src_w * cstate->pipe_src_h *
> > -		drm_format_plane_cpp(fb->pixel_format, 0);
> > +	return width * height * drm_format_plane_cpp(fb-
> > >pixel_format, 0);
> >  }
> >  
> >  /*
> > @@ -3033,8 +3037,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state
> > *cstate,
> >  		struct drm_framebuffer *fb = plane->state->fb;
> >  		int id = skl_wm_plane_id(intel_plane);
> >  
> > -		if (fb == NULL)
> > +		if (!to_intel_plane_state(plane->state)->visible)
> >  			continue;
> > +
> >  		if (plane->type == DRM_PLANE_TYPE_CURSOR)
> >  			continue;
> >  
> > @@ -3060,7 +3065,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state
> > *cstate,
> >  		uint16_t plane_blocks, y_plane_blocks = 0;
> >  		int id = skl_wm_plane_id(intel_plane);
> >  
> > -		if (pstate->fb == NULL)
> > +		if (!to_intel_plane_state(pstate)->visible)
> >  			continue;
> >  		if (plane->type == DRM_PLANE_TYPE_CURSOR)
> >  			continue;
> > @@ -3183,26 +3188,36 @@ static bool skl_compute_plane_wm(const struct
> > drm_i915_private *dev_priv,
> >  {
> >  	struct drm_plane *plane = &intel_plane->base;
> >  	struct drm_framebuffer *fb = plane->state->fb;
> > +	struct intel_plane_state *intel_pstate =
> > +					to_intel_plane_state(plane-
> > >state);
> >  	uint32_t latency = dev_priv->wm.skl_latency[level];
> >  	uint32_t method1, method2;
> >  	uint32_t plane_bytes_per_line, plane_blocks_per_line;
> >  	uint32_t res_blocks, res_lines;
> >  	uint32_t selected_result;
> >  	uint8_t cpp;
> > +	uint32_t width = 0, height = 0;
> >  
> > -	if (latency == 0 || !cstate->base.active || !fb)
> > +	if (latency == 0 || !cstate->base.active || !intel_pstate-
> > >visible)
> >  		return false;
> >  
> > +	width = drm_rect_width(&intel_pstate->src) >> 16;
> > +	height = drm_rect_height(&intel_pstate->src) >> 16;
> > +
> > +	if (intel_rotation_90_or_270(plane->state->rotation))
> > +		swap(width, height);
> > +
> >  	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> >  	method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
> >  				 cpp, latency);
> >  	method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
> >  				 cstate-
> > >base.adjusted_mode.crtc_htotal,
> > -				 cstate->pipe_src_w,
> > -				 cpp, fb->modifier[0],
> > +				 width,
> > +				 cpp,
> > +				 fb->modifier[0],
> >  				 latency);
> >  
> > -	plane_bytes_per_line = cstate->pipe_src_w * cpp;
> > +	plane_bytes_per_line = width * cpp;
> >  	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line,
> > 512);
> >  
> >  	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||

-- 
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] 28+ messages in thread

* Re: [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state
  2016-04-05  9:35   ` Maarten Lankhorst
@ 2016-04-14  1:58     ` Matt Roper
  2016-04-18 12:56       ` Maarten Lankhorst
  0 siblings, 1 reply; 28+ messages in thread
From: Matt Roper @ 2016-04-14  1:58 UTC (permalink / raw
  To: Maarten Lankhorst; +Cc: intel-gfx

On Tue, Apr 05, 2016 at 11:35:31AM +0200, Maarten Lankhorst wrote:
> Op 01-04-16 om 03:46 schreef Matt Roper:
> > We eventually want to calculate watermark values at atomic 'check' time
> > instead of atomic 'commit' time so that any requested configurations
> > that result in impossible watermark requirements are properly rejected.
> > The first step along this path is to allocate the DDB at atomic 'check'
> > time.  As we perform this transition, allow the main allocation function
> > to operate successfully on either an in-flight state or an
> > already-commited state.  Once we complete the transition in a future
> > patch, we'll come back and remove the unnecessary logic for the
> > already-committed case.
> >
> > Note one other minor change here...when working with the
> > already-committed state, we pull the active CRTC's from
> > hweight(dev_priv->active_crtcs) instead of
> > dev_priv->wm.config.num_pipes_active.  The values should be equivalent,
> > but dev_priv->wm.config is pretty much unused at this point and it would
> > be nice to eventually remove it entirely.
> > ---
...
> > @@ -3078,13 +3109,26 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  	total_data_rate = skl_get_total_relative_data_rate(cstate);
> >  
> >  	start = alloc->start;
> > -	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> > +	for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) {
> >  		struct drm_plane *plane = &intel_plane->base;
> > -		struct drm_plane_state *pstate = intel_plane->base.state;
> > +		struct drm_plane_state *pstate;
> >  		unsigned int data_rate, y_data_rate;
> >  		uint16_t plane_blocks, y_plane_blocks = 0;
> >  		int id = skl_wm_plane_id(intel_plane);
> >  
> > +		/*
> > +		 * TODO: Remove support for already-committed state once we
> > +		 * only allocate DDB on in-flight states.
> > +		 */
> > +		if (cstate->base.state) {
> > +			pstate = drm_atomic_get_plane_state(cstate->base.state,
> > +							    plane);
> >
> Yuck again? :( No way around this by storing data rates for example?

Is there a reason to try to avoid grabbing the plane state here?  If we
get here, then we already have the CRTC lock, so we're not preventing
any potential for parallel updates of this plane (at least not on Intel
hardware where planes are tied to the CRTC).

> Oh well, at least set cstate->base.planes_changed please.

I'm not sure I follow this one.  We're using pstate in a read-only
manner so nothing we're doing here should necessitate programming planes
as far as I can see.


Matt


-- 
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] 28+ messages in thread

* Re: [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state
  2016-04-14  1:58     ` Matt Roper
@ 2016-04-18 12:56       ` Maarten Lankhorst
  0 siblings, 0 replies; 28+ messages in thread
From: Maarten Lankhorst @ 2016-04-18 12:56 UTC (permalink / raw
  To: Matt Roper; +Cc: intel-gfx

Op 14-04-16 om 03:58 schreef Matt Roper:
> On Tue, Apr 05, 2016 at 11:35:31AM +0200, Maarten Lankhorst wrote:
>> Op 01-04-16 om 03:46 schreef Matt Roper:
>>> We eventually want to calculate watermark values at atomic 'check' time
>>> instead of atomic 'commit' time so that any requested configurations
>>> that result in impossible watermark requirements are properly rejected.
>>> The first step along this path is to allocate the DDB at atomic 'check'
>>> time.  As we perform this transition, allow the main allocation function
>>> to operate successfully on either an in-flight state or an
>>> already-commited state.  Once we complete the transition in a future
>>> patch, we'll come back and remove the unnecessary logic for the
>>> already-committed case.
>>>
>>> Note one other minor change here...when working with the
>>> already-committed state, we pull the active CRTC's from
>>> hweight(dev_priv->active_crtcs) instead of
>>> dev_priv->wm.config.num_pipes_active.  The values should be equivalent,
>>> but dev_priv->wm.config is pretty much unused at this point and it would
>>> be nice to eventually remove it entirely.
>>> ---
> ...
>>> @@ -3078,13 +3109,26 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>>  	total_data_rate = skl_get_total_relative_data_rate(cstate);
>>>  
>>>  	start = alloc->start;
>>> -	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
>>> +	for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) {
>>>  		struct drm_plane *plane = &intel_plane->base;
>>> -		struct drm_plane_state *pstate = intel_plane->base.state;
>>> +		struct drm_plane_state *pstate;
>>>  		unsigned int data_rate, y_data_rate;
>>>  		uint16_t plane_blocks, y_plane_blocks = 0;
>>>  		int id = skl_wm_plane_id(intel_plane);
>>>  
>>> +		/*
>>> +		 * TODO: Remove support for already-committed state once we
>>> +		 * only allocate DDB on in-flight states.
>>> +		 */
>>> +		if (cstate->base.state) {
>>> +			pstate = drm_atomic_get_plane_state(cstate->base.state,
>>> +							    plane);
>>>
>> Yuck again? :( No way around this by storing data rates for example?
> Is there a reason to try to avoid grabbing the plane state here?  If we
> get here, then we already have the CRTC lock, so we're not preventing
> any potential for parallel updates of this plane (at least not on Intel
> hardware where planes are tied to the CRTC).
If you don't have to, you don't want to grab the plane state. It's probably fine to do so temporarily, but a solution
like for ILK would be better eventually. :)
>> Oh well, at least set cstate->base.planes_changed please.
> I'm not sure I follow this one.  We're using pstate in a read-only
> manner so nothing we're doing here should necessitate programming planes
> as far as I can see.
Just being part of the state is enough. intel_prepare_plane_fb will be called on those planes,
so with my async unpin patch series you need to set the flag or you may not have async unpins, resulting in errors much later on when the fb is freed.

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

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

end of thread, other threads:[~2016-04-18 12:56 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-01  1:46 [PATCH 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
2016-04-01  1:46 ` [PATCH 01/16] drm/i915: Reorganize WM structs/unions in CRTC state Matt Roper
2016-04-01  1:46 ` [PATCH 02/16] drm/i915: Make skl_plane_relative_data_rate use passed " Matt Roper
2016-04-01  1:46 ` [PATCH 03/16] drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/ Matt Roper
2016-04-01  1:46 ` [PATCH 04/16] drm/i915/skl+: Use plane size for relative data rate calculation Matt Roper
2016-04-06 15:09   ` Imre Deak
2016-04-06 18:05     ` Matt Roper
2016-04-01  1:46 ` [PATCH 05/16] drm/i915/gen9: Allow calculation of data rate for in-flight state Matt Roper
2016-04-01  1:46 ` [PATCH 06/16] drm/i915: Ensure intel_state->active_crtcs is always set Matt Roper
2016-04-05  9:29   ` Maarten Lankhorst
2016-04-01  1:46 ` [PATCH 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state Matt Roper
2016-04-05  9:35   ` Maarten Lankhorst
2016-04-14  1:58     ` Matt Roper
2016-04-18 12:56       ` Maarten Lankhorst
2016-04-01  1:46 ` [PATCH 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time Matt Roper
2016-04-05  9:45   ` Maarten Lankhorst
2016-04-01  1:46 ` [PATCH 09/16] drm/i915/gen9: Drop re-allocation of DDB at atomic commit Matt Roper
2016-04-01  1:46 ` [PATCH 10/16] drm/i915/gen9: Calculate plane WM's from state Matt Roper
2016-04-01  1:46 ` [PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state Matt Roper
2016-04-05  9:52   ` Maarten Lankhorst
2016-04-01  1:46 ` [PATCH 12/16] drm/i915/gen9: Use a bitmask to track dirty pipe watermarks Matt Roper
2016-04-01  1:46 ` [PATCH 13/16] drm/i915/gen9: Propagate watermark calculation failures up the call chain Matt Roper
2016-04-01  1:46 ` [PATCH 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check' Matt Roper
2016-04-05 13:01   ` Patrik Jakobsson
2016-04-01  1:46 ` [PATCH 15/16] drm/i915/gen9: Reject display updates that exceed wm limitations Matt Roper
2016-04-01  1:46 ` [PATCH 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state Matt Roper
2016-04-05 10:14   ` Maarten Lankhorst
2016-04-01  9:36 ` ✗ Fi.CI.BAT: warning for Pre-calculate SKL-style atomic watermarks 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.