drivers/gpu/drm/i915/display/intel_dsi_vbt.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_dsi_vbt.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_dsi_vbt.c
Extension
.c
Size
29665 bytes
Lines
961
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_adapter_lookup {
	u16 target_addr;
	struct intel_dsi *intel_dsi;
	acpi_handle dev_handle;
};

#define CHV_GPIO_IDX_START_N		0
#define CHV_GPIO_IDX_START_E		73
#define CHV_GPIO_IDX_START_SW		100
#define CHV_GPIO_IDX_START_SE		198

/* ICL DSI Display GPIO Pins */
#define  ICL_GPIO_DDSP_HPD_A		0
#define  ICL_GPIO_L_VDDEN_1		1
#define  ICL_GPIO_L_BKLTEN_1		2
#define  ICL_GPIO_DDPA_CTRLCLK_1	3
#define  ICL_GPIO_DDPA_CTRLDATA_1	4
#define  ICL_GPIO_DDSP_HPD_B		5
#define  ICL_GPIO_L_VDDEN_2		6
#define  ICL_GPIO_L_BKLTEN_2		7
#define  ICL_GPIO_DDPA_CTRLCLK_2	8
#define  ICL_GPIO_DDPA_CTRLDATA_2	9

static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi,
					    u8 seq_port)
{
	/*
	 * If single link DSI is being used on any port, the VBT sequence block
	 * send packet apparently always has 0 for the port. Just use the port
	 * we have configured, and ignore the sequence block port.
	 */
	if (hweight8(intel_dsi->ports) == 1)
		return ffs(intel_dsi->ports) - 1;

	if (seq_port) {
		if (intel_dsi->ports & BIT(PORT_B))
			return PORT_B;
		if (intel_dsi->ports & BIT(PORT_C))
			return PORT_C;
	}

	return PORT_A;
}

static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi,
				       const u8 *data)
{
	struct intel_display *display = to_intel_display(&intel_dsi->base);
	struct mipi_dsi_device *dsi_device;
	u8 type, flags, seq_port;
	u16 len;
	enum port port;
	ssize_t ret;
	bool hs_mode;

	flags = *data++;
	type = *data++;

	len = *((u16 *) data);
	data += 2;

	seq_port = (flags >> MIPI_PORT_SHIFT) & 3;

	port = intel_dsi_seq_port_to_port(intel_dsi, seq_port);

	if (drm_WARN_ON(display->drm, !intel_dsi->dsi_hosts[port]))
		goto out;

	dsi_device = intel_dsi->dsi_hosts[port]->device;
	if (!dsi_device) {
		drm_dbg_kms(display->drm, "no dsi device for port %c\n",
			    port_name(port));
		goto out;
	}

	hs_mode = (flags >> MIPI_TRANSFER_MODE_SHIFT) & 1;
	if (hs_mode)
		dsi_device->mode_flags &= ~MIPI_DSI_MODE_LPM;
	else
		dsi_device->mode_flags |= MIPI_DSI_MODE_LPM;

	dsi_device->channel = (flags >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 3;

	drm_dbg_kms(display->drm, "DSI packet: Port %c (seq %u), Flags 0x%02x, VC %u, %s, Type 0x%02x, Length %u, Data %*ph\n",
		    port_name(port), seq_port, flags, dsi_device->channel,
		    hs_mode ? "HS" : "LP", type, len, (int)len, data);

	switch (type) {
	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
		ret = mipi_dsi_generic_write(dsi_device, NULL, 0);

Annotation

Implementation Notes