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

drm/i915/dp: Implement .set_idle_link_train() for everyone



All platforms are capable of explicitly transmitting the idle
pattern. Implement it for everyone (so far it as implemented
only for HSW+).

The immediate benefit is that we gain the possibility of
implementing the POST_LT_ADJ_REQ sequence for all platforms.

Another potential future use would be a pseudo port sync mode on
pre-BDW where we attempt to sync up multiple ports/pipes by trying
to turn on the transcoders at the same time, and switching the
links to normal pixel transmission at the same time.

I'm not 100% sure the hardware is guaranteed to transmit the
required number of idle patterns (5) when switching away from
training pattern (either via explicit idle pattern, or straight
to the normal pixel output). Would be nice to confirm that at
some point, but for now let's assume it happens correctly in
both cases.

v2: Elaborate a bit more on the min required idle patterns

Tested-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250710201718.25310-7-ville.syrjala@linux.intel.com
parent 4cd073be
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -600,6 +600,19 @@ cpt_set_link_train(struct intel_dp *intel_dp,
	intel_de_posting_read(display, intel_dp->output_reg);
}

static void
cpt_set_idle_link_train(struct intel_dp *intel_dp,
			const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(intel_dp);

	intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
	intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;

	intel_de_write(display, intel_dp->output_reg, intel_dp->DP);
	intel_de_posting_read(display, intel_dp->output_reg);
}

static void
g4x_set_link_train(struct intel_dp *intel_dp,
		   const struct intel_crtc_state *crtc_state,
@@ -628,6 +641,19 @@ g4x_set_link_train(struct intel_dp *intel_dp,
	intel_de_posting_read(display, intel_dp->output_reg);
}

static void
g4x_set_idle_link_train(struct intel_dp *intel_dp,
			const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(intel_dp);

	intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
	intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE;

	intel_de_write(display, intel_dp->output_reg, intel_dp->DP);
	intel_de_posting_read(display, intel_dp->output_reg);
}

static void intel_dp_enable_port(struct intel_dp *intel_dp,
				 const struct intel_crtc_state *crtc_state)
{
@@ -1331,10 +1357,13 @@ bool g4x_dp_init(struct intel_display *display,
	intel_encoder->audio_disable = g4x_dp_audio_disable;

	if ((display->platform.ivybridge && port == PORT_A) ||
	    (HAS_PCH_CPT(display) && port != PORT_A))
	    (HAS_PCH_CPT(display) && port != PORT_A)) {
		dig_port->dp.set_link_train = cpt_set_link_train;
	else
		dig_port->dp.set_idle_link_train = cpt_set_idle_link_train;
	} else {
		dig_port->dp.set_link_train = g4x_set_link_train;
		dig_port->dp.set_idle_link_train = g4x_set_idle_link_train;
	}

	if (display->platform.cherryview)
		intel_encoder->set_signal_levels = chv_set_signal_levels;