* [PATCH 3/3] drm/panel: raydium-rm68200: Use multi-context helpers for init sequence
2026-10-14 13:50 [PATCH 0/3] drm/panel: Use mipi_dsi_*_multi() in feiyang and rm68200 Hsieh Hung-En
2026-10-14 13:50 ` [PATCH 1/3] drm/panel: feiyang-fy07024di26a30d: Use mipi_dsi_*_multi() functions Hsieh Hung-En
2026-10-14 13:50 ` [PATCH 2/3] drm/panel: raydium-rm68200: " Hsieh Hung-En
@ 2026-10-14 13:50 ` Hsieh Hung-En
2 siblings, 0 replies; 4+ messages in thread
From: Hsieh Hung-En @ 2026-10-14 13:50 UTC (permalink / raw)
To: dianders, neil.armstrong, jesszhan0024
Cc: jagan, osama.abdelkader, dri-devel, linux-kernel,
maarten.lankhorst, mripard, tzimmermann, airlied, simona,
Hsieh Hung-En
Replace the custom DCS write helpers with mipi_dsi_dcs_write_seq_multi()
and mipi_dsi_dcs_write_var_seq_multi(), preserving individual DCS
transactions for registers that do not support auto-increment.
Previously, initialization failures were only logged, allowing prepare()
to report success despite incomplete initialization. Share the
multi-context with prepare() so that after the first failed write,
subsequent DCS commands and delays are skipped, and the error is
propagated to prepare().
The new helpers log errors without rate limiting.
Signed-off-by: Hsieh Hung-En <hungen3108@gmail.com>
---
drivers/gpu/drm/panel/panel-raydium-rm68200.c | 184 ++++++++----------
1 file changed, 80 insertions(+), 104 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
index 971d075bb060..a01b2db55c7f 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm68200.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
@@ -98,134 +98,110 @@ 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...
+ *
+ * Use arr instead of d to avoid shadowing the local d[] declared by
+ * mipi_dsi_dcs_write_var_seq_multi().
*/
-#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)
+#define dcs_write_cmd_seq(dsi_ctx, cmd, seq...) \
+ do { \
+ static const u8 arr[] = { seq }; \
+ unsigned int i; \
+ \
+ for (i = 0; i < ARRAY_SIZE(arr); i++) \
+ mipi_dsi_dcs_write_var_seq_multi(dsi_ctx, \
+ (cmd) + i, arr[i]); \
+ } while (0)
+
+static void rm68200_init_sequence(struct mipi_dsi_multi_context *dsi_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);
- dcs_write_seq(ctx, 0x03, 0x0F);
- dcs_write_seq(ctx, 0x04, 0x7D, 0x00, 0x50);
- dcs_write_cmd_seq(ctx, GOA_VSTV2, 0x05, 0x16, 0x0D, 0x11, 0x7D, 0x00,
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_CMD_MODE_SW, MCS_CMD2_P0);
+ dcs_write_cmd_seq(dsi_ctx, MCS_EXT_PWR_IC, 0xC0, 0x53, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_BT2CTR, 0xE5);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SETAVDD, 0x0A);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SETAVEE, 0x0A);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SGOPCTR, 0x52);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_BT3CTR, 0x53);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_BT4CTR, 0x5A);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_INVCTR, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_STBCTR, 0x0A);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SDCTR, 0x06);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_VCMCTR, 0x56);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SETVGN, 0xA0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SETVGP, 0xA0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_SW_CTRL, 0x11); /* 2 data lanes, see doc */
+
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_CMD_MODE_SW, MCS_CMD2_P2);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, GOA_VSTV1, 0x05);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x02, 0x0B);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x03, 0x0F);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x04, 0x7D, 0x00, 0x50);
+ dcs_write_cmd_seq(dsi_ctx, GOA_VSTV2, 0x05, 0x16, 0x0D, 0x11, 0x7D, 0x00,
0x50);
- dcs_write_cmd_seq(ctx, GOA_VCLK1, 0x07, 0x08, 0x01, 0x02, 0x00, 0x7D,
+ dcs_write_cmd_seq(dsi_ctx, GOA_VCLK1, 0x07, 0x08, 0x01, 0x02, 0x00, 0x7D,
0x00, 0x85, 0x08);
- dcs_write_cmd_seq(ctx, GOA_VCLK2, 0x03, 0x04, 0x05, 0x06, 0x00, 0x7D,
+ dcs_write_cmd_seq(dsi_ctx, GOA_VCLK2, 0x03, 0x04, 0x05, 0x06, 0x00, 0x7D,
0x00, 0x85, 0x08);
- dcs_write_seq(ctx, GOA_VCLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00);
- dcs_write_cmd_seq(ctx, GOA_BICLK1, 0x07, 0x08);
- dcs_write_seq(ctx, 0x2D, 0x01);
- dcs_write_seq(ctx, 0x2F, 0x02, 0x00, 0x40, 0x05, 0x08, 0x54, 0x7D,
- 0x00);
- dcs_write_cmd_seq(ctx, GOA_BICLK2, 0x03, 0x04, 0x05, 0x06, 0x00);
- dcs_write_seq(ctx, 0x3D, 0x40);
- dcs_write_seq(ctx, 0x3F, 0x05, 0x08, 0x54, 0x7D, 0x00);
- dcs_write_seq(ctx, GOA_BICLK3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00);
- dcs_write_seq(ctx, GOA_BICLK4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00);
- dcs_write_seq(ctx, 0x58, 0x00, 0x00, 0x00);
- dcs_write_seq(ctx, GOA_BICLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00);
- dcs_write_seq(ctx, GOA_BICLK_OPT2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- dcs_write_seq(ctx, MCS_GOA_GPO1, 0x00, 0x00, 0x00, 0x00);
- dcs_write_seq(ctx, MCS_GOA_GPO2, 0x00, 0x20, 0x00);
- dcs_write_seq(ctx, MCS_GOA_EQ, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x00, 0x00);
- dcs_write_seq(ctx, MCS_GOA_CLK_GALLON, 0x00, 0x00);
- dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL0, 0xBF, 0x02, 0x06, 0x14, 0x10,
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, GOA_VCLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00);
+ dcs_write_cmd_seq(dsi_ctx, GOA_BICLK1, 0x07, 0x08);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x2D, 0x01);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x2F, 0x02, 0x00, 0x40, 0x05, 0x08, 0x54, 0x7D,
+ 0x00);
+ dcs_write_cmd_seq(dsi_ctx, GOA_BICLK2, 0x03, 0x04, 0x05, 0x06, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x3D, 0x40);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x3F, 0x05, 0x08, 0x54, 0x7D, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, GOA_BICLK3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, GOA_BICLK4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x58, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, GOA_BICLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, GOA_BICLK_OPT2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_GOA_GPO1, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_GOA_GPO2, 0x00, 0x20, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_GOA_EQ, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_GOA_CLK_GALLON, 0x00, 0x00);
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_FS_SEL0, 0xBF, 0x02, 0x06, 0x14, 0x10,
0x16, 0x12, 0x08, 0x3F);
- dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0C,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_FS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0C,
0x0A, 0x0E, 0x3F, 0x3F, 0x00);
- dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL2, 0x04, 0x3F, 0x3F, 0x3F, 0x3F,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_FS_SEL2, 0x04, 0x3F, 0x3F, 0x3F, 0x3F,
0x05, 0x01, 0x3F, 0x3F, 0x0F);
- dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL3, 0x0B, 0x0D, 0x3F, 0x3F, 0x3F,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_FS_SEL3, 0x0B, 0x0D, 0x3F, 0x3F, 0x3F,
0x3F);
- dcs_write_cmd_seq(ctx, 0xA2, 0x3F, 0x09, 0x13, 0x17, 0x11, 0x15);
- dcs_write_cmd_seq(ctx, 0xA9, 0x07, 0x03, 0x3F);
- dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL0, 0x3F, 0x05, 0x01, 0x17, 0x13,
+ dcs_write_cmd_seq(dsi_ctx, 0xA2, 0x3F, 0x09, 0x13, 0x17, 0x11, 0x15);
+ dcs_write_cmd_seq(dsi_ctx, 0xA9, 0x07, 0x03, 0x3F);
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_BS_SEL0, 0x3F, 0x05, 0x01, 0x17, 0x13,
0x15, 0x11, 0x0F, 0x3F);
- dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0B,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_BS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0B,
0x0D, 0x09, 0x3F, 0x3F, 0x07);
- dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL2, 0x03, 0x3F, 0x3F, 0x3F, 0x3F,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_BS_SEL2, 0x03, 0x3F, 0x3F, 0x3F, 0x3F,
0x02, 0x06, 0x3F, 0x3F, 0x08);
- dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL3, 0x0C, 0x0A, 0x3F, 0x3F, 0x3F,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_BS_SEL3, 0x0C, 0x0A, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x0E, 0x10, 0x14);
- dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL4, 0x12, 0x16, 0x00, 0x04, 0x3F);
- dcs_write_seq(ctx, 0xDC, 0x02);
- dcs_write_seq(ctx, 0xDE, 0x12);
+ dcs_write_cmd_seq(dsi_ctx, MCS_GOA_BS_SEL4, 0x12, 0x16, 0x00, 0x04, 0x3F);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xDC, 0x02);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xDE, 0x12);
- dcs_write_seq(ctx, MCS_CMD_MODE_SW, 0x0E); /* No documentation */
- dcs_write_seq(ctx, 0x01, 0x75);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_CMD_MODE_SW, 0x0E); /* No documentation */
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x01, 0x75);
- dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P3);
- dcs_write_cmd_seq(ctx, MCS_GAMMA_VP, 0x00, 0x0C, 0x12, 0x0E, 0x06,
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_CMD_MODE_SW, MCS_CMD2_P3);
+ dcs_write_cmd_seq(dsi_ctx, MCS_GAMMA_VP, 0x00, 0x0C, 0x12, 0x0E, 0x06,
0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
0x12, 0x0C, 0x00);
- dcs_write_cmd_seq(ctx, MCS_GAMMA_VN, 0x00, 0x0C, 0x12, 0x0E, 0x06,
+ dcs_write_cmd_seq(dsi_ctx, MCS_GAMMA_VN, 0x00, 0x0C, 0x12, 0x0E, 0x06,
0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
0x12, 0x0C, 0x00);
/* Exit CMD2 */
- dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD1_UCS);
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, MCS_CMD_MODE_SW, MCS_CMD1_UCS);
}
static int rm68200_unprepare(struct drm_panel *panel)
@@ -272,7 +248,7 @@ static int rm68200_prepare(struct drm_panel *panel)
msleep(100);
}
- rm68200_init_sequence(ctx);
+ rm68200_init_sequence(&dsi_ctx);
mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread