yuchi.chen@intel.com has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/84201?usp=email )
Change subject: include/spd_bin.h: Add 3 SPD IO functions ......................................................................
include/spd_bin.h: Add 3 SPD IO functions
Now SMBus calls the new SPD IO functions to retrive SPD data. The default implementation is to forward to SMBus IO functions directly.
Based on this patch, SoC could provide another implementation of SPD IO functions such as using Integrated Memory Controller to get SPD data.
Change-Id: I656298aeda409fca3c85266b5b8727fac9bfc917 Signed-off-by: Yuchi Chen yuchi.chen@intel.com --- M src/include/spd_bin.h M src/soc/intel/common/block/smbus/Makefile.mk M src/soc/intel/common/block/smbus/smbuslib.c A src/soc/intel/common/block/smbus/spd_access.c 4 files changed, 40 insertions(+), 15 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/01/84201/1
diff --git a/src/include/spd_bin.h b/src/include/spd_bin.h index c51e449..434d674 100644 --- a/src/include/spd_bin.h +++ b/src/include/spd_bin.h @@ -49,6 +49,10 @@ void dump_spd_info(struct spd_block *blk); void get_spd_smbus(struct spd_block *blk);
+int spd_read_byte(u8 slave_addr, u8 bus_addr); +int spd_read_word(u8 slave_addr, u8 bus_addr); +void spd_write_byte(u8 slave_addr, u8 bus_addr, u8 value); + /* * get_spd_sn returns the SODIMM serial number. It only supports DDR3 and DDR4. * return CB_SUCCESS, sn is the serial number and sn=0xffffffff if the dimm is not present. diff --git a/src/soc/intel/common/block/smbus/Makefile.mk b/src/soc/intel/common/block/smbus/Makefile.mk index 777d92a..dd56814 100644 --- a/src/soc/intel/common/block/smbus/Makefile.mk +++ b/src/soc/intel/common/block/smbus/Makefile.mk @@ -1,8 +1,10 @@ ## SPDX-License-Identifier: GPL-2.0-only +bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += spd_access.c bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbuslib.c bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbus_early.c bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += spd_access.c romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbuslib.c romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbus_early.c romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c diff --git a/src/soc/intel/common/block/smbus/smbuslib.c b/src/soc/intel/common/block/smbus/smbuslib.c index aff6fb0..deb09b3 100644 --- a/src/soc/intel/common/block/smbus/smbuslib.c +++ b/src/soc/intel/common/block/smbus/smbuslib.c @@ -20,7 +20,7 @@ blk->len = SPD_PAGE_LEN; }
-static void smbus_read_spd(u8 *spd, u8 addr) +static void spd_read(u8 *spd, u8 addr) { u16 i; u8 step = 1; @@ -31,9 +31,9 @@ for (i = 0; i < SPD_PAGE_LEN; i += step) { if (CONFIG(SPD_READ_BY_WORD)) ((u16*)spd)[i / sizeof(uint16_t)] = - smbus_read_word(addr, i); + spd_read_word(addr, i); else - spd[i] = smbus_read_byte(addr, i); + spd[i] = spd_read_byte(addr, i); } }
@@ -42,11 +42,11 @@ { if (CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) { /* Restore to page 0 before reading */ - smbus_write_byte(SPD_PAGE_0, 0, 0); + spd_write_byte(SPD_PAGE_0, 0, 0); }
/* If address is not 0, it will return CB_ERR(-1) if no dimm */ - if (smbus_read_byte(addr, 0) < 0) { + if (spd_read_byte(addr, 0) < 0) { printk(BIOS_INFO, "No memory dimm at address %02X\n", addr << 1); return -1; @@ -54,20 +54,20 @@
if (i2c_eeprom_read(addr, 0, SPD_PAGE_LEN, spd) < 0) { printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n"); - smbus_read_spd(spd, addr); + spd_read(spd, addr); }
/* Check if module is DDR4, DDR4 spd is 512 byte. */ if (spd[SPD_DRAM_TYPE] == SPD_DRAM_DDR4 && CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) { /* Switch to page 1 */ - smbus_write_byte(SPD_PAGE_1, 0, 0); + spd_write_byte(SPD_PAGE_1, 0, 0);
if (i2c_eeprom_read(addr, 0, SPD_PAGE_LEN, spd + SPD_PAGE_LEN) < 0) { printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n"); - smbus_read_spd(spd + SPD_PAGE_LEN, addr); + spd_read(spd + SPD_PAGE_LEN, addr); } /* Restore to page 0 */ - smbus_write_byte(SPD_PAGE_0, 0, 0); + spd_write_byte(SPD_PAGE_0, 0, 0); } return 0; } @@ -109,11 +109,11 @@
if (CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) { /* Restore to page 0 before reading */ - smbus_write_byte(SPD_PAGE_0, 0, 0); + spd_write_byte(SPD_PAGE_0, 0, 0); }
/* If dimm is not present, set sn to 0xff. */ - smbus_ret = smbus_read_byte(addr, SPD_DRAM_TYPE); + smbus_ret = spd_read_byte(addr, SPD_DRAM_TYPE); if (smbus_ret < 0) { printk(BIOS_INFO, "No memory dimm at address %02X\n", addr << 1); *sn = 0xffffffff; @@ -125,17 +125,17 @@ /* Check if module is DDR4, DDR4 spd is 512 byte. */ if (dram_type == SPD_DRAM_DDR4 && CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) { /* Switch to page 1 */ - smbus_write_byte(SPD_PAGE_1, 0, 0); + spd_write_byte(SPD_PAGE_1, 0, 0);
for (i = 0; i < SPD_SN_LEN; i++) - *((u8 *)sn + i) = smbus_read_byte(addr, + *((u8 *)sn + i) = spd_read_byte(addr, i + DDR4_SPD_SN_OFF);
/* Restore to page 0 */ - smbus_write_byte(SPD_PAGE_0, 0, 0); + spd_write_byte(SPD_PAGE_0, 0, 0); } else if (dram_type == SPD_DRAM_DDR3) { for (i = 0; i < SPD_SN_LEN; i++) - *((u8 *)sn + i) = smbus_read_byte(addr, + *((u8 *)sn + i) = spd_read_byte(addr, i + DDR3_SPD_SN_OFF); } else { printk(BIOS_ERR, "Unsupported dram_type\n"); diff --git a/src/soc/intel/common/block/smbus/spd_access.c b/src/soc/intel/common/block/smbus/spd_access.c new file mode 100644 index 0000000..f37e313 --- /dev/null +++ b/src/soc/intel/common/block/smbus/spd_access.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/smbus_host.h> +#include <spd_bin.h> + +int spd_read_byte(u8 slave_addr, u8 bus_addr) +{ + return smbus_read_byte(slave_addr, bus_addr); +} + +int spd_read_word(u8 slave_addr, u8 bus_addr) +{ + return smbus_read_word(slave_addr, bus_addr); +} + +void spd_write_byte(u8 slave_addr, u8 bus_addr, u8 value) +{ + smbus_write_byte(slave_addr, bus_addr, value); +}