diff mbox

[RFC,14/15] drm/i915: Program atomic watermarks via vblank job

Message ID 1432174347-19138-15-git-send-email-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Matt Roper May 21, 2015, 2:12 a.m. UTC
Use the new vblank job infrastructure to schedule watermark programming
to happen when the next vblank occurs.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  7 +++++++
 drivers/gpu/drm/i915/intel_display.c | 38 +++++++++++++++++++++++++++++++-----
 drivers/gpu/drm/i915/intel_pm.c      |  1 +
 3 files changed, 41 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d577eba..5134101 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -569,6 +569,7 @@  struct drm_i915_display_funcs {
 				 struct drm_crtc *crtc,
 				 uint32_t sprite_width, uint32_t sprite_height,
 				 int pixel_size, bool enable, bool scaled);
+	void (*program_watermarks)(struct drm_i915_private *dev_priv);
 	void (*modeset_global_resources)(struct drm_atomic_state *state);
 	/* Returns the active state of the crtc, and if the crtc is active,
 	 * fills out the pipe-config with the hw state. */
@@ -2494,6 +2495,12 @@  struct drm_i915_cmd_table {
 #define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
 #define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev))
 
+/*
+ * FIXME:  Only some platforms have been transitioned to atomic watermark
+ * updates so far.
+ */
+#define HAS_ATOMIC_WM(dev_priv) (dev_priv->display.program_watermarks != NULL)
+
 #define GT_FREQUENCY_MULTIPLIER 50
 #define GEN9_FREQ_SCALER 3
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9b56d07..b2012c9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13209,6 +13209,24 @@  intel_disable_primary_plane(struct drm_plane *plane,
 	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
 }
 
+static void
+do_update_watermarks(struct intel_crtc *intel_crtc,
+		     void *data,
+		     bool early,
+		     u32 seq)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+
+	/*
+	 * If we fired early because the CRTC is turning off, there's no
+	 * need to actually program watermarks.
+	 */
+	if (early)
+		return;
+
+	dev_priv->display.program_watermarks(dev_priv);
+}
+
 static void intel_begin_crtc_commit(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -13251,7 +13269,7 @@  static void intel_begin_crtc_commit(struct drm_crtc *crtc)
 	if (intel_crtc->atomic.pre_disable_primary)
 		intel_pre_disable_primary(crtc);
 
-	if (intel_crtc->atomic.update_wm)
+	if (!HAS_ATOMIC_WM(dev_priv) && intel_crtc->atomic.update_wm)
 		intel_update_watermarks(crtc);
 
 	intel_runtime_pm_get(dev_priv);
@@ -13270,6 +13288,15 @@  static void intel_finish_crtc_commit(struct drm_crtc *crtc)
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_plane *p;
 
+	/*
+	 * If this platform supports atomic watermarks, schedule a job to
+	 * update watermarks when the next vblank occurs.  Otherwise, just
+	 * update watermarks the old-fashioned way.
+	 */
+	if (HAS_ATOMIC_WM(dev_priv))
+		intel_schedule_vblank_job(intel_crtc, do_update_watermarks,
+					  NULL, dev_priv->wq, 1);
+
 	if (intel_crtc->atomic.evade)
 		intel_pipe_update_end(intel_crtc,
 				      intel_crtc->atomic.start_vbl_count);
@@ -13290,10 +13317,11 @@  static void intel_finish_crtc_commit(struct drm_crtc *crtc)
 	if (intel_crtc->atomic.post_enable_primary)
 		intel_post_enable_primary(crtc);
 
-	drm_for_each_legacy_plane(p, &dev->mode_config.plane_list)
-		if (intel_crtc->atomic.update_sprite_watermarks &
-		    (1 << drm_plane_index(p)))
-			intel_update_sprite_watermarks(p, crtc);
+	if (!HAS_ATOMIC_WM(dev_priv))
+		drm_for_each_legacy_plane(p, &dev->mode_config.plane_list)
+			if (intel_crtc->atomic.update_sprite_watermarks &
+			    (1 << drm_plane_index(p)))
+				intel_update_sprite_watermarks(p, crtc);
 
 	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
 }
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 27337fe..7f0a0c1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6626,6 +6626,7 @@  void intel_init_pm(struct drm_device *dev)
 			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;
+			dev_priv->display.program_watermarks = ilk_program_watermarks;
 		} else {
 			DRM_DEBUG_KMS("Failed to read display plane latency. "
 				      "Disable CxSR\n");