diff mbox

[RFC,6/8] drm/i915/vlv: Add optimal field in intel_crtc_wm_state

Message ID 1466672279-16236-7-git-send-email-chix.ding@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

chix.ding@intel.com June 23, 2016, 8:57 a.m. UTC
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

For two-stage watermark programming, we need to calculate optimal
watermark which is set after vblank and intermediate watermark which
can be set without waiting for vblank.

This commit adds optimal watermark field and changes the code to use it
in vlv_compute_wm(), vlv_update_wm() and vlv_wm_get_hw_state()

v2:
- use mutex in vlv_update_wm to make assigning currently active wm_state
and merging multiple wm_state become one atomic operation
- change vlv_compute_fifo and vlv_invert_wms to pass wm_state as parameter

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Chi Ding <chix.ding@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h | 23 ++++++++++++++---------
 drivers/gpu/drm/i915/intel_pm.c  | 24 ++++++++++++++++--------
 2 files changed, 30 insertions(+), 17 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9d83494..6d616b6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -417,6 +417,16 @@  struct skl_pipe_wm {
 	uint32_t linetime;
 };
 
+struct vlv_wm_state {
+	struct vlv_pipe_wm wm[3];
+	struct vlv_sr_wm sr[3];
+	uint16_t fifo_size[I915_MAX_PLANES];
+	uint8_t num_active_planes;
+	uint8_t num_levels;
+	uint8_t level;
+	bool cxsr;
+};
+
 struct intel_crtc_wm_state {
 	union {
 		struct {
@@ -437,6 +447,10 @@  struct intel_crtc_wm_state {
 		} ilk;
 
 		struct {
+			struct vlv_wm_state optimal;
+		} vlv;
+
+		struct {
 			/* gen9+ only needs 1-step wm programming */
 			struct skl_pipe_wm optimal;
 
@@ -618,15 +632,6 @@  struct intel_crtc_state {
 	uint32_t gamma_mode;
 };
 
-struct vlv_wm_state {
-	struct vlv_pipe_wm wm[3];
-	struct vlv_sr_wm sr[3];
-	uint16_t fifo_size[I915_MAX_PLANES];
-	uint8_t num_active_planes;
-	uint8_t num_levels;
-	uint8_t level;
-	bool cxsr;
-};
 
 struct intel_crtc {
 	struct drm_crtc base;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 03cd139..0076716 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -983,10 +983,10 @@  static uint16_t vlv_compute_wm_level(struct intel_plane *plane,
 	return min_t(int, wm, USHRT_MAX);
 }
 
-static void vlv_compute_fifo(struct intel_crtc_state *cstate)
+static void vlv_compute_fifo(struct intel_crtc_state *cstate,
+				struct vlv_wm_state *wm_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
-	struct vlv_wm_state *wm_state = &crtc->wm_state;
 	struct drm_device *dev = crtc->base.dev;
 	struct intel_plane *plane;
 	unsigned int total_rate = 0;
@@ -1050,9 +1050,9 @@  static void vlv_compute_fifo(struct intel_crtc_state *cstate)
 	WARN_ON(fifo_left != 0);
 }
 
-static void vlv_invert_wms(struct intel_crtc *crtc)
+static void vlv_invert_wms(struct intel_crtc *crtc,
+			struct vlv_wm_state *wm_state)
 {
-	struct vlv_wm_state *wm_state = &crtc->wm_state;
 	int level;
 
 	for (level = 0; level < wm_state->num_levels; level++) {
@@ -1093,7 +1093,7 @@  static int vlv_compute_wm(struct intel_crtc_state *cstate)
 {
 	struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
 	struct drm_device *dev = crtc->base.dev;
-	struct vlv_wm_state *wm_state = &crtc->wm_state;
+	struct vlv_wm_state *wm_state = &cstate->wm.vlv.optimal;
 	struct intel_plane *plane;
 	int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1;
 	int level;
@@ -1105,7 +1105,7 @@  static int vlv_compute_wm(struct intel_crtc_state *cstate)
 
 	wm_state->num_active_planes = 0;
 
-	vlv_compute_fifo(cstate);
+	vlv_compute_fifo(cstate, wm_state);
 
 	if (wm_state->num_active_planes != 1)
 		wm_state->cxsr = false;
@@ -1191,7 +1191,7 @@  static int vlv_compute_wm(struct intel_crtc_state *cstate)
 		memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level]));
 	}
 
-	vlv_invert_wms(crtc);
+	vlv_invert_wms(crtc, wm_state);
 
 	return 0;
 }
@@ -1331,7 +1331,10 @@  static void vlv_update_wm(struct drm_crtc *crtc)
 	struct vlv_wm_values wm = {};
 
 	vlv_compute_wm(intel_crtc->config);
+	mutex_lock(&dev_priv->wm.wm_mutex);
+	intel_crtc->wm_state = intel_crtc->config->wm.vlv.optimal;
 	vlv_merge_wm(dev, &wm);
+	mutex_unlock(&dev_priv->wm.wm_mutex);
 
 	if (memcmp(&dev_priv->wm.vlv, &wm, sizeof(wm)) == 0) {
 		/* FIXME should be part of crtc atomic commit */
@@ -4282,10 +4285,15 @@  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) {
+		pipe = crtc->pipe;
+		to_intel_crtc_state(crtc->base.state)->wm.vlv.optimal
+			= crtc->wm_state;
+
 		DRM_DEBUG_KMS("Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n",
 			      pipe_name(pipe), wm->pipe[pipe].primary, wm->pipe[pipe].cursor,
 			      wm->pipe[pipe].sprite[0], wm->pipe[pipe].sprite[1]);
+	}
 
 	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);