[PATCH v2 2/2] drm: bridge: adv7511: fix edid read in idle state

Emil Abildgaard Svendsen EMAS at bang-olufsen.dk
Fri Oct 27 12:22:35 UTC 2023


Change check of DDC status. Instead of silently not reading EDID when in
"IDLE" state [1]. Always read EDID but add a debug log when DDC
controller is in reset.

[1]
ADV7511 Programming Guide: Table 11: DDCController Status:

  0xC8 [3:0]  DDC Controller State

  0000        In Reset (No Hot Plug Detected)
  0001        Reading EDID
  0010        IDLE (Waiting for HDCP Requested)
  0011        Initializing HDCP
  0100        HDCP Enabled
  0101        Initializing HDCP Repeater

Fixes: 9c8af882bf12 ("drm: Add adv7511 encoder driver")

Signed-off-by: Emil Svendsen <emas at bang-olufsen.dk>
---
v2:
 - Split into two patches.
 - Add Fixes tag.
 - Don't return -EIO when DDC controller is in reset state, only log.

v1: https://lore.kernel.org/all/20231026113029.575846-1-emas@bang-olufsen.dk/

 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 9b6294120516..713ad348dc46 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -537,6 +537,7 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
 				  size_t len)
 {
 	struct adv7511 *adv7511 = data;
+	struct device* dev = &adv7511->i2c_edid->dev;
 	int edid_segment = block / 2;
 	struct i2c_msg xfer[2];
 	uint8_t offset;
@@ -554,15 +555,18 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
 		if (ret < 0)
 			return ret;
 
-		if (status != 2) {
-			adv7511->edid_read = false;
-			regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,
-				     edid_segment);
-			ret = adv7511_wait_for_edid(adv7511, 200);
-			if (ret < 0)
-				return ret;
+		if (!(status & 0x0F)) {
+			dev_dbg(dev, "DDC in reset no hot plug detected %x\n",
+                                status);
 		}
 
+		adv7511->edid_read = false;
+		regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,
+			     edid_segment);
+		ret = adv7511_wait_for_edid(adv7511, 200);
+		if (ret < 0)
+			return ret;
+
 		/* Break this apart, hopefully more I2C controllers will
 		 * support 64 byte transfers than 256 byte transfers
 		 */
-- 
2.34.1


More information about the dri-devel mailing list