From: YİĞİTCAN KAVAKLI <[email protected]>

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 <[email protected]>
---
 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


Reply via email to