[PATCH 20/20] drm/i915: Disable bigjoiner in the correct order

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Mon Aug 12 08:55:53 UTC 2019


We have to disable planes, pipe and transcoder on the master crtc first,
then do the same on the slave crtc.

After that we can disable the encoder entirely. Add special handling
to take care of this case.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 100 +++++++++++++------
 1 file changed, 69 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 3836f153c3c6..db5546df6019 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6709,12 +6709,26 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 	else
 		ironlake_pfit_disable(old_crtc_state);
 
-	if (old_crtc_state->bigjoiner_master_crtc != NULL)
+	if (old_crtc_state->bigjoiner) {
+		struct intel_crtc *master = old_crtc_state->bigjoiner_master_crtc;
+		struct intel_crtc_state *master_crtc_state;
+
+		/* ports are disabled from the slave, after it deconfigures */
+		if (old_crtc_state->bigjoiner_master_crtc == NULL)
+			return;
+
+		master_crtc_state = intel_atomic_get_old_crtc_state(state, master);
+
 		intel_ddi_disable_pipe_clock(old_crtc_state);
 
-	intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
+		/* disable ports on the master crtc */
+		intel_encoders_post_disable(master, master_crtc_state, state);
+		intel_encoders_post_pll_disable(master, master_crtc_state, state);
+	} else {
+		intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
 
-	intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
+		intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
+	}
 }
 
 static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -14457,6 +14471,46 @@ static void intel_atomic_cleanup_work(struct work_struct *work)
 	intel_atomic_helper_free_state(i915);
 }
 
+static void intel_crtc_disable(struct intel_atomic_state *state,
+			       struct intel_crtc *crtc,
+			       struct intel_crtc_state *old_crtc_state,
+			       struct intel_crtc_state *new_crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+
+	intel_pre_plane_update(old_crtc_state, new_crtc_state);
+
+	if (!old_crtc_state->hw.active)
+		return;
+
+	intel_crtc_disable_planes(state, crtc);
+
+	/*
+	 * We need to disable pipe CRC before disabling the pipe,
+	 * or we race against vblank off.
+	 */
+	intel_crtc_disable_pipe_crc(crtc);
+
+	dev_priv->display.crtc_disable(old_crtc_state, state);
+	crtc->active = false;
+	intel_fbc_disable(crtc);
+	intel_disable_shared_dpll(old_crtc_state);
+
+	/*
+	 * Underruns don't always raise
+	 * interrupts, so check manually.
+	 */
+	intel_check_cpu_fifo_underruns(dev_priv);
+	intel_check_pch_fifo_underruns(dev_priv);
+
+	/* FIXME unify this for all platforms */
+	if (!new_crtc_state->hw.active &&
+	    !HAS_GMCH(dev_priv) &&
+	    dev_priv->display.initial_watermarks)
+		dev_priv->display.initial_watermarks(state,
+						     new_crtc_state);
+}
+
 static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 {
 	struct drm_device *dev = state->base.dev;
@@ -14482,38 +14536,22 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 				modeset_get_crtc_power_domains(new_crtc_state);
 		}
 
-		if (!needs_modeset(new_crtc_state))
+		if (!needs_modeset(new_crtc_state) ||
+		    old_crtc_state->bigjoiner_master_crtc)
 			continue;
 
-		intel_pre_plane_update(old_crtc_state, new_crtc_state);
-
-		if (old_crtc_state->hw.active) {
-			intel_crtc_disable_planes(state, crtc);
-
-			/*
-			 * We need to disable pipe CRC before disabling the pipe,
-			 * or we race against vblank off.
-			 */
-			intel_crtc_disable_pipe_crc(crtc);
+		intel_crtc_disable(state, crtc, old_crtc_state, new_crtc_state);
 
-			dev_priv->display.crtc_disable(old_crtc_state, state);
-			crtc->active = false;
-			intel_fbc_disable(crtc);
-			intel_disable_shared_dpll(old_crtc_state);
+		if (old_crtc_state->bigjoiner) {
+			struct intel_crtc *slave =
+				intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
+			struct intel_crtc_state *old_slave_crtc_state =
+				intel_atomic_get_crtc_state(&state->base, slave);
+			struct intel_crtc_state *new_slave_crtc_state =
+				intel_atomic_get_crtc_state(&state->base, slave);
 
-			/*
-			 * Underruns don't always raise
-			 * interrupts, so check manually.
-			 */
-			intel_check_cpu_fifo_underruns(dev_priv);
-			intel_check_pch_fifo_underruns(dev_priv);
-
-			/* FIXME unify this for all platforms */
-			if (!new_crtc_state->hw.active &&
-			    !HAS_GMCH(dev_priv) &&
-			    dev_priv->display.initial_watermarks)
-				dev_priv->display.initial_watermarks(state,
-								     new_crtc_state);
+			intel_crtc_disable(state, slave, old_slave_crtc_state,
+					   new_slave_crtc_state);
 		}
 	}
 
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list