Commit 3ef76c6a authored by Francesco Dolcini's avatar Francesco Dolcini Committed by Wen Zhiwei
Browse files

drm/bridge: tc358768: Fix DSI command tx

stable inclusion
from stable-v6.6.63
commit 1a312ed8f9b232b61ed824365e737af4fcff38fe
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBI1RP

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1a312ed8f9b232b61ed824365e737af4fcff38fe



--------------------------------

commit 32c4514455b2b8fde506f8c0962f15c7e4c26f1d upstream.

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: ff1ca639 ("drm/bridge: Add tc358768 driver")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarFrancesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20240926141246.48282-1-francesco@dolcini.it


Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240926141246.48282-1-francesco@dolcini.it


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarWen Zhiwei <wenzhiwei@kylinos.cn>
parent 23e1d75b
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@
#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)