include/spd_bin.h: Add SPD IO layer
By default, PCH SMBus codes will be called to retrieve SPD data. This patch adds a SPD IO layer so that SoC could implement its specific SPD IO layer functions such as using Integrated Memory Controller to get SPD data. Change-Id: I656298aeda409fca3c85266b5b8727fac9bfc917 Signed-off-by: Yuchi Chen <yuchi.chen@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/84201 Reviewed-by: Shuo Liu <shuo.liu@intel.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
031c078e86
commit
7a7b4f05fc
4 changed files with 40 additions and 15 deletions
|
|
@ -49,6 +49,10 @@ uintptr_t spd_cbfs_map(u8 spd_index);
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ static void update_spd_len(struct spd_block *blk)
|
|||
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 @@ static void smbus_read_spd(u8 *spd, u8 addr)
|
|||
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 @@ static int get_spd(u8 *spd, u8 addr)
|
|||
{
|
||||
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 @@ static int get_spd(u8 *spd, u8 addr)
|
|||
|
||||
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 @@ enum cb_err get_spd_sn(u8 addr, u32 *sn)
|
|||
|
||||
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 @@ enum cb_err get_spd_sn(u8 addr, u32 *sn)
|
|||
/* 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");
|
||||
|
|
|
|||
19
src/soc/intel/common/block/smbus/spd_access.c
Normal file
19
src/soc/intel/common/block/smbus/spd_access.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue