drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c
Extension
.c
Size
19290 bytes
Lines
703
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

struct i2c_payloads {
	struct vector payloads;
};

static bool i2c_payloads_create(
		struct dc_context *ctx,
		struct i2c_payloads *payloads,
		uint32_t count)
{
	if (dal_vector_construct(
		&payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
		return true;

	return false;
}

static struct i2c_payload *i2c_payloads_get(struct i2c_payloads *p)
{
	return (struct i2c_payload *)p->payloads.container;
}

static uint32_t i2c_payloads_get_count(struct i2c_payloads *p)
{
	return p->payloads.count;
}

static void i2c_payloads_destroy(struct i2c_payloads *p)
{
	if (!p)
		return;

	dal_vector_destruct(&p->payloads);
}

#define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))

static void i2c_payloads_add(
	struct i2c_payloads *payloads,
	uint32_t address,
	uint32_t len,
	uint8_t *data,
	bool write)
{
	uint32_t payload_size = EDID_SEGMENT_SIZE;
	uint32_t pos;

	for (pos = 0; pos < len; pos += payload_size) {
		struct i2c_payload payload = {
			.write = write,
			.address = (uint8_t)address,
			.length = DDC_MIN(payload_size, len - pos),
			.data = data + pos };
		dal_vector_append(&payloads->payloads, &payload);
	}

}

static void ddc_service_construct(
	struct ddc_service *ddc_service,
	struct ddc_service_init_data *init_data)
{
	enum connector_id connector_id =
		dal_graphics_object_id_get_connector_id(init_data->id);

	struct gpio_service *gpio_service = init_data->ctx->gpio_service;
	struct graphics_object_i2c_info i2c_info;
	struct gpio_ddc_hw_info hw_info;
	struct dc_bios *dcb = init_data->ctx->dc_bios;

	ddc_service->link = init_data->link;
	ddc_service->ctx = init_data->ctx;

	if (ddc_service->link && ddc_service->ctx->dc->config.dp_connector_no_native_i2c &&
		ddc_service->link->no_ddc_pin) {
		// Obtain aux instance info from i2c_info without GPIO DDC pin info
		if (dcb->funcs->get_connector_aux_info(dcb, init_data->id, &i2c_info) == BP_RESULT_OK)
			ddc_service->link->aux_hw_inst = (uint8_t)i2c_info.i2c_line;
	}  else {
		if (init_data->is_dpia_link ||
		dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
			ddc_service->ddc_pin = NULL;
		} else {
			DC_LOGGER_INIT(ddc_service->ctx->logger);
			DC_LOG_DC("BIOS object table - i2c_line: %d", i2c_info.i2c_line);
			DC_LOG_DC("BIOS object table - i2c_engine_id: %d", i2c_info.i2c_engine_id);

			hw_info.ddc_channel = i2c_info.i2c_line;
			if (ddc_service->link != NULL)
				hw_info.hw_supported = i2c_info.i2c_hw_assist;
			else

Annotation

Implementation Notes