[PATCH RFC 09/10] drm/msm/dsi: separate host link enable from video stream enable

From: YİĞİTCAN KAVAKLI via B4 Relay

Date: Fri Sep 11 2026 - 05:00:08 EST


From: YİĞİTCAN KAVAKLI <kavakliyigitcan@xxxxxxxxx>

In video mode DSI displays, enabling the host previously engaged the
hardware video engine immediately during atomic_pre_enable. When panel
prepare routines transmit initial DCS sleep-out and setup commands,
concurrent active video transmission causes DMA timeouts (-110).

Keep the DSI host in command mode during atomic_pre_enable to permit
clean panel preparation, and start video streaming in atomic_enable
after the panel has completed initialization.

Signed-off-by: YİĞİTCAN KAVAKLI <kavakliyigitcan@xxxxxxxxx>
---
drivers/gpu/drm/msm/dsi/dsi.h | 1 +
drivers/gpu/drm/msm/dsi/dsi_host.c | 23 ++++++++++++-----------
drivers/gpu/drm/msm/dsi/dsi_manager.c | 20 ++++++++++++++++++++
3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 93c028a122f3a59b1632da76472e0a3e781c6ae8..cfb2b51cae0a9227fbe88ecc5291ac1a9f82a5ce 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -69,6 +69,7 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host,
u32 dma_base, u32 len);
int msm_dsi_host_enable(struct mipi_dsi_host *host);
+void msm_dsi_host_enable_video(struct mipi_dsi_host *host);
int msm_dsi_host_disable(struct mipi_dsi_host *host);
void msm_dsi_host_enable_irq(struct mipi_dsi_host *host);
void msm_dsi_host_disable_irq(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index b9e2867d435a3ad8b6db6b57c440bbd827180b6e..b2702f772ee195b2758433d98d0f071e3f55955e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2438,22 +2438,23 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
{
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);

- dsi_op_mode_config(msm_host,
- !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), true);
-
- /* TODO: clock should be turned off for command mode,
- * and only turned on before MDP START.
- * This part of code should be enabled once mdp driver support it.
- */
- /* if (msm_panel->mode == MSM_DSI_CMD_MODE) {
- * dsi_link_clk_disable(msm_host);
- * pm_runtime_put(&msm_host->pdev->dev);
- * }
+ /* Keep DSI host in command mode (VID_MODE_EN = 0) during panel init
+ * to allow clean DCS communication without premature video engine startup.
*/
+ dsi_op_mode_config(msm_host, false, true);
+
msm_host->enabled = true;
return 0;
}

+void msm_dsi_host_enable_video(struct mipi_dsi_host *host)
+{
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+ if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
+ dsi_op_mode_config(msm_host, true, true);
+}
+
int msm_dsi_host_disable(struct mipi_dsi_host *host)
{
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 959daa88b1d022da5f552bb21ca7c04006524fa4..9e3f125ec4ea8e3fae50c8226e67b4106c01dc76 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -446,12 +446,32 @@ static int dsi_mgr_bridge_attach(struct drm_bridge *bridge,
bridge, flags);
}

+static void dsi_mgr_bridge_enable(struct drm_bridge *bridge,
+ struct drm_atomic_commit *commit)
+{
+ int id = dsi_mgr_bridge_get_id(bridge);
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+ struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
+ struct mipi_dsi_host *host = msm_dsi->host;
+ bool is_bonded_dsi = IS_BONDED_DSI();
+
+ DBG("id=%d", id);
+
+ if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+ return;
+
+ msm_dsi_host_enable_video(host);
+ if (is_bonded_dsi && msm_dsi1)
+ msm_dsi_host_enable_video(msm_dsi1->host);
+}
+
static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
.atomic_create_state = drm_atomic_helper_bridge_create_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.attach = dsi_mgr_bridge_attach,
.atomic_pre_enable = dsi_mgr_bridge_pre_enable,
+ .atomic_enable = dsi_mgr_bridge_enable,
.atomic_post_disable = dsi_mgr_bridge_post_disable,
.mode_set = dsi_mgr_bridge_mode_set,
.mode_valid = dsi_mgr_bridge_mode_valid,

--
2.47.3