soc/intel/common/block/smbus: Use i2c read eeprom to speedup SPD read

Reading the SPD using the SMBUS routines takes a long time because each
byte or word is access seperately.

Allow using the i2c read eeprom routines to read the SPD. By doing this
the start address is only sent once per page.

The time required to read a DDR4 SPD is reduced from 200 msec to 50
msec.

BUG=N/A
TEST=tested on facebook monolith

Change-Id: I44e18b8ba72e1b2321f83402a6a055e2be6f940c
Signed-off-by: Wim Vervoorn <wvervoorn@eltan.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40942
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Frans Hendriks <fhendriks@eltan.com>
This commit is contained in:
Wim Vervoorn 2020-05-01 13:50:08 +02:00 committed by Patrick Georgi
parent 544cc83470
commit 30e9149c4f

View file

@ -2,6 +2,7 @@
#include <console/console.h>
#include <spd_bin.h>
#include <device/smbus_def.h>
#include <device/smbus_host.h>
#include <string.h>
#include "smbuslib.h"
@ -46,14 +47,23 @@ static int get_spd(u8 *spd, u8 addr)
addr << 1);
return -1;
}
smbus_read_spd(spd, addr);
if (do_i2c_eeprom_read(SMBUS_IO_BASE, addr, 0, SPD_PAGE_LEN, spd) == SMBUS_ERROR) {
printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n");
smbus_read_spd(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 */
do_smbus_write_byte(SMBUS_IO_BASE, SPD_PAGE_1, 0, 0);
smbus_read_spd(spd + SPD_PAGE_LEN, addr);
if (do_i2c_eeprom_read(SMBUS_IO_BASE, addr, 0, SPD_PAGE_LEN,
spd + SPD_PAGE_LEN) == SMBUS_ERROR) {
printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n");
smbus_read_spd(spd + SPD_PAGE_LEN, addr);
}
/* Restore to page 0 */
do_smbus_write_byte(SMBUS_IO_BASE, SPD_PAGE_0, 0, 0);
}