All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v2 07/18] drm/i915: Compute vlv/chv wms the atomic way
Date: Thu,  2 Mar 2017 19:14:57 +0200	[thread overview]
Message-ID: <20170302171508.1666-8-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20170302171508.1666-1-ville.syrjala@linux.intel.com>

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

Start computing the vlv/chv watermarks the atomic way, from the
.compute_pipe_wm() hook. We'll recompute the actual watermarks
for only planes that are part of the state, the other planes will
keep their watermark from the last time it was computed.

And the actual watermark programming will happen from the
.initial_watermarks() hook. For now we'll just compute the
optimal watermarks, and we'll hook up the intermediate
watermarks properly later.

The DSPARB registers responsible for the FIFO paritioning are
double buffered, so they will be programming from
intel_begin_crtc_commit().

v2: s/noninverted/raw/ for consistency with other platforms
    s/vlv_plane_wm_set/vlv_raw_plane_wm_set/ for clarity

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   8 +
 drivers/gpu/drm/i915/intel_display.c |  21 ++-
 drivers/gpu/drm/i915/intel_drv.h     |   2 -
 drivers/gpu/drm/i915/intel_pm.c      | 302 +++++++++++++++++++++++------------
 4 files changed, 228 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 26f36b004d2f..0e8fd78d33e8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -526,6 +526,14 @@ struct i915_hotplug {
 	for_each_power_well_rev(__dev_priv, __power_well)		        \
 		for_each_if ((__power_well)->domains & (__domain_mask))
 
+#define for_each_intel_plane_in_state(__state, plane, plane_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->base.dev->mode_config.num_total_plane && \
+		     ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \
+		      (plane_state) = to_intel_plane_state((__state)->base.planes[__i].state), 1); \
+	     (__i)++) \
+		for_each_if (plane_state)
+
 struct drm_i915_private;
 struct i915_mm_struct;
 struct i915_mmu_object;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f4c024aaacc..7ca7d3e5d18e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5684,6 +5684,8 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
 static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 				   struct drm_atomic_state *old_state)
 {
+	struct intel_atomic_state *old_intel_state =
+		to_intel_atomic_state(old_state);
 	struct drm_crtc *crtc = pipe_config->base.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -5728,7 +5730,8 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 
 	intel_color_load_luts(&pipe_config->base);
 
-	intel_update_watermarks(intel_crtc);
+	dev_priv->display.initial_watermarks(old_intel_state,
+					     pipe_config);
 	intel_enable_pipe(intel_crtc);
 
 	assert_vblank_disabled(crtc);
@@ -5845,6 +5848,9 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
 
 	if (!IS_GEN2(dev_priv))
 		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+
+	if (!dev_priv->display.initial_watermarks)
+		intel_update_watermarks(intel_crtc);
 }
 
 static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
@@ -11268,10 +11274,13 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 static void
 clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 {
+	struct drm_i915_private *dev_priv =
+		to_i915(crtc_state->base.crtc->dev);
 	struct drm_crtc_state tmp_state;
 	struct intel_crtc_scaler_state scaler_state;
 	struct intel_dpll_hw_state dpll_hw_state;
 	struct intel_shared_dpll *shared_dpll;
+	struct intel_crtc_wm_state wm_state;
 	bool force_thru;
 
 	/* FIXME: before the switch to atomic started, a new pipe_config was
@@ -11284,6 +11293,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	shared_dpll = crtc_state->shared_dpll;
 	dpll_hw_state = crtc_state->dpll_hw_state;
 	force_thru = crtc_state->pch_pfit.force_thru;
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		wm_state = crtc_state->wm;
 
 	memset(crtc_state, 0, sizeof *crtc_state);
 
@@ -11292,6 +11303,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	crtc_state->shared_dpll = shared_dpll;
 	crtc_state->dpll_hw_state = dpll_hw_state;
 	crtc_state->pch_pfit.force_thru = force_thru;
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		crtc_state->wm = wm_state;
 }
 
 static int
@@ -12804,12 +12817,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 				/*
 				 * Make sure we don't call initial_watermarks
 				 * for ILK-style watermark updates.
+				 *
+				 * No clue what this is supposed to achieve.
 				 */
-				if (dev_priv->display.atomic_update_watermarks)
+				if (INTEL_GEN(dev_priv) >= 9)
 					dev_priv->display.initial_watermarks(intel_state,
 									     to_intel_crtc_state(crtc->state));
-				else
-					intel_update_watermarks(intel_crtc);
 			}
 		}
 	}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 28ebb2e5801e..351a14c98205 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -502,9 +502,7 @@ enum vlv_wm_level {
 struct vlv_wm_state {
 	struct vlv_pipe_wm wm[NUM_VLV_WM_LEVELS];
 	struct vlv_sr_wm sr[NUM_VLV_WM_LEVELS];
-	uint8_t num_active_planes;
 	uint8_t num_levels;
-	uint8_t level;
 	bool cxsr;
 };
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c4c7cf8f384e..f7cc013b3a78 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1094,6 +1094,28 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state)
 	return 0;
 }
 
+static int vlv_num_wm_levels(struct drm_i915_private *dev_priv)
+{
+	return dev_priv->wm.max_level + 1;
+}
+
+/* mark all levels starting from 'level' as invalid */
+static void vlv_invalidate_wms(struct intel_crtc *crtc,
+			       struct vlv_wm_state *wm_state, int level)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	for (; level < vlv_num_wm_levels(dev_priv); level++) {
+		enum plane_id plane_id;
+
+		for_each_plane_id_on_crtc(crtc, plane_id)
+			wm_state->wm[level].plane[plane_id] = USHRT_MAX;
+
+		wm_state->sr[level].cursor = USHRT_MAX;
+		wm_state->sr[level].plane = USHRT_MAX;
+	}
+}
+
 static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size)
 {
 	if (wm > fifo_size)
@@ -1102,105 +1124,162 @@ static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size)
 		return fifo_size - wm;
 }
 
-static void vlv_invert_wms(struct intel_crtc_state *crtc_state)
+/*
+ * Starting from 'level' set all higher
+ * levels to 'value' in the "raw" watermarks.
+ */
+static void vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
+				 int level, enum plane_id plane_id, u16 value)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
-	const struct vlv_fifo_state *fifo_state =
-		&crtc_state->wm.vlv.fifo_state;
-	int level;
-
-	for (level = 0; level < wm_state->num_levels; level++) {
-		struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-		const int sr_fifo_size =
-			INTEL_INFO(dev_priv)->num_pipes * 512 - 1;
-		enum plane_id plane_id;
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	int num_levels = vlv_num_wm_levels(dev_priv);
 
-		wm_state->sr[level].plane =
-			vlv_invert_wm_value(wm_state->sr[level].plane,
-					    sr_fifo_size);
-		wm_state->sr[level].cursor =
-			vlv_invert_wm_value(wm_state->sr[level].cursor,
-					    63);
+	for (; level < num_levels; level++) {
+		struct vlv_pipe_wm *raw = &crtc_state->wm.vlv.raw[level];
 
-		for_each_plane_id_on_crtc(crtc, plane_id) {
-			wm_state->wm[level].plane[plane_id] =
-				vlv_invert_wm_value(wm_state->wm[level].plane[plane_id],
-						    fifo_state->plane[plane_id]);
-		}
+		raw->plane[plane_id] = value;
 	}
 }
 
-static void vlv_compute_wm(struct intel_crtc_state *crtc_state)
+static void vlv_plane_wm_compute(struct intel_crtc_state *crtc_state,
+				 const struct intel_plane_state *plane_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
-	struct intel_plane *plane;
+	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+	enum plane_id plane_id = plane->id;
+	int num_levels = vlv_num_wm_levels(to_i915(plane->base.dev));
 	int level;
 
-	memset(wm_state, 0, sizeof(*wm_state));
-	memset(&crtc_state->wm.vlv.raw, 0, sizeof(crtc_state->wm.vlv.raw));
+	if (!plane_state->base.visible) {
+		vlv_raw_plane_wm_set(crtc_state, 0, plane_id, 0);
+		return;
+	}
 
-	wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed;
-	wm_state->num_levels = dev_priv->wm.max_level + 1;
+	for (level = 0; level < num_levels; level++) {
+		struct vlv_pipe_wm *raw = &crtc_state->wm.vlv.raw[level];
+		int wm = vlv_compute_wm_level(crtc_state, plane_state, level);
+		int max_wm = plane_id == PLANE_CURSOR ? 63 : 511;
 
-	wm_state->num_active_planes = 0;
+		/* FIXME just bail */
+		if (WARN_ON(level == 0 && wm > max_wm))
+			wm = max_wm;
 
-	if (wm_state->num_active_planes != 1)
-		wm_state->cxsr = false;
+		if (wm > max_wm)
+			break;
 
-	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
-		struct intel_plane_state *state =
-			to_intel_plane_state(plane->base.state);
+		raw->plane[plane_id] = wm;
+	}
 
-		if (!state->base.visible)
-			continue;
+	/* mark all higher levels as invalid */
+	vlv_raw_plane_wm_set(crtc_state, level, plane_id, USHRT_MAX);
 
-		for (level = 0; level < wm_state->num_levels; level++) {
-			struct vlv_pipe_wm *raw = &crtc_state->wm.vlv.raw[level];
-			int wm = vlv_compute_wm_level(crtc_state, state, level);
-			int max_wm = plane->id == PLANE_CURSOR ? 63 : 511;
+	DRM_DEBUG_KMS("%s wms: [0]=%d,[1]=%d,[2]=%d\n",
+		      plane->base.name,
+		      crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2].plane[plane_id],
+		      crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM5].plane[plane_id],
+		      crtc_state->wm.vlv.raw[VLV_WM_LEVEL_DDR_DVFS].plane[plane_id]);
+}
 
-			/* hack */
-			if (WARN_ON(level == 0 && wm > max_wm))
-				wm = max_wm;
+static bool vlv_plane_wm_is_valid(const struct intel_crtc_state *crtc_state,
+				  enum plane_id plane_id, int level)
+{
+	const struct vlv_pipe_wm *raw =
+		&crtc_state->wm.vlv.raw[level];
+	const struct vlv_fifo_state *fifo_state =
+		&crtc_state->wm.vlv.fifo_state;
 
-			if (wm > max_wm)
-				break;
+	return raw->plane[plane_id] <= fifo_state->plane[plane_id];
+}
 
-			raw->plane[plane->id] = wm;
-		}
+static bool vlv_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state, int level)
+{
+	return vlv_plane_wm_is_valid(crtc_state, PLANE_PRIMARY, level) &&
+		vlv_plane_wm_is_valid(crtc_state, PLANE_SPRITE0, level) &&
+		vlv_plane_wm_is_valid(crtc_state, PLANE_SPRITE1, level) &&
+		vlv_plane_wm_is_valid(crtc_state, PLANE_CURSOR, level);
+}
+
+static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(crtc_state->base.state);
+	struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
+	const struct vlv_fifo_state *fifo_state =
+		&crtc_state->wm.vlv.fifo_state;
+	int num_active_planes = hweight32(crtc_state->active_planes &
+					  ~BIT(PLANE_CURSOR));
+	struct intel_plane_state *plane_state;
+	struct intel_plane *plane;
+	enum plane_id plane_id;
+	int level, ret, i;
+
+	for_each_intel_plane_in_state(state, plane, plane_state, i) {
+		const struct intel_plane_state *old_plane_state =
+			to_intel_plane_state(plane->base.state);
+
+		if (plane_state->base.crtc != &crtc->base &&
+		    old_plane_state->base.crtc != &crtc->base)
+			continue;
 
-		wm_state->num_levels = level;
+		vlv_plane_wm_compute(crtc_state, plane_state);
 	}
 
-	vlv_compute_fifo(crtc_state);
+	/* initially allow all levels */
+	wm_state->num_levels = vlv_num_wm_levels(dev_priv);
+	/*
+	 * Note that enabling cxsr with no primary/sprite planes
+	 * enabled can wedge the pipe. Hence we only allow cxsr
+	 * with exactly one enabled primary/sprite plane.
+	 */
+	wm_state->cxsr = crtc->pipe != PIPE_C &&
+		crtc->wm.cxsr_allowed && num_active_planes == 1;
+
+	ret = vlv_compute_fifo(crtc_state);
+	if (ret)
+		return ret;
 
 	for (level = 0; level < wm_state->num_levels; level++) {
-		struct vlv_pipe_wm *raw = &crtc_state->wm.vlv.raw[level];
+		const struct vlv_pipe_wm *raw = &crtc_state->wm.vlv.raw[level];
+		const int sr_fifo_size = INTEL_INFO(dev_priv)->num_pipes * 512 - 1;
 
-		wm_state->wm[level] = *raw;
+		if (!vlv_crtc_wm_is_valid(crtc_state, level))
+			break;
 
-		wm_state->sr[level].plane = max3(raw->plane[PLANE_PRIMARY],
+		for_each_plane_id_on_crtc(crtc, plane_id) {
+			wm_state->wm[level].plane[plane_id] =
+				vlv_invert_wm_value(raw->plane[plane_id],
+						    fifo_state->plane[plane_id]);
+		}
+
+		wm_state->sr[level].plane =
+			vlv_invert_wm_value(max3(raw->plane[PLANE_PRIMARY],
 						 raw->plane[PLANE_SPRITE0],
-						 raw->plane[PLANE_SPRITE1]);
-		wm_state->sr[level].cursor = raw->plane[PLANE_CURSOR];
-	}
+						 raw->plane[PLANE_SPRITE1]),
+					    sr_fifo_size);
 
-	/* clear any (partially) filled invalid levels */
-	for (level = wm_state->num_levels; level < dev_priv->wm.max_level + 1; level++) {
-		memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level]));
-		memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level]));
+		wm_state->sr[level].cursor =
+			vlv_invert_wm_value(raw->plane[PLANE_CURSOR],
+					    63);
 	}
 
-	vlv_invert_wms(crtc_state);
+	if (level == 0)
+		return -EINVAL;
+
+	/* limit to only levels we can actually handle */
+	wm_state->num_levels = level;
+
+	/* invalidate the higher levels */
+	vlv_invalidate_wms(crtc, wm_state, level);
+
+	return 0;
 }
 
 #define VLV_FIFO(plane, value) \
 	(((value) << DSPARB_ ## plane ## _SHIFT_VLV) & DSPARB_ ## plane ## _MASK_VLV)
 
-static void vlv_pipe_set_fifo_size(const struct intel_crtc_state *crtc_state)
+static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
+				   struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -1215,10 +1294,6 @@ static void vlv_pipe_set_fifo_size(const struct intel_crtc_state *crtc_state)
 	WARN_ON(fifo_state->plane[PLANE_CURSOR] != 63);
 	WARN_ON(fifo_size != 511);
 
-	DRM_DEBUG_KMS("Pipe %c FIFO split %d / %d / %d\n",
-		      pipe_name(crtc->pipe), sprite0_start,
-		      sprite1_start, fifo_size);
-
 	spin_lock(&dev_priv->wm.dsparb_lock);
 
 	switch (crtc->pipe) {
@@ -1317,11 +1392,8 @@ static void vlv_merge_wm(struct drm_i915_private *dev_priv,
 		const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv;
 		enum pipe pipe = crtc->pipe;
 
-		if (!crtc->active)
-			continue;
-
 		wm->pipe[pipe] = wm_state->wm[wm->level];
-		if (wm->cxsr)
+		if (crtc->active && wm->cxsr)
 			wm->sr = wm_state->sr[wm->level];
 
 		wm->ddl[pipe].plane[PLANE_PRIMARY] = DDL_PRECISION_HIGH | 2;
@@ -1341,24 +1413,15 @@ static bool is_enabling(int old, int new, int threshold)
 	return old < threshold && new >= threshold;
 }
 
-static void vlv_update_wm(struct intel_crtc *crtc)
+static void vlv_program_watermarks(struct drm_i915_private *dev_priv)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_crtc_state *crtc_state =
-		to_intel_crtc_state(crtc->base.state);
-	enum pipe pipe = crtc->pipe;
 	struct vlv_wm_values *old_wm = &dev_priv->wm.vlv;
 	struct vlv_wm_values new_wm = {};
 
-	vlv_compute_wm(crtc_state);
-	crtc->wm.active.vlv = crtc_state->wm.vlv.optimal;
 	vlv_merge_wm(dev_priv, &new_wm);
 
-	if (memcmp(old_wm, &new_wm, sizeof(new_wm)) == 0) {
-		/* FIXME should be part of crtc atomic commit */
-		vlv_pipe_set_fifo_size(crtc_state);
+	if (memcmp(old_wm, &new_wm, sizeof(new_wm)) == 0)
 		return;
-	}
 
 	if (is_disabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_DDR_DVFS))
 		chv_set_memory_dvfs(dev_priv, false);
@@ -1369,17 +1432,8 @@ static void vlv_update_wm(struct intel_crtc *crtc)
 	if (is_disabling(old_wm->cxsr, new_wm.cxsr, true))
 		_intel_set_memory_cxsr(dev_priv, false);
 
-	/* FIXME should be part of crtc atomic commit */
-	vlv_pipe_set_fifo_size(crtc_state);
-
 	vlv_write_wm_values(dev_priv, &new_wm);
 
-	DRM_DEBUG_KMS("Setting FIFO watermarks - %c: plane=%d, cursor=%d, "
-		      "sprite0=%d, sprite1=%d, SR: plane=%d, cursor=%d level=%d cxsr=%d\n",
-		      pipe_name(pipe), new_wm.pipe[pipe].plane[PLANE_PRIMARY], new_wm.pipe[pipe].plane[PLANE_CURSOR],
-		      new_wm.pipe[pipe].plane[PLANE_SPRITE0], new_wm.pipe[pipe].plane[PLANE_SPRITE1],
-		      new_wm.sr.plane, new_wm.sr.cursor, new_wm.level, new_wm.cxsr);
-
 	if (is_enabling(old_wm->cxsr, new_wm.cxsr, true))
 		_intel_set_memory_cxsr(dev_priv, true);
 
@@ -1392,6 +1446,18 @@ static void vlv_update_wm(struct intel_crtc *crtc)
 	*old_wm = new_wm;
 }
 
+static void vlv_initial_watermarks(struct intel_atomic_state *state,
+				   struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+
+	mutex_lock(&dev_priv->wm.wm_mutex);
+	crtc->wm.active.vlv = crtc_state->wm.vlv.optimal;
+	vlv_program_watermarks(dev_priv);
+	mutex_unlock(&dev_priv->wm.wm_mutex);
+}
+
 #define single_plane_enabled(mask) is_power_of_2(mask)
 
 static void g4x_update_wm(struct intel_crtc *crtc)
@@ -4508,14 +4574,10 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct vlv_wm_values *wm = &dev_priv->wm.vlv;
 	struct intel_crtc *crtc;
-	enum pipe pipe;
 	u32 val;
 
 	vlv_read_wm_values(dev_priv, wm);
 
-	for_each_intel_crtc(dev, crtc)
-		vlv_get_fifo_size(to_intel_crtc_state(crtc->base.state));
-
 	wm->cxsr = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
 	wm->level = VLV_WM_LEVEL_PM2;
 
@@ -4553,13 +4615,53 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 		mutex_unlock(&dev_priv->rps.hw_lock);
 	}
 
-	for_each_pipe(dev_priv, pipe)
+	for_each_intel_crtc(dev, crtc) {
+		struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+		struct vlv_wm_state *active = &crtc->wm.active.vlv;
+		const struct vlv_fifo_state *fifo_state =
+			&crtc_state->wm.vlv.fifo_state;
+		enum pipe pipe = crtc->pipe;
+		enum plane_id plane_id;
+		int level;
+
+		vlv_get_fifo_size(crtc_state);
+
+		active->num_levels = wm->level + 1;
+		active->cxsr = wm->cxsr;
+
+		/* FIXME sanitize things more */
+		for (level = 0; level < active->num_levels; level++) {
+			struct vlv_pipe_wm *raw =
+				&crtc_state->wm.vlv.raw[level];
+
+			active->sr[level].plane = wm->sr.plane;
+			active->sr[level].cursor = wm->sr.cursor;
+
+			for_each_plane_id_on_crtc(crtc, plane_id) {
+				active->wm[level].plane[plane_id] =
+					wm->pipe[pipe].plane[plane_id];
+
+				raw->plane[plane_id] =
+					vlv_invert_wm_value(active->wm[level].plane[plane_id],
+							    fifo_state->plane[plane_id]);
+			}
+		}
+
+		for_each_plane_id_on_crtc(crtc, plane_id)
+			vlv_raw_plane_wm_set(crtc_state, level,
+					     plane_id, USHRT_MAX);
+		vlv_invalidate_wms(crtc, active, level);
+
+		crtc_state->wm.vlv.optimal = *active;
+
 		DRM_DEBUG_KMS("Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n",
 			      pipe_name(pipe),
 			      wm->pipe[pipe].plane[PLANE_PRIMARY],
 			      wm->pipe[pipe].plane[PLANE_CURSOR],
 			      wm->pipe[pipe].plane[PLANE_SPRITE0],
 			      wm->pipe[pipe].plane[PLANE_SPRITE1]);
+	}
 
 	DRM_DEBUG_KMS("Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n",
 		      wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr);
@@ -7717,7 +7819,9 @@ void intel_init_pm(struct drm_i915_private *dev_priv)
 		}
 	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 		vlv_setup_wm_latency(dev_priv);
-		dev_priv->display.update_wm = vlv_update_wm;
+		dev_priv->display.compute_pipe_wm = vlv_compute_pipe_wm;
+		dev_priv->display.initial_watermarks = vlv_initial_watermarks;
+		dev_priv->display.atomic_update_watermarks = vlv_atomic_update_fifo;
 	} else if (IS_PINEVIEW(dev_priv)) {
 		if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv),
 					    dev_priv->is_ddr3,
-- 
2.10.2

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

  parent reply	other threads:[~2017-03-02 17:15 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-02 17:14 [PATCH v3 00/18] drm/i915: VLV/CHV two-stage watermarks (v3) ville.syrjala
2017-03-02 17:14 ` [PATCH 01/18] drm/i915: Track visible planes in a bitmask ville.syrjala
2017-03-02 17:14 ` [PATCH v2 02/18] drm/i915: Track plane fifo sizes under intel_crtc ville.syrjala
2017-03-02 17:14 ` [PATCH 03/18] drm/i915: Move vlv wms from crtc->wm_state to crtc->wm.active.vlv ville.syrjala
2017-03-02 17:14 ` [PATCH 04/18] drm/i915: Plop vlv wm state into crtc_state ville.syrjala
2017-03-02 17:14 ` [PATCH 05/18] drm/i915: Plop vlv/chv fifo sizes into crtc state ville.syrjala
2017-03-02 17:14 ` [PATCH v2 06/18] drm/i915: Compute VLV/CHV FIFO sizes based on the PM2 watermarks ville.syrjala
2017-03-02 17:14 ` ville.syrjala [this message]
2017-03-02 17:14 ` [PATCH v2 08/18] drm/i915: Skip useless watermark/FIFO related work on VLV/CHV when not needed ville.syrjala
2017-03-03 14:52   ` Ville Syrjälä
2017-03-02 17:14 ` [PATCH 09/18] drm/i915: Compute proper intermediate wms for vlv/cvh ville.syrjala
2017-03-02 17:15 ` [PATCH 10/18] drm/i915: Nuke crtc->wm.cxsr_allowed ville.syrjala
2017-03-02 17:15 ` [PATCH 11/18] drm/i915: Only use update_wm_{pre, post} for pre-ilk platforms ville.syrjala
2017-03-02 17:15 ` [PATCH v2 12/18] drm/i915: Sanitize VLV/CHV watermarks properly ville.syrjala
2017-03-02 17:15 ` [PATCH v2 13/18] drm/i915: Workaround VLV/CHV sprite1->sprite0 enable underrun ville.syrjala
2017-03-02 17:15 ` [PATCH 14/18] drm/i915: Kill level 0 wm hack for VLV/CHV ville.syrjala
2017-03-02 17:15 ` [PATCH v2 15/18] drm/i915: Add plane update/disable tracepoints ville.syrjala
2017-03-02 17:15 ` [PATCH 16/18] drm/i915: Add VLV/CHV watermark/FIFO programming tracepoints ville.syrjala
2017-03-02 17:15 ` [PATCH 17/18] drm/i915: Add cxsr toggle tracepoint ville.syrjala
2017-03-02 17:15 ` [PATCH v2 18/18] drm/i915: Add FIFO underrun tracepoints ville.syrjala
2017-03-02 19:18 ` ✓ Fi.CI.BAT: success for drm/i915: VLV/CHV two-stage watermarks (rev3) Patchwork

Reply instructions:

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

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

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

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

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

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

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