drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
Extension
.c
Size
32517 bytes
Lines
996
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 (pipes[i]->stream_res.audio != NULL) {
				const struct link_hwss *link_hwss = get_link_hwss(
					link, &pipes[i]->link_res);

				link_hwss->setup_audio_output(pipes[i], &audio_output[i],
						pipes[i]->stream_res.audio->inst);

				pipes[i]->stream_res.audio->funcs->az_configure(
						pipes[i]->stream_res.audio,
						pipes[i]->stream->signal,
						&audio_output[i].crtc_info,
						&pipes[i]->stream->audio_info,
						&audio_output[i].dp_link_info);

				if (link->dc->config.disable_hbr_audio_dp2 &&
						pipes[i]->stream_res.audio->funcs->az_disable_hbr_audio &&
						link->dc->link_srv->dp_is_128b_132b_signal(pipes[i]))
					pipes[i]->stream_res.audio->funcs->az_disable_hbr_audio(pipes[i]->stream_res.audio);
			}
		}
	}

	// Toggle on HPO I/O if necessary
	is_hpo_acquired = resource_is_hpo_acquired(state);
	if (was_hpo_acquired != is_hpo_acquired && link->dc->hwss.setup_hpo_hw_control)
		link->dc->hwss.setup_hpo_hw_control(link->dc->hwseq, is_hpo_acquired);

	for (i = 0; i < count; i++)
		pipes[i]->stream_res.tg->funcs->enable_crtc(pipes[i]->stream_res.tg);

	// Set DPMS on with stream update
	// Cache all streams on current link since dc_update_planes_and_stream might kill current_state
	for (i = 0; i < MAX_PIPES; i++) {
		if (state->streams[i] && state->streams[i]->is_phantom)
			continue;
		if (state->streams[i] && state->streams[i]->link && state->streams[i]->link == link)
			streams_on_link[num_streams_on_link++] = state->streams[i];
	}

	for (i = 0; i < num_streams_on_link; i++) {
		if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) {
			stream_update.stream = streams_on_link[i];
			stream_update.dpms_off = &dpms_off;
			dc_update_planes_and_stream(dc, NULL, 0, streams_on_link[i], &stream_update);
		}
	}
}

static void dp_test_send_link_training(struct dc_link *link)
{
	struct dc_link_settings link_settings = {0};
	uint8_t test_rate = 0;

	core_link_read_dpcd(
			link,
			DP_TEST_LANE_COUNT,
			(unsigned char *)(&link_settings.lane_count),
			1);
	core_link_read_dpcd(
			link,
			DP_TEST_LINK_RATE,
			&test_rate,
			1);
	link_settings.link_rate = get_link_rate_from_test_link_rate(test_rate);

	if (link_settings.link_rate == LINK_RATE_UNKNOWN) {
		DC_LOG_ERROR("%s: Invalid test link rate.", __func__);
		ASSERT(0);
	}

	/* Set preferred link settings */
	link->verified_link_cap.lane_count = link_settings.lane_count;
	link->verified_link_cap.link_rate = link_settings.link_rate;

	dp_retrain_link_dp_test(link, &link_settings, false);
}

static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
{
	union audio_test_mode            dpcd_test_mode = {0};
	struct audio_test_pattern_type   dpcd_pattern_type = {0};
	union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
	enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;

	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
	struct pipe_ctx *pipe_ctx = &pipes[0];
	unsigned int channel_count;
	unsigned int channel = 0;
	unsigned int modes = 0;

Annotation

Implementation Notes