drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
Extension
.c
Size
22601 bytes
Lines
750
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_enc && ((uint32_t)stream->link->connector_signal & link_enc->output_signals)) {
				is_dig_stream = true;
				/* If stream is HDMI FRL, then it is not a DIG stream. */
				if (dc_is_hdmi_frl_signal(stream->signal))
					is_dig_stream = false;
				break;
			}
		}
	}
	return is_dig_stream;
}

static struct link_enc_assignment get_assignment(struct dc *dc, int i)
{
	struct link_enc_assignment assignment;

	if (dc->current_state->res_ctx.link_enc_cfg_ctx.mode == LINK_ENC_CFG_TRANSIENT)
		assignment = dc->current_state->res_ctx.link_enc_cfg_ctx.transient_assignments[i];
	else /* LINK_ENC_CFG_STEADY */
		assignment = dc->current_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];

	return assignment;
}

/* Return stream using DIG link encoder resource. NULL if unused. */
static struct dc_stream_state *get_stream_using_link_enc(
		struct dc_state *state,
		enum engine_id eng_id)
{
	struct dc_stream_state *stream = NULL;
	int i;

	for (i = 0; i < state->stream_count; i++) {
		struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];

		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
			stream = state->streams[i];
			break;
		}
	}

	return stream;
}

static void remove_link_enc_assignment(
		struct dc_state *state,
		struct dc_stream_state *stream,
		enum engine_id eng_id)
{
	int eng_idx;
	int i;

	if (eng_id != ENGINE_ID_UNKNOWN) {
		eng_idx = eng_id - ENGINE_ID_DIGA;

		/* stream ptr of stream in dc_state used to update correct entry in
		 * link_enc_assignments table.
		 */
		for (i = 0; i < MAX_PIPES; i++) {
			struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];

			if (assignment.valid && assignment.stream == stream) {
				state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false;
				/* Only add link encoder back to availability pool if not being
				 * used by any other stream (i.e. removing SST stream or last MST stream).
				 */
				if (get_stream_using_link_enc(state, eng_id) == NULL)
					state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = eng_id;

				stream->link_enc = NULL;
				state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN;
				state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL;
				dc_stream_release(stream);
				break;
			}
		}
	}
}

static void add_link_enc_assignment(
		struct dc_state *state,
		struct dc_stream_state *stream,
		enum engine_id eng_id)
{
	int eng_idx;
	int i;

	if (eng_id != ENGINE_ID_UNKNOWN) {
		eng_idx = eng_id - ENGINE_ID_DIGA;

Annotation

Implementation Notes