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 <xji@analogix.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87961
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yidi Lin <yidilin@google.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
Xin Ji 2025-05-26 14:56:17 +08:00 committed by Yidi Lin
commit c2496bc62e
2 changed files with 16 additions and 10 deletions

View file

@ -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)

View file

@ -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;