drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c
Extension
.c
Size
25508 bytes
Lines
800
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 (link) {
			dpia_control.dpia_id = link->ddc_hw_inst;
			dpia_control.fec_rdy = link->dc->link_srv->dp_should_enable_fec(link);
		} else {
			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
			BREAK_TO_DEBUGGER();
			return;
		}

		DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
		link_dpia_control(enc->ctx, &dpia_control);
	}
}

void dcn31_link_encoder_enable_dp_mst_output(
	struct link_encoder *enc,
	const struct dc_link_settings *link_settings,
	enum clock_source_id clock_source)
{
	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);

	/* Enable transmitter and encoder. */
	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {

		DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
		dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source);

	} else {

		struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
		struct dc_link *link;

		link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);

		enc1_configure_encoder(enc10, link_settings);

		dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE;
		dpia_control.enc_id = enc->preferred_engine;
		dpia_control.mode_laneset.digmode = 5; /* 0 for SST; 5 for MST */
		dpia_control.lanenum = (uint8_t)link_settings->lane_count;
		dpia_control.symclk_10khz = link_settings->link_rate *
				LINK_RATE_REF_FREQ_IN_KHZ / 10;
		/* DIG_BE_CNTL.DIG_HPD_SELECT set to 5 (hpdsel - 1) to indicate HPD pin
		 * unused by DPIA.
		 */
		dpia_control.hpdsel = 6;

		if (link) {
			dpia_control.dpia_id = link->ddc_hw_inst;
			dpia_control.fec_rdy = link->dc->link_srv->dp_should_enable_fec(link);
		} else {
			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
			BREAK_TO_DEBUGGER();
			return;
		}

		DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
		link_dpia_control(enc->ctx, &dpia_control);
	}
}

void dcn31_link_encoder_disable_output(
	struct link_encoder *enc,
	enum signal_type signal)
{
	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);

	/* Disable transmitter and encoder. */
	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {

		DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
		dcn10_link_encoder_disable_output(enc, signal);

	} else {

		struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
		struct dc_link *link;

		if (enc->funcs->is_dig_enabled && !enc->funcs->is_dig_enabled(enc))
			return;

		link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);

		dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_DISABLE;
		dpia_control.enc_id = enc->preferred_engine;
		if (signal == SIGNAL_TYPE_DISPLAY_PORT) {
			dpia_control.mode_laneset.digmode = 0; /* 0 for SST; 5 for MST */
		} else if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
			dpia_control.mode_laneset.digmode = 5; /* 0 for SST; 5 for MST */
		} else {

Annotation

Implementation Notes