From c2496bc62e6ce4ff7e54d0985b0167246bdeb7d8 Mon Sep 17 00:00:00 2001 From: Xin Ji Date: Mon, 26 May 2025 14:56:17 +0800 Subject: [PATCH] drivers/analogix/anx7625: Add a retry mechanism to decode EDID Anx7625 reads EDID through AUX channel with I2C Over Aux operation, reading 16-byte chunk a time. Sometimes, panel(CSOT MNB601LS1-3) does not returns EDID raw data in time or returns OK without providing data. Root cause: The measured difference between two adjacent UI signals of the AUX signal is 36ns (518 - 482ns), it meets the VESA DP1.2/1.3 spec < 0.08UI (48ns) requirement. However, this value exceeds the VESA DP1.1a spec supported by the panel: max < 0.04UI (24ns) requirement, which exceeds the tolerance value of the panel and leads to EDID communication failure. To address this issue, determined by tests, so that the issue did not reproduce in over 200 tests Test result: Verified on 12pcs panels(8pcs issue panels, 4pcs new panels), 10pcs tested 300 cycles, 2pcs tested 400 cycles, issue cannot be reproduced. BUG=b:415946451 TEST=Tested on corsola over 200 times BRANCH=corsola Change-Id: I2d4f6b65b8f663ea9b9459e0343897a1223d631a Signed-off-by: Xin Ji Reviewed-on: https://review.coreboot.org/c/coreboot/+/87961 Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu --- src/drivers/analogix/anx7625/anx7625.c | 27 +++++++++++++++----------- src/drivers/analogix/anx7625/anx7625.h | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/drivers/analogix/anx7625/anx7625.c b/src/drivers/analogix/anx7625/anx7625.c index 4792d07296..ed5000fb75 100644 --- a/src/drivers/analogix/anx7625/anx7625.c +++ b/src/drivers/analogix/anx7625/anx7625.c @@ -830,20 +830,25 @@ int anx7625_dp_get_edid(uint8_t bus, struct edid *out) int block_num; int ret; u8 edid[FOUR_BLOCK_SIZE]; + int i; - block_num = sp_tx_edid_read(bus, edid, FOUR_BLOCK_SIZE); - if (block_num < 0) { - ANXERROR("Failed to get eDP EDID.\n"); - return -1; + for (i = 0; i < EDID_RETRY; i++) { + block_num = sp_tx_edid_read(bus, edid, FOUR_BLOCK_SIZE); + if (block_num < 0) { + ANXERROR("Failed to get eDP EDID(retry %d).\n", i); + continue; + } + + ret = decode_edid(edid, (block_num + 1) * ONE_BLOCK_SIZE, out); + if (ret == EDID_CONFORMANT) { + ANXINFO("Success read out EDID(retry %d).\n", i); + return 0; + } + + ANXERROR("Failed to decode EDID(retry %d).\n", i); } - ret = decode_edid(edid, (block_num + 1) * ONE_BLOCK_SIZE, out); - if (ret != EDID_CONFORMANT) { - ANXERROR("Failed to decode EDID.\n"); - return -1; - } - - return 0; + return -1; } int anx7625_init(uint8_t bus) diff --git a/src/drivers/analogix/anx7625/anx7625.h b/src/drivers/analogix/anx7625/anx7625.h index f14f8bd0a6..51973ffbd8 100644 --- a/src/drivers/analogix/anx7625/anx7625.h +++ b/src/drivers/analogix/anx7625/anx7625.h @@ -339,6 +339,7 @@ enum AudioWdLen { #define ONE_BLOCK_SIZE 128 #define FOUR_BLOCK_SIZE (128*4) +#define EDID_RETRY 3 struct display_timing { unsigned int pixelclock;