diff options
Diffstat (limited to 'src/soc/amd/stoneyridge/smbus_spd.c')
-rw-r--r-- | src/soc/amd/stoneyridge/smbus_spd.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/src/soc/amd/stoneyridge/smbus_spd.c b/src/soc/amd/stoneyridge/smbus_spd.c index 9bbce5bc25..605f8da78e 100644 --- a/src/soc/amd/stoneyridge/smbus_spd.c +++ b/src/soc/amd/stoneyridge/smbus_spd.c @@ -20,10 +20,10 @@ #include <Porting.h> #include <AGESA.h> #include <soc/southbridge.h> +#include <soc/smbus.h> #include <dimmSpd.h> -/*----------------------------------------------------------------------------- - * +/* * readSmbusByteData - read a single SPD byte from any offset */ static int readSmbusByteData(int iobase, int address, char *buffer, int offset) @@ -33,33 +33,32 @@ static int readSmbusByteData(int iobase, int address, char *buffer, int offset) address |= 1; // set read bit - __outbyte(iobase + 0, 0xff); // clear error status - __outbyte(iobase + 1, 0x1f); // clear error status - __outbyte(iobase + 3, offset); // offset in eeprom - __outbyte(iobase + 4, address); // slave address and read bit - __outbyte(iobase + 2, 0x48); // read byte command + __outbyte(iobase + SMBHSTSTAT, SMBHST_STAT_CLEAR); + __outbyte(iobase + SMBSLVSTAT, SMBSLV_STAT_CLEAR); + __outbyte(iobase + SMBHSTCMD, offset); // offset in eeprom + __outbyte(iobase + SMBHSTADDR, address); // slave addr & read bit + __outbyte(iobase + SMBHSTCTRL, SMBHST_CTRL_STRT + SMBHST_CTRL_BDT_RW); // time limit to avoid hanging for unexpected error status limit = __rdtsc() + 2000000000 / 10; for (;;) { - status = __inbyte(iobase); + status = __inbyte(iobase + SMBHSTSTAT); if (__rdtsc() > limit) break; - if ((status & 2) == 0) + if ((status & SMBHST_STAT_INTERRUPT) == 0) continue; // SMBusInterrupt not set, keep waiting - if ((status & 1) == 1) + if ((status & SMBHST_STAT_BUSY) == SMBHST_STAT_BUSY) continue; // HostBusy set, keep waiting break; } - buffer[0] = __inbyte(iobase + 5); - if (status == 2) - status = 0; // check for done with no errors + buffer[0] = __inbyte(iobase + SMBHSTDAT0); + if (status == SMBHST_STAT_NOERROR) + status = 0; // done with no errors return status; } -/*----------------------------------------------------------------------------- - * +/* * readSmbusByte - read a single SPD byte from the default offset * this function is faster function readSmbusByteData */ @@ -68,30 +67,29 @@ static int readSmbusByte(int iobase, int address, char *buffer) unsigned int status; UINT64 limit; - __outbyte(iobase + 0, 0xff); // clear error status - __outbyte(iobase + 2, 0x44); // read command + __outbyte(iobase + SMBHSTSTAT, SMBHST_STAT_CLEAR); + __outbyte(iobase + SMBHSTCTRL, SMBHST_CTRL_STRT + SMBHST_CTRL_BTE_RW); // time limit to avoid hanging for unexpected error status limit = __rdtsc() + 2000000000 / 10; for (;;) { - status = __inbyte(iobase); + status = __inbyte(iobase + SMBHSTSTAT); if (__rdtsc() > limit) break; - if ((status & 2) == 0) + if ((status & SMBHST_STAT_INTERRUPT) == 0) continue; // SMBusInterrupt not set, keep waiting - if ((status & 1) == 1) + if ((status & SMBHST_STAT_BUSY) == SMBHST_STAT_BUSY) continue; // HostBusy set, keep waiting break; } - buffer[0] = __inbyte(iobase + 5); - if (status == 2) - status = 0; // check for done with no errors + buffer[0] = __inbyte(iobase + SMBHSTDAT0); + if (status == SMBHST_STAT_NOERROR) + status = 0; // done with no errors return status; } -/*--------------------------------------------------------------------------- - * +/* * readspd - Read one or more SPD bytes from a DIMM. * Start with offset zero and read sequentially. * Optimization relies on autoincrement to avoid @@ -115,7 +113,7 @@ static int readspd(int iobase, int SmbusSlaveAddress, char *buffer, int count) } /* read the remaining bytes using auto-increment for speed */ - for (index = 1 ; index < count ; index++) { + for (index = 1; index < count; index++) { error = readSmbusByte(iobase, SmbusSlaveAddress, &buffer[index]); if (error) { @@ -137,15 +135,16 @@ static void writePmReg(int reg, int data) static void setupFch(int ioBase) { + /* register 0x2c and 0x2d are not defined in public datasheet */ writePmReg(0x2d, ioBase >> 8); writePmReg(0x2c, ioBase | 1); /* set SMBus clock to 400 KHz */ - __outbyte(ioBase + 0x0e, 66000000 / 400000 / 4); + __outbyte(ioBase + SMBTIMING, 66000000 / 400000 / 4); } int sb_readSpd(int spdAddress, char *buf, size_t len) { - int ioBase = 0xb00; + int ioBase = SMB_BASE_ADDR; setupFch(ioBase); return readspd(ioBase, spdAddress, buf, len); } |