drivers/gpu/drm/adp/adp-mipi.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/adp/adp-mipi.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/adp/adp-mipi.c
Extension
.c
Size
6825 bytes
Lines
278
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 adp_mipi_drv_private {
	struct mipi_dsi_host dsi;
	struct drm_bridge bridge;
	struct drm_bridge *next_bridge;
	void __iomem *mipi;
};

#define mipi_to_adp(x) container_of(x, struct adp_mipi_drv_private, dsi)

static int adp_dsi_gen_pkt_hdr_write(struct adp_mipi_drv_private *adp, u32 hdr_val)
{
	int ret;
	u32 val, mask;

	ret = readl_poll_timeout(adp->mipi + DSI_CMD_PKT_STATUS,
				 val, !(val & GEN_CMD_FULL), 1000,
				 CMD_PKT_STATUS_TIMEOUT_US);
	if (ret) {
		dev_err(adp->dsi.dev, "failed to get available command FIFO\n");
		return ret;
	}

	writel(hdr_val, adp->mipi + DSI_GEN_HDR);

	mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
	ret = readl_poll_timeout(adp->mipi + DSI_CMD_PKT_STATUS,
				 val, (val & mask) == mask,
				 1000, CMD_PKT_STATUS_TIMEOUT_US);
	if (ret) {
		dev_err(adp->dsi.dev, "failed to write command FIFO\n");
		return ret;
	}

	return 0;
}

static int adp_dsi_write(struct adp_mipi_drv_private *adp,
			 const struct mipi_dsi_packet *packet)
{
	const u8 *tx_buf = packet->payload;
	int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
	__le32 word;
	u32 val;

	while (len) {
		if (len < pld_data_bytes) {
			word = 0;
			memcpy(&word, tx_buf, len);
			writel(le32_to_cpu(word), adp->mipi + DSI_GEN_PLD_DATA);
			len = 0;
		} else {
			memcpy(&word, tx_buf, pld_data_bytes);
			writel(le32_to_cpu(word), adp->mipi + DSI_GEN_PLD_DATA);
			tx_buf += pld_data_bytes;
			len -= pld_data_bytes;
		}

		ret = readl_poll_timeout(adp->mipi + DSI_CMD_PKT_STATUS,
					 val, !(val & GEN_PLD_W_FULL), 1000,
					 CMD_PKT_STATUS_TIMEOUT_US);
		if (ret) {
			dev_err(adp->dsi.dev,
				"failed to get available write payload FIFO\n");
			return ret;
		}
	}

	word = 0;
	memcpy(&word, packet->header, sizeof(packet->header));
	return adp_dsi_gen_pkt_hdr_write(adp, le32_to_cpu(word));
}

static int adp_dsi_read(struct adp_mipi_drv_private *adp,
			const struct mipi_dsi_msg *msg)
{
	int i, j, ret, len = msg->rx_len;
	u8 *buf = msg->rx_buf;
	u32 val;

	/* Wait end of the read operation */
	ret = readl_poll_timeout(adp->mipi + DSI_CMD_PKT_STATUS,
				 val, !(val & GEN_RD_CMD_BUSY),
				 1000, CMD_PKT_STATUS_TIMEOUT_US);
	if (ret) {
		dev_err(adp->dsi.dev, "Timeout during read operation\n");
		return ret;
	}

	for (i = 0; i < len; i += 4) {
		/* Read fifo must not be empty before all bytes are read */

Annotation

Implementation Notes