[PATCH 2/2] drm/bridge: tc358767: Reset chip again on attach

Marek Vasut marex at denx.de
Mon May 13 02:16:28 UTC 2024


In case the chip is released from reset using the RESX signal while the
DSI lanes are in non-LP11 mode, the chip may enter some sort of debug
mode, where its internal clock run at 1/6th of expected clock rate. In
this mode, the AUX channel also operates at 1/6th of the 10 MHz mandated
by DP specification, which breaks DPCD communication.

There is no known software way of bringing the chip out of this state
once the chip enters it, except for toggling the RESX signal and
performing full reset.

The chip may enter this mode when the chip was released from reset in
probe(), because at that point the DSI lane mode is undefined.

When the .attach callback is called, the DSI link is surely in LP11 mode.
Toggle the RESX signal here and reconfigure the AUX channel. That way,
the AUX channel communication from this point on does surely run at
10 MHz as it should.

Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Adam Ford <aford173 at gmail.com>
Cc: Alexander Stein <alexander.stein at ew.tq-group.com>
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: David Airlie <airlied at gmail.com>
Cc: Frieder Schrempf <frieder.schrempf at kontron.de>
Cc: Inki Dae <inki.dae at samsung.com>
Cc: Jagan Teki <jagan at amarulasolutions.com>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Lucas Stach <l.stach at pengutronix.de>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Marek Szyprowski <m.szyprowski at samsung.com>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Michael Walle <mwalle at kernel.org>
Cc: Neil Armstrong <neil.armstrong at linaro.org>
Cc: Robert Foss <rfoss at kernel.org>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: dri-devel at lists.freedesktop.org
Cc: kernel at dh-electronics.com
---
 drivers/gpu/drm/bridge/tc358767.c | 50 +++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index fe2b93546eaef..9b01dc885973c 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1749,10 +1749,30 @@ static const struct drm_connector_funcs tc_connector_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
+static void tc_bridge_reset(struct tc_data *tc)
+{
+	if (!tc->reset_gpio)
+		return;
+
+	gpiod_set_value_cansleep(tc->reset_gpio, 0);
+	usleep_range(10000, 11000);
+	gpiod_set_value_cansleep(tc->reset_gpio, 1);
+	usleep_range(5000, 10000);
+}
+
 static int tc_dpi_bridge_attach(struct drm_bridge *bridge,
 				enum drm_bridge_attach_flags flags)
 {
 	struct tc_data *tc = bridge_to_tc(bridge);
+	int ret;
+
+	if (tc->reset_gpio) {
+		tc_bridge_reset(tc);
+
+		ret = tc_set_syspllparam(tc);
+		if (ret)
+			return ret;
+	}
 
 	if (!tc->panel_bridge)
 		return 0;
@@ -1769,6 +1789,36 @@ static int tc_edp_bridge_attach(struct drm_bridge *bridge,
 	struct drm_device *drm = bridge->dev;
 	int ret;
 
+	if (tc->reset_gpio) {
+		/*
+		 * In case the chip is released from reset using the RESX
+		 * signal while the DSI lanes are in non-LP11 mode, the chip
+		 * may enter some sort of debug mode, where its internal
+		 * clock run at 1/6th of expected clock rate. In this mode,
+		 * the AUX channel also operates at 1/6th of the 10 MHz
+		 * mandated by DP specification, which breaks DPCD
+		 * communication.
+		 *
+		 * There is no known software way of bringing the chip out of
+		 * this state once the chip enters it, except for toggling
+		 * the RESX signal and performing full reset.
+		 *
+		 * The chip may enter this mode when the chip was released
+		 * from reset in probe(), because at that point the DSI lane
+		 * mode is undefined.
+		 *
+		 * At this point, the DSI link is surely in LP11 mode. Toggle
+		 * the RESX signal here and reconfigure the AUX channel. That
+		 * way, the AUX channel communication from this point on does
+		 * surely run at 10 MHz as it should.
+		 */
+		tc_bridge_reset(tc);
+
+		ret = tc_aux_link_setup(tc);
+		if (ret)
+			return ret;
+	}
+
 	if (tc->panel_bridge) {
 		/* If a connector is required then this driver shall create it */
 		ret = drm_bridge_attach(tc->bridge.encoder, tc->panel_bridge,
-- 
2.43.0



More information about the dri-devel mailing list