drm/bridge: cdns-dsi: Wait for Clk and Data Lanes to be ready
authorAradhya Bhatia <a-bhatia1@ti.com>
Sat, 29 Mar 2025 11:39:16 +0000 (17:09 +0530)
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Sun, 30 Mar 2025 16:47:12 +0000 (19:47 +0300)
Once the DSI Link and DSI Phy are initialized, the code needs to wait
for Clk and Data Lanes to be ready, before continuing configuration.
This is in accordance with the DSI Start-up procedure, found in the
Technical Reference Manual of Texas Instrument's J721E SoC[0] which
houses this DSI TX controller.

If the previous bridge (or crtc/encoder) are configured pre-maturely,
the input signal FIFO gets corrupt. This introduces a color-shift on the
display.

Allow the driver to wait for the clk and data lanes to get ready during
DSI enable.

[0]: See section 12.6.5.7.3 "Start-up Procedure" in J721E SoC TRM
Link: http://www.ti.com/lit/pdf/spruil1
Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver")
Cc: stable@vger.kernel.org
Tested-by: Dominik Haller <d.haller@phytec.de>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Tested-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Signed-off-by: Aradhya Bhatia <a-bhatia1@ti.com>
Signed-off-by: Aradhya Bhatia <aradhya.bhatia@linux.dev>
Link: https://lore.kernel.org/r/20250329113925.68204-6-aradhya.bhatia@linux.dev
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c

index 741d676b8266730b01e9a2b0ea8b9217fbddf2d0..93c3d5f1651d1b5bf4ca8670cf01480f2047376b 100644 (file)
@@ -776,7 +776,7 @@ static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
        struct drm_connector *connector;
        unsigned long tx_byte_period;
        struct cdns_dsi_cfg dsi_cfg;
-       u32 tmp, reg_wakeup, div;
+       u32 tmp, reg_wakeup, div, status;
        int nlanes;
 
        if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
@@ -796,6 +796,19 @@ static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
        cdns_dsi_hs_init(dsi);
        cdns_dsi_init_link(dsi);
 
+       /*
+        * Now that the DSI Link and DSI Phy are initialized,
+        * wait for the CLK and Data Lanes to be ready.
+        */
+       tmp = CLK_LANE_RDY;
+       for (int i = 0; i < nlanes; i++)
+               tmp |= DATA_LANE_RDY(i);
+
+       if (readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status,
+                              (tmp == (status & tmp)), 100, 500000))
+               dev_err(dsi->base.dev,
+                       "Timed Out: DSI-DPhy Clock and Data Lanes not ready.\n");
+
        writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa),
               dsi->regs + VID_HSIZE1);
        writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact),