* [PATCH 1/2] drm/panel: visionox-rm69299: Split DSI commands out into enable/disable
2026-04-27 13:56 [PATCH 0/2] drm/panel/visionox-rm69299: Split DSI commands out into enable/disable Guido Günther
@ 2026-04-27 13:56 ` Guido Günther
2026-04-28 4:33 ` Claude review: " Claude Code Review Bot
2026-04-27 13:56 ` [PATCH 2/2] drm/panel: visionox-rm69299: Move power_on/off into prepare/unprepare Guido Günther
2026-04-28 4:33 ` Claude review: drm/panel/visionox-rm69299: Split DSI commands out into enable/disable Claude Code Review Bot
2 siblings, 1 reply; 6+ messages in thread
From: Guido Günther @ 2026-04-27 13:56 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, phone-devel, David Heidelberg,
Guido Günther
It's when DSI commands should be sent and it also fixes these DSI errors
on every screen blank/unblank on the SHIFT6mq:
dmesg:
msm_dsi ae94000.dsi: [drm:dsi_cmds2buf_tx] *ERROR* wait for video done timed out
dsi_cmds2buf_tx: cmd dma tx failed, type=0x5, data0=0x28, len=4, ret=-110
panel-visionox-rm69299 ae94000.dsi.0: sending DCS SET_DISPLAY_OFF failed: -110
Signed-off-by: Guido Günther <agx@sigxcpu.org>
---
drivers/gpu/drm/panel/panel-visionox-rm69299.c | 77 +++++++++++++++-----------
1 file changed, 44 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
index f1430370ff94..3c92a6ceb8df 100644
--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c
+++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
@@ -158,6 +158,46 @@ static inline struct visionox_rm69299 *panel_to_ctx(struct drm_panel *panel)
return container_of(panel, struct visionox_rm69299, panel);
}
+static int visionox_rm69299_enable(struct drm_panel *panel)
+{
+ struct visionox_rm69299 *ctx = panel_to_ctx(panel);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+ ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ for (int i = 0; i < ctx->desc->init_seq_len; i++)
+ mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, &ctx->desc->init_seq[i * 2], 2);
+
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+
+ /* Per DSI spec wait 120ms after sending exit sleep DCS command */
+ mipi_dsi_msleep(&dsi_ctx, 120);
+
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+
+ /* Per DSI spec wait 120ms after sending set_display_on DCS command */
+ mipi_dsi_msleep(&dsi_ctx, 120);
+
+ return dsi_ctx.accum_err;
+}
+
+static int visionox_rm69299_disable(struct drm_panel *panel)
+{
+ struct visionox_rm69299 *ctx = panel_to_ctx(panel);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+
+ /* 120ms delay required here as per DCS spec */
+ mipi_dsi_msleep(&dsi_ctx, 120);
+
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+
+ return dsi_ctx.accum_err;
+}
+
static int visionox_rm69299_power_on(struct visionox_rm69299 *ctx)
{
int ret;
@@ -193,16 +233,6 @@ static int visionox_rm69299_power_off(struct visionox_rm69299 *ctx)
static int visionox_rm69299_unprepare(struct drm_panel *panel)
{
struct visionox_rm69299 *ctx = panel_to_ctx(panel);
- struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
-
- ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
-
- mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
-
- /* 120ms delay required here as per DCS spec */
- mipi_dsi_msleep(&dsi_ctx, 120);
-
- mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
return visionox_rm69299_power_off(ctx);
}
@@ -210,29 +240,8 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel)
static int visionox_rm69299_prepare(struct drm_panel *panel)
{
struct visionox_rm69299 *ctx = panel_to_ctx(panel);
- struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
- int ret, i;
- ret = visionox_rm69299_power_on(ctx);
- if (ret < 0)
- return ret;
-
- ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
-
- for (i = 0; i < ctx->desc->init_seq_len; i++)
- mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, &ctx->desc->init_seq[i * 2], 2);
-
- mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
-
- /* Per DSI spec wait 120ms after sending exit sleep DCS command */
- mipi_dsi_msleep(&dsi_ctx, 120);
-
- mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
-
- /* Per DSI spec wait 120ms after sending set_display_on DCS command */
- mipi_dsi_msleep(&dsi_ctx, 120);
-
- return dsi_ctx.accum_err;
+ return visionox_rm69299_power_on(ctx);
}
static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = {
@@ -284,7 +293,9 @@ static int visionox_rm69299_get_modes(struct drm_panel *panel,
static const struct drm_panel_funcs visionox_rm69299_drm_funcs = {
.unprepare = visionox_rm69299_unprepare,
- .prepare = visionox_rm69299_prepare,
+ .disable = visionox_rm69299_disable,
+ .prepare = visionox_rm69299_prepare,
+ .enable = visionox_rm69299_enable,
.get_modes = visionox_rm69299_get_modes,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/2] drm/panel: visionox-rm69299: Move power_on/off into prepare/unprepare
2026-04-27 13:56 [PATCH 0/2] drm/panel/visionox-rm69299: Split DSI commands out into enable/disable Guido Günther
2026-04-27 13:56 ` [PATCH 1/2] drm/panel: visionox-rm69299: " Guido Günther
@ 2026-04-27 13:56 ` Guido Günther
2026-04-28 4:33 ` Claude review: " Claude Code Review Bot
2026-04-28 4:33 ` Claude review: drm/panel/visionox-rm69299: Split DSI commands out into enable/disable Claude Code Review Bot
2 siblings, 1 reply; 6+ messages in thread
From: Guido Günther @ 2026-04-27 13:56 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, phone-devel, David Heidelberg,
Guido Günther
No need to have separate functions now that prepare/unprepare only
handle powering on & off.
Signed-off-by: Guido Günther <agx@sigxcpu.org>
---
drivers/gpu/drm/panel/panel-visionox-rm69299.c | 36 +++++++++-----------------
1 file changed, 12 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
index 3c92a6ceb8df..5c869d353368 100644
--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c
+++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
@@ -198,15 +198,25 @@ static int visionox_rm69299_disable(struct drm_panel *panel)
return dsi_ctx.accum_err;
}
-static int visionox_rm69299_power_on(struct visionox_rm69299 *ctx)
+static int visionox_rm69299_unprepare(struct drm_panel *panel)
+{
+ struct visionox_rm69299 *ctx = panel_to_ctx(panel);
+
+ gpiod_set_value(ctx->reset_gpio, 0);
+
+ return regulator_bulk_disable(ARRAY_SIZE(visionox_rm69299_supplies),
+ ctx->supplies);
+}
+
+static int visionox_rm69299_prepare(struct drm_panel *panel)
{
int ret;
+ struct visionox_rm69299 *ctx = panel_to_ctx(panel);
ret = regulator_bulk_enable(ARRAY_SIZE(visionox_rm69299_supplies),
ctx->supplies);
if (ret < 0)
return ret;
-
/*
* Reset sequence of visionox panel requires the panel to be
* out of reset for 10ms, followed by being held in reset
@@ -222,28 +232,6 @@ static int visionox_rm69299_power_on(struct visionox_rm69299 *ctx)
return 0;
}
-static int visionox_rm69299_power_off(struct visionox_rm69299 *ctx)
-{
- gpiod_set_value(ctx->reset_gpio, 0);
-
- return regulator_bulk_disable(ARRAY_SIZE(visionox_rm69299_supplies),
- ctx->supplies);
-}
-
-static int visionox_rm69299_unprepare(struct drm_panel *panel)
-{
- struct visionox_rm69299 *ctx = panel_to_ctx(panel);
-
- return visionox_rm69299_power_off(ctx);
-}
-
-static int visionox_rm69299_prepare(struct drm_panel *panel)
-{
- struct visionox_rm69299 *ctx = panel_to_ctx(panel);
-
- return visionox_rm69299_power_on(ctx);
-}
-
static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = {
.name = "1080x2248",
.clock = 158695,
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread