]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/bridge: tc358768: Fix DSI command tx
authorFrancesco Dolcini <francesco.dolcini@toradex.com>
Thu, 26 Sep 2024 14:12:46 +0000 (16:12 +0200)
committerNeil Armstrong <neil.armstrong@linaro.org>
Thu, 14 Nov 2024 10:29:42 +0000 (11:29 +0100)
Wait for the command transmission to be completed in the DSI transfer
function polling for the dc_start bit to go back to idle state after the
transmission is started.

This is documented in the datasheet and failures to do so lead to
commands corruption.

Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
Cc: stable@vger.kernel.org
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20240926141246.48282-1-francesco@dolcini.it
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240926141246.48282-1-francesco@dolcini.it
drivers/gpu/drm/bridge/tc358768.c

index 0e8813278a2fa5feff1b986bed68547d5a8f2ab6..bb1750a3dab0dc71e807007ccb0fa19b7c837b63 100644 (file)
 #define TC358768_DSI_CONFW_MODE_CLR    (6 << 29)
 #define TC358768_DSI_CONFW_ADDR_DSI_CONTROL    (0x3 << 24)
 
+/* TC358768_DSICMD_TX (0x0600) register */
+#define TC358768_DSI_CMDTX_DC_START    BIT(0)
+
 static const char * const tc358768_supplies[] = {
        "vddc", "vddmipi", "vddio"
 };
@@ -229,6 +232,21 @@ static void tc358768_update_bits(struct tc358768_priv *priv, u32 reg, u32 mask,
                tc358768_write(priv, reg, tmp);
 }
 
+static void tc358768_dsicmd_tx(struct tc358768_priv *priv)
+{
+       u32 val;
+
+       /* start transfer */
+       tc358768_write(priv, TC358768_DSICMD_TX, TC358768_DSI_CMDTX_DC_START);
+       if (priv->error)
+               return;
+
+       /* wait transfer completion */
+       priv->error = regmap_read_poll_timeout(priv->regmap, TC358768_DSICMD_TX, val,
+                                              (val & TC358768_DSI_CMDTX_DC_START) == 0,
+                                              100, 100000);
+}
+
 static int tc358768_sw_reset(struct tc358768_priv *priv)
 {
        /* Assert Reset */
@@ -516,8 +534,7 @@ static ssize_t tc358768_dsi_host_transfer(struct mipi_dsi_host *host,
                }
        }
 
-       /* start transfer */
-       tc358768_write(priv, TC358768_DSICMD_TX, 1);
+       tc358768_dsicmd_tx(priv);
 
        ret = tc358768_clear_error(priv);
        if (ret)