drivers/i2c/at24rf08c: Add option for early locking

Currently the Sandybridge Lenovo devices are spending 25msec waiting
for ME to signal if RAM has been replaced. At the same time the RFID
I2C EEPROM needs to be locked, taking about 26msec.

By moving the locking to romstage the time spent waiting for ME can
be used to do something useful and thus reduce boot time.

TEST=On Lenovo X220 it boots 24msec faster.

Change-Id: Idd1f02a20dab6e422d55e3cf01d7b4a168792272
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91031
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
Patrick Rudolph 2026-01-31 08:30:51 +01:00 committed by Matt DeVillier
commit a607d831c0
33 changed files with 115 additions and 3 deletions

View file

@ -3,3 +3,7 @@
config DRIVER_LENOVO_SERIALS
bool
select SMBIOS_PROVIDED_BY_MOBO
config DRIVER_LENOVO_SERIALS_EARLY_LOCK
bool
depends on DRIVER_LENOVO_SERIALS

View file

@ -3,3 +3,4 @@
ramstage-$(CONFIG_DRIVER_LENOVO_SERIALS) += at24rf08c.c
$(call src-to-obj,ramstage,$(dir)/lenovo_serials.c) : $(obj)/build.h
ramstage-$(CONFIG_DRIVER_LENOVO_SERIALS) += lenovo_serials.c
romstage-$(CONFIG_DRIVER_LENOVO_SERIALS_EARLY_LOCK) += romstage.c

View file

@ -11,6 +11,9 @@ static void at24rf08c_init(struct device *dev)
if (!dev->enabled)
return;
if (CONFIG(DRIVER_LENOVO_SERIALS_EARLY_LOCK))
return;
/* Ensure that EEPROM/RFID chip is not accessible through RFID.
Need to do it only on 5c. */
if (dev->path.type != DEVICE_PATH_I2C || dev->path.i2c.device != 0x5c)

View file

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
const char *lenovo_mainboard_partnumber(void);
void lenovo_mainboard_eeprom_lock(void);

View file

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/smbus_host.h>
#include <console/console.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
void lenovo_mainboard_eeprom_lock(void)
{
printk(BIOS_DEBUG, "Locking EEPROM RFID\n");
for (int i = 0; i < 8; i++) {
/* After a register write AT24RF08C sometimes stops responding.
Retry several times in case of failure. */
for (int j = 0; j < 100; j++)
if (smbus_write_byte(0x5c, i, 0x0f) >= 0)
break;
}
}

View file

@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS
select AZALIA_USE_LEGACY_VERB_TABLE
select BOARD_ROMSIZE_KB_4096
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_LENOVO_H8
select EC_LENOVO_PMH7
select HAVE_ACPI_RESUME

View file

@ -2,5 +2,6 @@
bootblock-y += gpio.c
romstage-y += gpio.c
romstage-y += early_init.c
ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}

View file

@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS
select AZALIA_USE_LEGACY_VERB_TABLE
select BOARD_ROMSIZE_KB_12288
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_ACPI
select EC_COMPAL_ENE932
select GFX_GMA_PANEL_1_ON_LVDS

View file

@ -2,8 +2,10 @@
#include <device/pci_ops.h>
#include <console/console.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <gpio.h>
#include <northbridge/intel/sandybridge/raminit.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <southbridge/intel/bd82x6x/pch.h>
#include "ec.h"
@ -56,3 +58,8 @@ void mb_get_spd_map(struct spd_info *spdi)
spdi->addresses[0] = SPD_MEMORY_DOWN;
spdi->spd_index = spd_index;
}
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}

View file

@ -22,6 +22,7 @@ config BOARD_SPECIFIC_OPTIONS
select INTEL_INT15
select DRIVERS_RICOH_RCE822
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select MEMORY_MAPPED_TPM
select MAINBOARD_HAS_TPM1
select MAINBOARD_HAS_LIBGFXINIT

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/pci_ops.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
@ -33,4 +34,5 @@ static void hybrid_graphics_init(void)
void mainboard_early_init(bool s3resume)
{
hybrid_graphics_init();
lenovo_mainboard_eeprom_lock();
}

View file

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select BOARD_ROMSIZE_KB_8192
select DRIVERS_LENOVO_HYBRID_GRAPHICS
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_LENOVO_H8
select EC_LENOVO_PMH7
select GFX_GMA_PANEL_1_ON_LVDS

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/pci_ops.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
@ -33,4 +34,5 @@ static void hybrid_graphics_init(void)
void mainboard_early_init(bool s3resume)
{
hybrid_graphics_init();
lenovo_mainboard_eeprom_lock();
}

View file

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select BOARD_ROMSIZE_KB_12288
select DRIVERS_LENOVO_HYBRID_GRAPHICS
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select DRIVERS_RICOH_RCE822
select EC_LENOVO_H8
select EC_LENOVO_PMH7

View file

@ -3,6 +3,7 @@
#include <device/pci_ops.h>
#include <device/pci_def.h>
#include <ec/lenovo/pmh7/pmh7.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
@ -35,4 +36,5 @@ static void hybrid_graphics_init(void)
void mainboard_early_init(bool s3resume)
{
hybrid_graphics_init();
lenovo_mainboard_eeprom_lock();
}

View file

@ -29,6 +29,7 @@ config BOARD_SPECIFIC_OPTIONS
select MAINBOARD_USES_IFD_GBE_REGION
select DRIVERS_RICOH_RCE822 if BOARD_LENOVO_T431S
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select HAVE_SPD_IN_CBFS if BOARD_LENOVO_T431S
# Workaround for EC/KBC IRQ1.

View file

@ -3,6 +3,7 @@
#include <option.h>
#include <device/pci_ops.h>
#include <device/pci_def.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <ec/lenovo/pmh7/pmh7.h>
#include <types.h>
@ -20,4 +21,6 @@ void mainboard_early_init(bool s3resume)
// Hide disabled dGPU device
pci_and_config32(HOST_BRIDGE, DEVEN, ~DEVEN_PEG10);
}
lenovo_mainboard_eeprom_lock();
}

View file

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <northbridge/intel/sandybridge/raminit.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
void mb_get_spd_map(struct spd_info *spdi)
{
@ -9,3 +11,8 @@ void mb_get_spd_map(struct spd_info *spdi)
spdi->addresses[2] = 0x51;
spdi->spd_index = 0;
}
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}

View file

@ -27,6 +27,7 @@ config BOARD_LENOVO_BASEBOARD_T520
select INTEL_GMA_HAVE_VBT if BOARD_LENOVO_T520
select MAINBOARD_USES_IFD_GBE_REGION
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
# Workaround for EC/KBC IRQ1.
select SERIRQ_CONTINUOUS_MODE

View file

@ -1,12 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdint.h>
#include <device/device.h>
#include <device/pci_ops.h>
#include <device/pci_def.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <southbridge/intel/bd82x6x/pch.h>
#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h>
#include <device/device.h>
static void hybrid_graphics_init(void)
{
@ -37,4 +38,5 @@ static void hybrid_graphics_init(void)
void mainboard_early_init(bool s3resume)
{
hybrid_graphics_init();
lenovo_mainboard_eeprom_lock();
}

View file

@ -6,6 +6,7 @@ config BOARD_LENOVO_BASEBOARD_T530
select BOARD_ROMSIZE_KB_12288
select DRIVERS_LENOVO_HYBRID_GRAPHICS
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_LENOVO_H8
select EC_LENOVO_PMH7
select GFX_GMA_PANEL_1_ON_LVDS

View file

@ -1,11 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <types.h>
#include <device/device.h>
#include <device/pci_ops.h>
#include <device/pci_def.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h>
#include <device/device.h>
static void hybrid_graphics_init(void)
{
@ -36,4 +37,5 @@ static void hybrid_graphics_init(void)
void mainboard_early_init(bool s3resume)
{
hybrid_graphics_init();
lenovo_mainboard_eeprom_lock();
}

View file

@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS
select AZALIA_USE_LEGACY_VERB_TABLE
select BOARD_ROMSIZE_KB_12288
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_LENOVO_H8
select GFX_GMA_PANEL_1_ON_LVDS
select HAVE_ACPI_RESUME

View file

@ -2,5 +2,6 @@
bootblock-y += gpio.c
romstage-y += gpio.c
romstage-y += early_init.c
ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}

View file

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select BOARD_ROMSIZE_KB_12288
select DRIVERS_RICOH_RCE822
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_LENOVO_H8
select EC_LENOVO_PMH7
select GFX_GMA_PANEL_1_ON_LVDS

View file

@ -1,8 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
#include <gpio.h>
#include <northbridge/intel/sandybridge/raminit.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
static unsigned int get_spd_index(void)
{
@ -40,3 +42,8 @@ void mb_get_spd_map(struct spd_info *spdi)
spdi->addresses[2] = SPD_MEMORY_DOWN;
spdi->spd_index = get_spd_index();
}
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}

View file

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select BOARD_ROMSIZE_KB_8192
select DRIVERS_RICOH_RCE822
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select EC_LENOVO_H8
select EC_LENOVO_PMH7
select GFX_GMA_PANEL_1_ON_LVDS

View file

@ -2,7 +2,14 @@
#include <stdint.h>
#include <northbridge/intel/sandybridge/raminit.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
void mainboard_fill_pei_data(struct pei_data *pei_data)
{
}
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}

View file

@ -24,6 +24,7 @@ config BOARD_SPECIFIC_OPTIONS
select INTEL_INT15
select DRIVERS_RICOH_RCE822
select DRIVER_LENOVO_SERIALS
select DRIVER_LENOVO_SERIALS_EARLY_LOCK
select MEMORY_MAPPED_TPM
select MAINBOARD_HAS_TPM1 if BOARD_LENOVO_X230 || BOARD_LENOVO_X230T || BOARD_LENOVO_X230_EDP
select MAINBOARD_HAS_LIBGFXINIT

View file

@ -4,6 +4,8 @@ bootblock-y += variants/$(VARIANT_DIR)/gpio.c
romstage-y += variants/$(VARIANT_DIR)/gpio.c
ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c
romstage-y += early_init.c
ifeq ($(CONFIG_BOARD_LENOVO_X230_EDP),y)
ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/x230_edp/gma-mainboard.ads
else

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <drivers/i2c/at24rf08c/lenovo.h>
void mainboard_early_init(bool s3resume)
{
lenovo_mainboard_eeprom_lock();
}