drivers/gpu/drm/panel/panel-raydium-rm68200.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-raydium-rm68200.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-raydium-rm68200.c
Extension
.c
Size
12212 bytes
Lines
404
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 rm68200 {
	struct device *dev;
	struct drm_panel panel;
	struct gpio_desc *reset_gpio;
	struct regulator *supply;
};

static const struct drm_display_mode default_mode = {
	.clock = 54000,
	.hdisplay = 720,
	.hsync_start = 720 + 48,
	.hsync_end = 720 + 48 + 9,
	.htotal = 720 + 48 + 9 + 48,
	.vdisplay = 1280,
	.vsync_start = 1280 + 12,
	.vsync_end = 1280 + 12 + 5,
	.vtotal = 1280 + 12 + 5 + 12,
	.flags = 0,
	.width_mm = 68,
	.height_mm = 122,
};

static inline struct rm68200 *panel_to_rm68200(struct drm_panel *panel)
{
	return container_of(panel, struct rm68200, panel);
}

static void rm68200_dcs_write_buf(struct rm68200 *ctx, const void *data,
				  size_t len)
{
	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
	int err;

	err = mipi_dsi_dcs_write_buffer(dsi, data, len);
	if (err < 0)
		dev_err_ratelimited(ctx->dev, "MIPI DSI DCS write buffer failed: %d\n", err);
}

static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value)
{
	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
	int err;

	err = mipi_dsi_dcs_write(dsi, cmd, &value, 1);
	if (err < 0)
		dev_err_ratelimited(ctx->dev, "MIPI DSI DCS write failed: %d\n", err);
}

#define dcs_write_seq(ctx, seq...)				\
({								\
	static const u8 d[] = { seq };				\
								\
	rm68200_dcs_write_buf(ctx, d, ARRAY_SIZE(d));		\
})

/*
 * This panel is not able to auto-increment all cmd addresses so for some of
 * them, we need to send them one by one...
 */
#define dcs_write_cmd_seq(ctx, cmd, seq...)			\
({								\
	static const u8 d[] = { seq };				\
	unsigned int i;						\
								\
	for (i = 0; i < ARRAY_SIZE(d) ; i++)			\
		rm68200_dcs_write_cmd(ctx, cmd + i, d[i]);	\
})

static void rm68200_init_sequence(struct rm68200 *ctx)
{
	/* Enter CMD2 with page 0 */
	dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P0);
	dcs_write_cmd_seq(ctx, MCS_EXT_PWR_IC, 0xC0, 0x53, 0x00);
	dcs_write_seq(ctx, MCS_BT2CTR, 0xE5);
	dcs_write_seq(ctx, MCS_SETAVDD, 0x0A);
	dcs_write_seq(ctx, MCS_SETAVEE, 0x0A);
	dcs_write_seq(ctx, MCS_SGOPCTR, 0x52);
	dcs_write_seq(ctx, MCS_BT3CTR, 0x53);
	dcs_write_seq(ctx, MCS_BT4CTR, 0x5A);
	dcs_write_seq(ctx, MCS_INVCTR, 0x00);
	dcs_write_seq(ctx, MCS_STBCTR, 0x0A);
	dcs_write_seq(ctx, MCS_SDCTR, 0x06);
	dcs_write_seq(ctx, MCS_VCMCTR, 0x56);
	dcs_write_seq(ctx, MCS_SETVGN, 0xA0, 0x00);
	dcs_write_seq(ctx, MCS_SETVGP, 0xA0, 0x00);
	dcs_write_seq(ctx, MCS_SW_CTRL, 0x11); /* 2 data lanes, see doc */

	dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P2);
	dcs_write_seq(ctx, GOA_VSTV1, 0x05);
	dcs_write_seq(ctx, 0x02, 0x0B);

Annotation

Implementation Notes