public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH] drm/bridge: lt9611uxc: support displays with up to 4 EDID blocks
@ 2026-05-17 18:14 vishnu.saini
  2026-05-17 20:58 ` Dmitry Baryshkov
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: vishnu.saini @ 2026-05-17 18:14 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: dri-devel, linux-kernel, prahlad.valluru, Ravi Agola,
	Vishnu Saini

From: Ravi Agola <raviagol@qti.qualcomm.com>

The LT9611UXC bridge can fetch only 2 EDID blocks at a time, which
previously limited EDID reading to 2 blocks and prevented support
for displays exposing more than 2 EDID blocks.

Extend the driver to support up to 4 EDID blocks by re-triggering
EDID access after the first 2 blocks are read. For block 2, clear
the EDID ready flag in 0xb02a so the bridge can expose the remaining
blocks, then retry the read until the expected EDID is returned.

Also cache the full EDID blob in the driver and reuse it until the
next HPD disconnect event, so repeated EDID reads do not re-query
the bridge.

Signed-off-by: Ravi Agola <raviagol@qti.qualcomm.com>
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
---
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 84 ++++++++++++++++++++++++++----
 1 file changed, 73 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 11aab07d88df..b5a9f62b9fe3 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -28,7 +28,7 @@
 #include <drm/display/drm_hdmi_audio_helper.h>
 
 #define EDID_BLOCK_SIZE	128
-#define EDID_NUM_BLOCKS	2
+#define EDID_NUM_BLOCKS	4
 
 #define FW_FILE "lt9611uxc_fw.bin"
 
@@ -61,6 +61,8 @@ struct lt9611uxc {
 	/* can be accessed from different threads, so protect this with ocm_lock */
 	bool hdmi_connected;
 	uint8_t fw_version;
+
+	const struct drm_edid *edid_data;
 };
 
 #define LT9611_PAGE_CONTROL	0xff
@@ -170,6 +172,12 @@ static void lt9611uxc_hpd_work(struct work_struct *work)
 	connected = lt9611uxc->hdmi_connected;
 	mutex_unlock(&lt9611uxc->ocm_lock);
 
+	if (!connected) {
+		lt9611uxc->edid_read = false;
+		drm_edid_free(lt9611uxc->edid_data);
+		lt9611uxc->edid_data = NULL;
+	}
+
 	drm_bridge_hpd_notify(&lt9611uxc->bridge,
 			      connected ?
 			      connector_status_connected :
@@ -384,10 +392,34 @@ static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc)
 			msecs_to_jiffies(500));
 }
 
+static int lt9611uxc_read_edid_block(struct lt9611uxc *lt9611uxc, unsigned int block,
+				     u8 *buf,  size_t len)
+{
+	int ret;
+
+	lt9611uxc_lock(lt9611uxc);
+
+	regmap_write(lt9611uxc->regmap, 0xb00a, (block%2) * EDID_BLOCK_SIZE);
+
+	ret = regmap_noinc_read(lt9611uxc->regmap, 0xb0b0, buf, len);
+	if (ret) {
+		dev_err(lt9611uxc->dev, "edid block %d read failed: %d\n", block, ret);
+		lt9611uxc_unlock(lt9611uxc);
+		return -EINVAL;
+	}
+	lt9611uxc_unlock(lt9611uxc);
+
+	return ret;
+}
+
 static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
 {
 	struct lt9611uxc *lt9611uxc = data;
-	int ret;
+	int ret = 0;
+	int retry_cnt = 10;
+	int edid_ext_block;
+	const u8 edid_header[8] = { 0x00, 0xFF, 0xFF, 0xFF,
+				    0xFF, 0xFF, 0xFF, 0x00 };
 
 	if (len > EDID_BLOCK_SIZE)
 		return -EINVAL;
@@ -395,19 +427,39 @@ static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, siz
 	if (block >= EDID_NUM_BLOCKS)
 		return -EINVAL;
 
-	lt9611uxc_lock(lt9611uxc);
+	if (block == 2) {
+		lt9611uxc_lock(lt9611uxc);
 
-	regmap_write(lt9611uxc->regmap, 0xb00b, 0x10);
+		/* Read number of block available in EDID data */
+		ret = regmap_read(lt9611uxc->regmap, 0xb02a, &edid_ext_block);
+		if (ret) {
+			dev_err(lt9611uxc->dev, "edid block read failed: %d\n", ret);
+			lt9611uxc_unlock(lt9611uxc);
+			return ret;
+		}
 
-	regmap_write(lt9611uxc->regmap, 0xb00a, block * EDID_BLOCK_SIZE);
+		/* Reset EDID ready flag so that lt9611uxc can read 2nd and 3rd block */
+		regmap_write(lt9611uxc->regmap, 0xb02a, (edid_ext_block & (~BIT(3))));
 
-	ret = regmap_noinc_read(lt9611uxc->regmap, 0xb0b0, buf, len);
-	if (ret)
-		dev_err(lt9611uxc->dev, "edid read failed: %d\n", ret);
+		lt9611uxc_unlock(lt9611uxc);
 
-	lt9611uxc_unlock(lt9611uxc);
+		msleep(100);
 
-	return 0;
+		ret = lt9611uxc_read_edid_block(lt9611uxc, block, buf, len);
+
+		/*
+		 * Compare first 8 bytes of EDID header (0th block) and 2nd block to confirm
+		 * that 2nd EDID block data is read successfully by lt9611uxc
+		 */
+		while (!ret && 0 == memcmp(&edid_header, &buf, 8) && retry_cnt-- > 0) {
+			msleep(100);
+			ret = lt9611uxc_read_edid_block(lt9611uxc, block, buf, len);
+		}
+	} else {
+		ret = lt9611uxc_read_edid_block(lt9611uxc, block, buf, len);
+	}
+
+	return ret;
 };
 
 static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *bridge,
@@ -425,7 +477,17 @@ static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *brid
 		return NULL;
 	}
 
-	return drm_edid_read_custom(connector, lt9611uxc_get_edid_block, lt9611uxc);
+	/* If EDID is read once, provide same EDID data till next HPD event */
+	if (lt9611uxc->edid_data == NULL) {
+		lt9611uxc->edid_data = drm_edid_read_custom(connector, lt9611uxc_get_edid_block,
+							   lt9611uxc);
+	}
+
+	/*
+	 * Copy the EDID data and return the copied value which will be freed by DRM.
+	 * The original EDID data is cached in the driver until the next HPD event.
+	 */
+	return drm_edid_dup(lt9611uxc->edid_data);
 }
 
 static void lt9611uxc_bridge_hpd_notify(struct drm_bridge *bridge,

---
base-commit: 4c26e162947f91aa78ba57dd4fddd38fc80e7d60
change-id: 20260517-lt9611usc_edid34_misc_next-b02592de0b25

Best regards,
-- 
Vishnu Saini <vishnu.saini@oss.qualcomm.com>


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-18  6:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-17 18:14 [PATCH] drm/bridge: lt9611uxc: support displays with up to 4 EDID blocks vishnu.saini
2026-05-17 20:58 ` Dmitry Baryshkov
2026-05-18  0:16 ` kernel test robot
2026-05-18  0:36 ` kernel test robot
2026-05-18  6:00 ` Claude review: " Claude Code Review Bot
2026-05-18  6:00 ` Claude Code Review Bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox