drivers/gpu/drm/i915/display/intel_dp_link_training.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_dp_link_training.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_dp_link_training.c
Extension
.c
Size
67193 bytes
Lines
2236
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (intel_dp_is_uhbr(crtc_state)) {
			if (!intel_dp_lane_max_tx_ffe_reached(train_set_lane))
				return false;
		} else {
			if (!intel_dp_lane_max_vswing_reached(train_set_lane))
				return false;
		}
	}

	return true;
}

void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate,
				     bool is_vrr,
				     bool pr_with_as_sdp_enable)
{
	u8 link_config[2];

	link_config[0] = is_vrr ? DP_MSA_TIMING_PAR_IGNORE_EN : 0;
	link_config[0] |= pr_with_as_sdp_enable ? DP_FIXED_VTOTAL_AS_SDP_EN_IN_PR_ACTIVE : 0;
	link_config[1] = drm_dp_is_uhbr_rate(link_rate) ?
			 DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B;
	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
}

static bool
intel_dp_pr_with_as_sdp_enabled(struct intel_dp *intel_dp,
				const struct intel_crtc_state *crtc_state)
{
	return intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) &&
		(crtc_state->infoframes.enable &
		 intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC));
}

static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp,
					    const struct intel_crtc_state *crtc_state)
{
	 /*
	  * Currently, we set the MSA ignore bit based on vrr.in_range.
	  * We can't really read that out during driver load since we don't have
	  * the connector information read in yet. So if we do end up doing a
	  * modeset during initial_commit() we'll clear the MSA ignore bit.
	  * GOP likely wouldn't have set this bit so after the initial commit,
	  * if there are no modesets and we enable VRR mode seamlessly
	  * (without a full modeset), the MSA ignore bit might never get set.
	  *
	  * #TODO: Implement readout of vrr.in_range.
	  * We need fastset support for setting the MSA ignore bit in DPCD,
	  * especially on the first real commit when clearing the inherited flag.
	  */
	intel_dp_link_training_set_mode(intel_dp,
					crtc_state->port_clock,
					crtc_state->vrr.in_range,
					intel_dp_pr_with_as_sdp_enabled(intel_dp, crtc_state));
}

void intel_dp_link_training_set_bw(struct intel_dp *intel_dp,
				   int link_bw, int rate_select, int lane_count,
				   bool enhanced_framing, bool post_lt_adj_req)
{
	if (enhanced_framing)
		lane_count |= DP_LANE_COUNT_ENHANCED_FRAME_EN;

	if (post_lt_adj_req)
		lane_count |= DP_POST_LT_ADJ_REQ_GRANTED;

	if (link_bw) {
		/* DP and eDP v1.3 and earlier link bw set method. */
		u8 link_config[] = { link_bw, lane_count };

		drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config,
				  ARRAY_SIZE(link_config));
	} else {
		/*
		 * eDP v1.4 and later link rate set method.
		 *
		 * eDP v1.4x sinks shall ignore DP_LINK_RATE_SET if
		 * DP_LINK_BW_SET is set. Avoid writing DP_LINK_BW_SET.
		 *
		 * eDP v1.5 sinks allow choosing either, and the last choice
		 * shall be active.
		 */
		drm_dp_dpcd_writeb(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count);
		drm_dp_dpcd_writeb(&intel_dp->aux, DP_LINK_RATE_SET, rate_select);
	}
}

/*
 * Pick Training Pattern Sequence (TPS) for channel equalization. 128b/132b TPS2
 * for UHBR+, TPS4 for HBR3 or for 1.4 devices that support it, TPS3 for HBR2 or

Annotation

Implementation Notes