drivers/gpu/drm/amd/display/dc/dc_fused_io.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dc_fused_io.c
Extension
.c
Size
4211 bytes
Lines
149
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

// SPDX-License-Identifier: MIT
//
// Copyright 2025 Advanced Micro Devices, Inc.

#include "dc_fused_io.h"

#include "dm_helpers.h"
#include "gpio.h"

static bool op_i2c_convert(
		union dmub_rb_cmd *cmd,
		const struct mod_hdcp_atomic_op_i2c *op,
		enum dmub_cmd_fused_request_type type,
		uint32_t ddc_line,
		bool over_aux
)
{
	struct dmub_cmd_fused_request *req = &cmd->fused_io.request;
	struct dmub_cmd_fused_request_location_i2c *loc = &req->u.i2c;

	if (!op || op->size > sizeof(req->buffer))
		return false;

	req->type = type;
	loc->is_aux = false;
	loc->ddc_line = (uint8_t)ddc_line;
	loc->over_aux = over_aux;
	loc->address = op->address;
	loc->offset = op->offset;
	loc->length = (uint8_t)op->size;
	memcpy(req->buffer, op->data, op->size);

	return true;
}

static bool op_aux_convert(
		union dmub_rb_cmd *cmd,
		const struct mod_hdcp_atomic_op_aux *op,
		enum dmub_cmd_fused_request_type type,
		uint32_t ddc_line
)
{
	struct dmub_cmd_fused_request *req = &cmd->fused_io.request;
	struct dmub_cmd_fused_request_location_aux *loc = &req->u.aux;

	if (!op || op->size > sizeof(req->buffer))
		return false;

	req->type = type;
	loc->is_aux = true;
	loc->ddc_line = ddc_line;
	loc->address = op->address;
	loc->length = op->size;
	memcpy(req->buffer, op->data, op->size);

	return true;
}

static bool atomic_write_poll_read(
		struct dc_link *link,
		union dmub_rb_cmd commands[3],
		uint32_t poll_timeout_us,
		uint8_t poll_mask_msb
)
{
	const uint8_t count = 3;
	const uint32_t timeout_per_request_us = 10000;
	const uint32_t timeout_per_aux_transaction_us = 10000;
	uint64_t timeout_us = 0;

	commands[1].fused_io.request.poll_mask_msb = poll_mask_msb;
	commands[1].fused_io.request.timeout_us = poll_timeout_us;

	for (uint8_t i = 0; i < count; i++) {
		struct dmub_rb_cmd_fused_io *io = &commands[i].fused_io;

		io->header.type = DMUB_CMD__FUSED_IO;
		io->header.sub_type = DMUB_CMD__FUSED_IO_EXECUTE;
		io->header.multi_cmd_pending = i != count - 1;
		io->header.payload_bytes = sizeof(commands[i].fused_io) - sizeof(io->header);

		timeout_us += timeout_per_request_us + io->request.timeout_us;
		if (!io->request.timeout_us && io->request.u.aux.is_aux)
			timeout_us += timeout_per_aux_transaction_us * (io->request.u.aux.length / 16);
	}

	if (!dm_helpers_execute_fused_io(link->ctx, link, commands, count, (uint32_t)timeout_us))
		return false;

	return commands[0].fused_io.request.status == FUSED_REQUEST_STATUS_SUCCESS;

Annotation

Implementation Notes