drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
Extension
.c
Size
64047 bytes
Lines
1880
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 (dcn32_check_no_memory_request_for_cab(dc)) {
			/* Enable no-memory-requests case */
			memset(&cmd, 0, sizeof(cmd));
			cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
			cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
			cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);

			dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);

			return true;
		}

		/* 2. Check if all surfaces can fit in CAB.
		 * If surfaces can fit into CAB, send CAB_ACTION_ALLOW DMUB message
		 * and configure HUBP's to fetch from MALL
		 */
		ways = dcn32_calculate_cab_allocation(dc, dc->current_state);

		/* MALL not supported with Stereo3D or TMZ surface. If any plane is using stereo,
		 * or TMZ surface, don't try to enter MALL.
		 */
		for (i = 0; i < dc->current_state->stream_count; i++) {
			for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) {
				plane = dc->current_state->stream_status[i].plane_states[j];

				if (plane->address.type == PLN_ADDR_TYPE_GRPH_STEREO ||
						plane->address.tmz_surface) {
					mall_ss_unsupported = true;
					break;
				}
			}
			if (mall_ss_unsupported)
				break;
		}
		if (ways <= dc->caps.cache_num_ways && !mall_ss_unsupported) {
			memset(&cmd, 0, sizeof(cmd));
			cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
			cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
			cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
			cmd.cab.cab_alloc_ways = (uint8_t)ways;

			dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
			DC_LOG_MALL("enable scanout from MALL");

			return true;
		}

		DC_LOG_MALL("surface cannot fit in CAB, disabling scanout from MALL\n");
		return false;
	}

	/* Disable CAB */
	memset(&cmd, 0, sizeof(cmd));
	cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
	cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION;
	cmd.cab.header.payload_bytes =
			sizeof(cmd.cab) - sizeof(cmd.cab.header);

	dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);

	return true;
}

/* Send DMCUB message with SubVP pipe info
 * - For each pipe in context, populate payload with required SubVP information
 *   if the pipe is using SubVP for MCLK switch
 * - This function must be called while the DMUB HW lock is acquired by driver
 */
void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context)
{
	unsigned int i;
	bool enable_subvp = false;

	if (!dc->ctx || !dc->ctx->dmub_srv)
		return;

	for (i = 0; i < dc->res_pool->pipe_count; i++) {
		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];

		if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_MAIN) {
			// There is at least 1 SubVP pipe, so enable SubVP
			enable_subvp = true;
			break;
		}
	}
	dc_dmub_setup_subvp_dmub_command(dc, context, enable_subvp);
}

/* Sub-Viewport DMUB lock needs to be acquired by driver whenever SubVP is active and:
 * 1. Any full update for any SubVP main pipe

Annotation

Implementation Notes