Commit e16bcbb0 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Handle joined pipes inside hsw_crtc_disable()



Reorganize the crtc disable path to only deal with the
master pipes/transcoders in intel_old_crtc_state_disables()
and offload the handling of joined pipes to hsw_crtc_disable().
This makes the whole thing much more sensible since we can
actually control the order in which we do the per-pipe vs.
per-transcoder modeset steps.

v2: Use the name 'pipe_crtc' for the per-pipe crtc pointer

Tested-by: default avatarVidya Srinivas <vidya.srinivas@intel.com>
Reviewed-by: default avatarArun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240409163502.29633-4-ville.syrjala@linux.intel.com
parent b7ce2803
Loading
Loading
Loading
Loading
+39 −25
Original line number Diff line number Diff line
@@ -1816,29 +1816,28 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
	const struct intel_crtc_state *old_crtc_state =
		intel_atomic_get_old_crtc_state(state, crtc);
	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
	struct intel_crtc *pipe_crtc;

	/*
	 * FIXME collapse everything to one hook.
	 * Need care with mst->ddi interactions.
	 */
	if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
	intel_encoders_disable(state, crtc);
	intel_encoders_post_disable(state, crtc);
	}

	intel_disable_shared_dpll(old_crtc_state);
	for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc,
					 intel_crtc_joined_pipe_mask(old_crtc_state)) {
		const struct intel_crtc_state *old_pipe_crtc_state =
			intel_atomic_get_old_crtc_state(state, pipe_crtc);

	if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
		struct intel_crtc *slave_crtc;
		intel_disable_shared_dpll(old_pipe_crtc_state);
	}

	intel_encoders_post_pll_disable(state, crtc);

		intel_dmc_disable_pipe(i915, crtc->pipe);

		for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
						 intel_crtc_bigjoiner_slave_pipes(old_crtc_state))
			intel_dmc_disable_pipe(i915, slave_crtc->pipe);
	}
	for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc,
					 intel_crtc_joined_pipe_mask(old_crtc_state))
		intel_dmc_disable_pipe(i915, pipe_crtc->pipe);
}

static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -6869,21 +6868,31 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
					  struct intel_crtc *crtc)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	const struct intel_crtc_state *new_crtc_state =
		intel_atomic_get_new_crtc_state(state, crtc);
	const struct intel_crtc_state *old_crtc_state =
		intel_atomic_get_old_crtc_state(state, crtc);
	struct intel_crtc *pipe_crtc;

	/*
	 * We need to disable pipe CRC before disabling the pipe,
	 * or we race against vblank off.
	 */
	intel_crtc_disable_pipe_crc(crtc);
	for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc,
					 intel_crtc_joined_pipe_mask(old_crtc_state))
		intel_crtc_disable_pipe_crc(pipe_crtc);

	dev_priv->display.funcs.display->crtc_disable(state, crtc);
	crtc->active = false;
	intel_fbc_disable(crtc);

	if (!new_crtc_state->hw.active)
		intel_initial_watermarks(state, crtc);
	for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc,
					 intel_crtc_joined_pipe_mask(old_crtc_state)) {
		const struct intel_crtc_state *new_pipe_crtc_state =
			intel_atomic_get_new_crtc_state(state, pipe_crtc);

		pipe_crtc->active = false;
		intel_fbc_disable(pipe_crtc);

		if (!new_pipe_crtc_state->hw.active)
			intel_initial_watermarks(state, pipe_crtc);
	}
}

static void intel_commit_modeset_disables(struct intel_atomic_state *state)
@@ -6923,19 +6932,21 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
		if ((disable_pipes & BIT(crtc->pipe)) == 0)
			continue;

		if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
			continue;

		/* In case of Transcoder port Sync master slave CRTCs can be
		 * assigned in any order and we need to make sure that
		 * slave CRTCs are disabled first and then master CRTC since
		 * Slave vblanks are masked till Master Vblanks.
		 */
		if (!is_trans_port_sync_slave(old_crtc_state) &&
		    !intel_dp_mst_is_slave_trans(old_crtc_state) &&
		    !intel_crtc_is_bigjoiner_slave(old_crtc_state))
		    !intel_dp_mst_is_slave_trans(old_crtc_state))
			continue;

		intel_old_crtc_state_disables(state, crtc);

		disable_pipes &= ~BIT(crtc->pipe);
		disable_pipes &= ~intel_crtc_joined_pipe_mask(old_crtc_state);
	}

	/* Disable everything else left on */
@@ -6943,9 +6954,12 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
		if ((disable_pipes & BIT(crtc->pipe)) == 0)
			continue;

		if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
			continue;

		intel_old_crtc_state_disables(state, crtc);

		disable_pipes &= ~BIT(crtc->pipe);
		disable_pipes &= ~intel_crtc_joined_pipe_mask(old_crtc_state);
	}

	drm_WARN_ON(&i915->drm, disable_pipes);