]> git.baikalelectronics.ru Git - uboot.git/commitdiff
board: ti: common: board_detect: Fix EEPROM read quirk for 2-byte
authorNeha Malcom Francis <n-francis@ti.com>
Tue, 13 Dec 2022 06:27:34 +0000 (11:57 +0530)
committerTom Rini <trini@konsulko.com>
Mon, 2 Jan 2023 21:06:07 +0000 (16:06 -0500)
EEPROM detection logic in ti_i2c_eeprom_get() involves figuring out
whether addressing is 1-byte or 2-byte. There are currently different
behaviours seen across boards as documented in commit 90fde2a3094d
("board: ti: common: board_detect: Fix EEPROM read quirk"). Adding to
the list, we see that there are 2-byte EEPROMs that read properly
with 1-byte addressing with no offset.

For ti_i2c_eeprom_am6_get where eeprom parse operation is dynamic, the
earlier commit 1752ddb410c9 ("board: ti: common: board_detect: Fix
EEPROM read quirk for AM6 style data") tried to resolve this by running
ti_i2c_eeprom_get() twice. However this commit along with its former
commit fails on J7 platforms where EEPROM successfully return back the
header on 1-byte addressing and continues to do so until an offset is
introduced. So the second read incorrectly determines the EEPROM as
1-byte addressing.

A more generic solution is introduced here to solve
this issue: 1-byte read without offset and 1-byte read with offset. If
both passes, it follows 1-byte addressing else we proceed with 2-byte
addressing check.

Tested on J721E, J7200, DRA7xx, AM64x

Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
Fixes: 1752ddb410c9 (board: ti: common: board_detect: Fix EEPROM read quirk for AM6 style data)
Fixes: 90fde2a3094d (board: ti: common: board_detect: Fix EEPROM read quirk)
Tested-By: Matwey V. Kornilov <matwey.kornilov@gmail.com>
board/ti/common/board_detect.c

index c37629fe8ab31f7008e4db01e705bdb0adb6da3b..9a53884c98e071cfad77bc53636d639134b2c6c7 100644 (file)
@@ -87,6 +87,8 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
                                            u32 header, u32 size, uint8_t *ep)
 {
        int rc;
+       uint8_t offset_test;
+       bool one_byte_addressing = true;
 
 #if CONFIG_IS_ENABLED(DM_I2C)
        struct udevice *dev;
@@ -114,8 +116,23 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
         */
        (void)dm_i2c_read(dev, 0, ep, size);
 
+       if (*((u32 *)ep) != header)
+               one_byte_addressing = false;
+
+       /*
+        * Handle case of bad 2 byte eeproms that responds to 1 byte addressing
+        * but gets stuck in const addressing when read requests are performed
+        * on offsets. We perform an offset test to make sure it is not a 2 byte
+        * eeprom that works with 1 byte addressing but just without an offset
+        */
+
+       rc = dm_i2c_read(dev, 0x1, &offset_test, sizeof(offset_test));
+
+       if (*((u32 *)ep) != (header & 0xFF))
+               one_byte_addressing = false;
+
        /* Corrupted data??? */
-       if (*((u32 *)ep) != header) {
+       if (!one_byte_addressing) {
                /*
                 * read the eeprom header using i2c again, but use only a
                 * 2 byte address (some newer boards need this..)
@@ -151,8 +168,23 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
         */
        (void)i2c_read(dev_addr, 0x0, byte, ep, size);
 
+       if (*((u32 *)ep) != header)
+               one_byte_addressing = false;
+
+       /*
+        * Handle case of bad 2 byte eeproms that responds to 1 byte addressing
+        * but gets stuck in const addressing when read requests are performed
+        * on offsets. We perform an offset test to make sure it is not a 2 byte
+        * eeprom that works with 1 byte addressing but just without an offset
+        */
+
+       rc = i2c_read(dev_addr, 0x1, byte, &offset_test, sizeof(offset_test));
+
+       if (*((u32 *)ep) != (header & 0xFF))
+               one_byte_addressing = false;
+
        /* Corrupted data??? */
-       if (*((u32 *)ep) != header) {
+       if (!one_byte_addressing) {
                /*
                 * read the eeprom header using i2c again, but use only a
                 * 2 byte address (some newer boards need this..)
@@ -444,16 +476,6 @@ int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
        if (rc)
                return rc;
 
-       /*
-        * Handle case of bad 2 byte eeproms that responds to 1 byte addressing
-        * but gets stuck in const addressing when read requests are performed
-        * on offsets. We re-read the board ID to ensure we have sane data back
-        */
-       rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
-                              sizeof(board_id), (uint8_t *)&board_id);
-       if (rc)
-               return rc;
-
        if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) {
                pr_err("%s: Invalid board ID record!\n", __func__);
                return -EINVAL;