[Intel-gfx] [RFC 11/15] drm/i915: Calculate pipe watermark values during atomic check

Matt Roper matthew.d.roper at intel.com
Wed May 20 19:12:23 PDT 2015


Calculate pipe watermarks during atomic calculation phase, based on the
contents of the atomic transaction's state structure.

FIXME:  For now we just dump this in a temporary structure and don't do
anything with it except compare it to the values we re-calculate later.
Ultimately we should squash the next patch into this one once we're sure
this is really working as expected.

Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  3 +++
 drivers/gpu/drm/i915/intel_atomic.c  | 29 +++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_display.c |  1 +
 drivers/gpu/drm/i915/intel_drv.h     |  5 +++++
 drivers/gpu/drm/i915/intel_pm.c      |  6 +++++-
 5 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index df5673f..214ce76 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -562,6 +562,9 @@ struct drm_i915_display_funcs {
 			  int target, int refclk,
 			  struct dpll *match_clock,
 			  struct dpll *best_clock);
+	int (*compute_pipe_wm)(struct drm_crtc *crtc,
+			       struct drm_atomic_state *state,
+			       void *target);
 	void (*update_wm)(struct drm_crtc *crtc);
 	void (*update_sprite_wm)(struct drm_plane *plane,
 				 struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 7ed8033..db349dd 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -176,8 +176,13 @@ int intel_atomic_commit(struct drm_device *dev,
 			continue;
 		}
 
-		to_intel_crtc(crtc)->config->scaler_state =
-			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
+#define STATE_SWAP(x) to_intel_crtc(crtc)->config->x = \
+	to_intel_crtc_state(state->crtc_states[i])->x;
+
+		STATE_SWAP(scaler_state);
+		STATE_SWAP(wm);
+
+#undef STATE_SWAP
 
 		if (INTEL_INFO(dev)->gen >= 9)
 			skl_detach_scalers(to_intel_crtc(crtc));
@@ -421,3 +426,23 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 
 	return 0;
 }
+
+/*
+ * intel_check_crtc: Check CRTC state
+ */
+int
+intel_check_crtc(struct drm_crtc *crtc,
+		 struct drm_crtc_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct intel_crtc_state *intel_state = to_intel_crtc_state(state);
+	int ret;
+
+	if (!dev_priv->display.compute_pipe_wm)
+		return 0;
+
+	ret = dev_priv->display.compute_pipe_wm(crtc, state->state,
+						&intel_state->wm.tmp);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f4398a7..76affba 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11096,6 +11096,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
 	.load_lut = intel_crtc_load_lut,
 	.atomic_begin = intel_begin_crtc_commit,
 	.atomic_flush = intel_finish_crtc_commit,
+	.atomic_check = intel_check_crtc,
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4ae109c..6ca3c06 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -464,6 +464,9 @@ struct intel_crtc_state {
 	struct intel_crtc_scaler_state scaler_state;
 
 	struct {
+		/* tmp wm */
+		struct intel_pipe_wm tmp;
+
 		/* final, target watermarks for state */
 		union {
 			struct intel_pipe_wm ilk;
@@ -1424,6 +1427,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 int intel_atomic_setup_scalers(struct drm_device *dev,
 	struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state);
+int intel_check_crtc(struct drm_crtc *crtc,
+		     struct drm_crtc_state *state);
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 789b4fe..017b184 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2074,8 +2074,9 @@ static void ilk_compute_wm_config(struct drm_device *dev,
 /* Compute new watermarks for the pipe */
 static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
 			       struct drm_atomic_state *state,
-			       struct intel_pipe_wm *pipe_wm)
+			       void *target)
 {
+	struct intel_pipe_wm *pipe_wm = target;
 	struct drm_device *dev = crtc->dev;
 	const struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -3514,6 +3515,8 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 	struct intel_pipe_wm pipe_wm = {};
 
 	ilk_compute_pipe_wm(crtc, NULL, &pipe_wm);
+	WARN(memcmp(&cstate->wm.tmp, &pipe_wm, sizeof(pipe_wm)) != 0,
+	     "Pre-computed atomic watermark values do not match final values!");
 
 	if (!memcmp(&cstate->wm.target.ilk, &pipe_wm, sizeof(pipe_wm)))
 		return;
@@ -6655,6 +6658,7 @@ void intel_init_pm(struct drm_device *dev)
 		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
 			dev_priv->display.update_wm = ilk_update_wm;
 			dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;
+			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
 		} else {
 			DRM_DEBUG_KMS("Failed to read display plane latency. "
 				      "Disable CxSR\n");
-- 
1.8.5.1



More information about the Intel-gfx mailing list