From 77a39d588ec87d0c60e7354025a12f4c6373946e Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 31 Jan 2026 07:38:43 +0100 Subject: [PATCH] drivers/i2c/at24rf08c: Use I2C block read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use I2C block read command to access the VPD EEPROM to speed up SMBIOS table generation, but keep the single byte read as fallback. Shrink the size of the mainboard version string to not crossing the 128 byte block boundary. TEST=On Lenovo X220 the BS_WRITE_TABLES is 15 msec faster. Change-Id: Ida21a8dc653551440e79b062abcce9194d11bef4 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91029 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/drivers/i2c/at24rf08c/lenovo_serials.c | 51 +++++++++++----------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/drivers/i2c/at24rf08c/lenovo_serials.c b/src/drivers/i2c/at24rf08c/lenovo_serials.c index 8b355062e5..34b98004c6 100644 --- a/src/drivers/i2c/at24rf08c/lenovo_serials.c +++ b/src/drivers/i2c/at24rf08c/lenovo_serials.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -38,18 +39,22 @@ static int at24rf08c_read_byte(struct device *dev, u8 addr) return t; } -static void at24rf08c_read_string_dev(struct device *dev, u8 start, - u8 len, char *result) +static void at24rf08c_read_string_dev(struct device *dev, const u8 start, + const u8 len, char *result) { - int i; - for (i = 0; i < len; i++) { - int t = at24rf08c_read_byte(dev, start + i); + assert(start + len <= 128); - if (t < 0x20 || t > 0x7f) { + int ret = smbus_i2c_eeprom_read(dev, start, len, (u8 *)result); + if (ret != len) { + for (int i = 0; i < len; i++) + result[i] = at24rf08c_read_byte(dev, start + i); + } + + for (int i = 0; i < len; i++) { + if (result[i] < 0x20) { memcpy(result, ERROR_STRING, sizeof(ERROR_STRING)); return; } - result[i] = t; } result[len] = '\0'; } @@ -106,7 +111,7 @@ const char *smbios_mainboard_product_name(void) void smbios_system_set_uuid(u8 *uuid) { static char result[16]; - unsigned int i; + u8 buf[16]; static int already_read; struct device *dev; const int remap[16] = { @@ -119,34 +124,30 @@ void smbios_system_set_uuid(u8 *uuid) return; } - memset(result, 0, sizeof(result)); + memset(uuid, 0, 16); dev = dev_find_slot_on_smbus(1, 0x56); if (dev == NULL) { printk(BIOS_WARNING, "EEPROM not found\n"); already_read = 1; - memset(uuid, 0, 16); return; } - for (i = 0; i < 16; i++) { - int t; - int j; - /* After a register write AT24RF08C (which we issued in init function) sometimes stops responding. - Retry several times in case of failure. - */ - for (j = 0; j < 100; j++) { - t = smbus_read_byte(dev, 0x12 + i); - if (t >= 0) - break; + int ret = smbus_i2c_eeprom_read(dev, 0x12, 16, buf); + if (ret != 16) { + for (int i = 0; i < 16; i++) { + int c = at24rf08c_read_byte(dev, 0x12 + i); + if (c < 0) { + already_read = 1; + return; + } + buf[i] = c; } - if (t < 0) { - memset(result, 0, sizeof(result)); - break; - } - result[remap[i]] = t; } + for (int i = 0; i < 16; i++) + result[remap[i]] = buf[i]; + already_read = 1; memcpy(uuid, result, 16);