diff options
author | Francis Rowe <info@gluglug.org.uk> | 2015-10-19 00:12:53 +0100 |
---|---|---|
committer | Francis Rowe <info@gluglug.org.uk> | 2015-10-19 02:32:36 +0100 |
commit | 0622df6194dbb1b2120743c0fd1cc5e72c380128 (patch) | |
tree | 4c858b8c5667fe001a9907ae0578b4ec28a8f513 /resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch | |
parent | 5999dba5f71f1c05040a551d2420ab8c7f3a9da4 (diff) | |
download | librebootfr-0622df6194dbb1b2120743c0fd1cc5e72c380128.tar.gz librebootfr-0622df6194dbb1b2120743c0fd1cc5e72c380128.zip |
KGPE-D16: update patch set (also update coreboot and vboot)
Also contains other fixes from coreboot, like:
* 551cff0 Derive lvds_dual_channel from EDID timings.
^ makes single/dual channel LVDS selection on GM45 automatic
* 26fc544 lenovo/t60: Enable native intel gfx init.
^ was being maintained in libreboot, now upstreamed so not needed
Framebuffer mode was disabled for the KGPE-D16, because only
text-mode works at the moment.
Diffstat (limited to 'resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch')
-rw-r--r-- | resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch b/resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch new file mode 100644 index 00000000..d70b8957 --- /dev/null +++ b/resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch @@ -0,0 +1,461 @@ +From f26e90bcbbd7b5966ac353a7e7ba63fa188ffac0 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 2 Jun 2015 20:51:59 -0500 +Subject: [PATCH 040/139] northbridge/amd/amdmct: Read SPD data into cache to + decrease bootup time + +Change-Id: Ic16a927a3f1fc6f7cb1aea36a8abe8cc1999cb52 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 161 +++++++++++++++------------- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 7 ++ + 2 files changed, 92 insertions(+), 76 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +index 4677c73..5344ff9 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +@@ -180,7 +180,7 @@ static void mct_WriteLevelization_HW(struct MCTStatStruc *pMCTstat, + static u8 Get_Latency_Diff(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct); + static void SyncSetting(struct DCTStatStruc *pDCTstat); +-static u8 crcCheck(u8 smbaddr); ++static uint8_t crcCheck(struct DCTStatStruc *pDCTstat, uint8_t dimm); + static void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat); + static void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat); + +@@ -1170,6 +1170,20 @@ static void precise_memclk_delay_fam15(struct MCTStatStruc *pMCTstat, struct DCT + precise_ndelay_fam15(pMCTstat, delay_ns); + } + ++static void read_spd_bytes(struct MCTStatStruc *pMCTstat, ++ struct DCTStatStruc *pDCTstat, uint8_t dimm) ++{ ++ uint16_t addr; ++ uint16_t byte; ++ ++ addr = Get_DIMMAddress_D(pDCTstat, dimm); ++ pDCTstat->spd_data.spd_address[dimm] = addr; ++ ++ for (byte = 0; byte < 256; byte++) { ++ pDCTstat->spd_data.spd_bytes[dimm][byte] = mctRead_SPD(addr, byte); ++ } ++} ++ + static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstatA) + { +@@ -1275,7 +1289,7 @@ restartinit: + mct_InitialMCT_D(pMCTstat, pDCTstat); + + printk(BIOS_DEBUG, "mctAutoInitMCT_D: mctSMBhub_Init\n"); +- mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node*/ ++ mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node */ + + printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_preInitDCT\n"); + mct_preInitDCT(pMCTstat, pDCTstat); +@@ -2435,7 +2449,6 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, + u32 dword; + u32 dev; + u32 val; +- u16 smbaddr; + + printk(BIOS_DEBUG, "%s: Start\n", __func__); + +@@ -2455,64 +2468,62 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, + for ( i = 0; i< MAX_DIMMS_SUPPORTED; i++) { + LDIMM = i >> 1; + if (pDCTstat->DIMMValid & (1 << i)) { +- smbaddr = Get_DIMMAddress_D(pDCTstat, (dct + i)); +- +- val = mctRead_SPD(smbaddr, SPD_MTBDivisor); /* MTB=Dividend/Divisor */ +- MTB16x = ((mctRead_SPD(smbaddr, SPD_MTBDividend) & 0xFF)<<4); ++ val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDivisor]; /* MTB=Dividend/Divisor */ ++ MTB16x = ((pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDividend] & 0xff) << 4); + MTB16x /= val; /* transfer to MTB*16 */ + +- byte = mctRead_SPD(smbaddr, SPD_tRPmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRPmin]; + val = byte * MTB16x; + if (Trp < val) + Trp = val; + +- byte = mctRead_SPD(smbaddr, SPD_tRRDmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRRDmin]; + val = byte * MTB16x; + if (Trrd < val) + Trrd = val; + +- byte = mctRead_SPD(smbaddr, SPD_tRCDmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRCDmin]; + val = byte * MTB16x; + if (Trcd < val) + Trcd = val; + +- byte = mctRead_SPD(smbaddr, SPD_tRTPmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRTPmin]; + val = byte * MTB16x; + if (Trtp < val) + Trtp = val; + +- byte = mctRead_SPD(smbaddr, SPD_tWRmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tWRmin]; + val = byte * MTB16x; + if (Twr < val) + Twr = val; + +- byte = mctRead_SPD(smbaddr, SPD_tWTRmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tWTRmin]; + val = byte * MTB16x; + if (Twtr < val) + Twtr = val; + +- val = mctRead_SPD(smbaddr, SPD_Upper_tRAS_tRC) & 0xFF; ++ val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Upper_tRAS_tRC] & 0xFF; + val >>= 4; + val <<= 8; +- val |= mctRead_SPD(smbaddr, SPD_tRCmin) & 0xFF; ++ val |= pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRCmin] & 0xFF; + val *= MTB16x; + if (Trc < val) + Trc = val; + +- byte = mctRead_SPD(smbaddr, SPD_Density) & 0xF; ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Density] & 0xF; + if (Trfc[LDIMM] < byte) + Trfc[LDIMM] = byte; + +- val = mctRead_SPD(smbaddr, SPD_Upper_tRAS_tRC) & 0xF; ++ val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Upper_tRAS_tRC] & 0xF; + val <<= 8; +- val |= (mctRead_SPD(smbaddr, SPD_tRASmin) & 0xFF); ++ val |= (pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRASmin] & 0xFF); + val *= MTB16x; + if (Tras < val) + Tras = val; + +- val = mctRead_SPD(smbaddr, SPD_Upper_tFAW) & 0xF; ++ val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Upper_tFAW] & 0xF; + val <<= 8; +- val |= mctRead_SPD(smbaddr, SPD_tFAWmin) & 0xFF; ++ val |= pDCTstat->spd_data.spd_bytes[dct + i][SPD_tFAWmin] & 0xFF; + val *= MTB16x; + if (Tfaw < val) + Tfaw = val; +@@ -2928,7 +2939,7 @@ static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, + u8 CLactual, CLdesired, CLT_Fail; + uint16_t min_frequency_tck16x; + +- u8 smbaddr, byte = 0, bytex = 0; ++ u8 byte = 0, bytex = 0; + + CASLatLow = 0xFF; + CASLatHigh = 0xFF; +@@ -2949,28 +2960,27 @@ static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, + + for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) { + if (pDCTstat->DIMMValid & (1 << i)) { +- smbaddr = Get_DIMMAddress_D(pDCTstat, (dct + i)); + /* Step 1: Determine the common set of supported CAS Latency + * values for all modules on the memory channel using the CAS + * Latencies Supported in SPD bytes 14 and 15. + */ +- byte = mctRead_SPD(smbaddr, SPD_CASLow); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_CASLow]; + CASLatLow &= byte; +- byte = mctRead_SPD(smbaddr, SPD_CASHigh); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_CASHigh]; + CASLatHigh &= byte; + /* Step 2: Determine tAAmin(all) which is the largest tAAmin + value for all modules on the memory channel (SPD byte 16). */ +- byte = mctRead_SPD(smbaddr, SPD_MTBDivisor); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDivisor]; + +- MTB16x = ((mctRead_SPD(smbaddr, SPD_MTBDividend) & 0xFF)<<4); ++ MTB16x = ((pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDividend] & 0xFF)<<4); + MTB16x /= byte; /* transfer to MTB*16 */ + +- byte = mctRead_SPD(smbaddr, SPD_tAAmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tAAmin]; + if (tAAmin16x < byte * MTB16x) + tAAmin16x = byte * MTB16x; + /* Step 3: Determine tCKmin(all) which is the largest tCKmin + value for all modules on the memory channel (SPD byte 12). */ +- byte = mctRead_SPD(smbaddr, SPD_tCKmin); ++ byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tCKmin]; + + if (tCKmin16x < byte * MTB16x) + tCKmin16x = byte * MTB16x; +@@ -3341,7 +3351,6 @@ static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, + u8 byte; + u16 word; + u32 dword; +- u16 smbaddr; + + dev = pDCTstat->dev_dct; + +@@ -3352,16 +3361,14 @@ static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, + byte -= 3; + + if (pDCTstat->DIMMValid & (1<<byte)) { +- smbaddr = Get_DIMMAddress_D(pDCTstat, (ChipSel + dct)); +- +- byte = mctRead_SPD(smbaddr, SPD_Addressing); ++ byte = pDCTstat->spd_data.spd_bytes[ChipSel + dct][SPD_Addressing]; + Rows = (byte >> 3) & 0x7; /* Rows:0b=12-bit,... */ + Cols = byte & 0x7; /* Cols:0b=9-bit,... */ + +- byte = mctRead_SPD(smbaddr, SPD_Density); ++ byte = pDCTstat->spd_data.spd_bytes[ChipSel + dct][SPD_Density]; + Banks = (byte >> 4) & 7; /* Banks:0b=3-bit,... */ + +- byte = mctRead_SPD(smbaddr, SPD_Organization); ++ byte = pDCTstat->spd_data.spd_bytes[ChipSel + dct][SPD_Organization]; + Ranks = ((byte >> 3) & 7) + 1; + + /* Configure Bank encoding +@@ -3456,46 +3463,42 @@ static void SPDCalcWidth_D(struct MCTStatStruc *pMCTstat, + * and determine the width mode: 64-bit, 64-bit muxed, 128-bit. + */ + u8 i; +- u8 smbaddr, smbaddr1; + u8 byte, byte1; + + /* Check Symmetry of Channel A and Channel B DIMMs + (must be matched for 128-bit mode).*/ + for (i=0; i < MAX_DIMMS_SUPPORTED; i += 2) { + if ((pDCTstat->DIMMValid & (1 << i)) && (pDCTstat->DIMMValid & (1<<(i+1)))) { +- smbaddr = Get_DIMMAddress_D(pDCTstat, i); +- smbaddr1 = Get_DIMMAddress_D(pDCTstat, i+1); +- +- byte = mctRead_SPD(smbaddr, SPD_Addressing) & 0x7; +- byte1 = mctRead_SPD(smbaddr1, SPD_Addressing) & 0x7; ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_Addressing] & 0x7; ++ byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_Addressing] & 0x7; + if (byte != byte1) { + pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); + break; + } + +- byte = mctRead_SPD(smbaddr, SPD_Density) & 0x0f; +- byte1 = mctRead_SPD(smbaddr1, SPD_Density) & 0x0f; ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0x0f; ++ byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_Density] & 0x0f; + if (byte != byte1) { + pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); + break; + } + +- byte = mctRead_SPD(smbaddr, SPD_Organization) & 0x7; +- byte1 = mctRead_SPD(smbaddr1, SPD_Organization) & 0x7; ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x7; ++ byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_Organization] & 0x7; + if (byte != byte1) { + pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); + break; + } + +- byte = (mctRead_SPD(smbaddr, SPD_Organization) >> 3) & 0x7; +- byte1 = (mctRead_SPD(smbaddr1, SPD_Organization) >> 3) & 0x7; ++ byte = (pDCTstat->spd_data.spd_bytes[i][SPD_Organization] >> 3) & 0x7; ++ byte1 = (pDCTstat->spd_data.spd_bytes[i + 1][SPD_Organization] >> 3) & 0x7; + if (byte != byte1) { + pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); + break; + } + +- byte = mctRead_SPD(smbaddr, SPD_DMBANKS) & 7; /* #ranks-1 */ +- byte1 = mctRead_SPD(smbaddr1, SPD_DMBANKS) & 7; /* #ranks-1 */ ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_DMBANKS] & 7; /* #ranks-1 */ ++ byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_DMBANKS] & 7; /* #ranks-1 */ + if (byte != byte1) { + pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); + break; +@@ -3676,8 +3679,9 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + status = mctRead_SPD(smbaddr, SPD_ByteUse); + if (status >= 0) { /* SPD access is ok */ + pDCTstat->DIMMPresent |= 1 << i; +- if (crcCheck(smbaddr)) { /* CRC is OK */ +- byte = mctRead_SPD(smbaddr, SPD_TYPE); ++ read_spd_bytes(pMCTstat, pDCTstat, i); ++ if (crcCheck(pDCTstat, i)) { /* CRC is OK */ ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_TYPE]; + if (byte == JED_DDR3SDRAM) { + /*Dimm is 'Present'*/ + pDCTstat->DIMMValid |= 1 << i; +@@ -3690,36 +3694,41 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + } else { + /*if NV_SPDCHK_RESTRT is set to 1, ignore faulty SPD checksum*/ + pDCTstat->ErrStatus |= 1<<SB_DIMMChkSum; +- byte = mctRead_SPD(smbaddr, SPD_TYPE); ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_TYPE]; + if (byte == JED_DDR3SDRAM) + pDCTstat->DIMMValid |= 1 << i; + } + } ++ ++ /* Zero DIMM SPD data cache if DIMM not present / valid */ ++ if (!(pDCTstat->DIMMValid & (1 << i))) ++ memset(pDCTstat->spd_data.spd_bytes[i], 0, 256); ++ + /* Get module information for SMBIOS */ + if (pDCTstat->DIMMValid & (1 << i)) { + pDCTstat->DimmManufacturerID[i] = 0; + for (k = 0; k < 8; k++) +- pDCTstat->DimmManufacturerID[i] |= ((uint64_t)mctRead_SPD(smbaddr, SPD_MANID_START + k)) << (k * 8); ++ pDCTstat->DimmManufacturerID[i] |= ((uint64_t)pDCTstat->spd_data.spd_bytes[i][SPD_MANID_START + k]) << (k * 8); + for (k = 0; k < SPD_PARTN_LENGTH; k++) +- pDCTstat->DimmPartNumber[i][k] = mctRead_SPD(smbaddr, SPD_PARTN_START + k); ++ pDCTstat->DimmPartNumber[i][k] = pDCTstat->spd_data.spd_bytes[i][SPD_PARTN_START + k]; + pDCTstat->DimmPartNumber[i][SPD_PARTN_LENGTH] = 0; + pDCTstat->DimmRevisionNumber[i] = 0; + for (k = 0; k < 2; k++) +- pDCTstat->DimmRevisionNumber[i] |= ((uint16_t)mctRead_SPD(smbaddr, SPD_REVNO_START + k)) << (k * 8); ++ pDCTstat->DimmRevisionNumber[i] |= ((uint16_t)pDCTstat->spd_data.spd_bytes[i][SPD_REVNO_START + k]) << (k * 8); + pDCTstat->DimmSerialNumber[i] = 0; + for (k = 0; k < 4; k++) +- pDCTstat->DimmSerialNumber[i] |= ((uint32_t)mctRead_SPD(smbaddr, SPD_SERIAL_START + k)) << (k * 8); +- pDCTstat->DimmRows[i] = (mctRead_SPD(smbaddr, SPD_Addressing) & 0x38) >> 3; +- pDCTstat->DimmCols[i] = mctRead_SPD(smbaddr, SPD_Addressing) & 0x7; +- pDCTstat->DimmRanks[i] = ((mctRead_SPD(smbaddr, SPD_Organization) & 0x38) >> 3) + 1; +- pDCTstat->DimmBanks[i] = 1ULL << (((mctRead_SPD(smbaddr, SPD_Density) & 0x70) >> 4) + 3); +- pDCTstat->DimmWidth[i] = 1ULL << ((mctRead_SPD(smbaddr, SPD_BusWidth) & 0x7) + 3); ++ pDCTstat->DimmSerialNumber[i] |= ((uint32_t)pDCTstat->spd_data.spd_bytes[i][SPD_SERIAL_START + k]) << (k * 8); ++ pDCTstat->DimmRows[i] = (pDCTstat->spd_data.spd_bytes[i][SPD_Addressing] & 0x38) >> 3; ++ pDCTstat->DimmCols[i] = pDCTstat->spd_data.spd_bytes[i][SPD_Addressing] & 0x7; ++ pDCTstat->DimmRanks[i] = ((pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x38) >> 3) + 1; ++ pDCTstat->DimmBanks[i] = 1ULL << (((pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0x70) >> 4) + 3); ++ pDCTstat->DimmWidth[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_BusWidth] & 0x7) + 3); + } + /* Check supported voltage(s) */ +- pDCTstat->DimmSupportedVoltages[i] = mctRead_SPD(smbaddr, SPD_Voltage) & 0x7; ++ pDCTstat->DimmSupportedVoltages[i] = pDCTstat->spd_data.spd_bytes[i][SPD_Voltage] & 0x7; + pDCTstat->DimmSupportedVoltages[i] ^= 0x1; /* Invert LSB to convert from SPD format to internal bitmap format */ + /* Check module type */ +- byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE) & 0x7; ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_DIMMTYPE] & 0x7; + if (byte == JED_RDIMM || byte == JED_MiniRDIMM) { + RegDIMMPresent |= 1 << i; + pDCTstat->DimmRegistered[i] = 1; +@@ -3733,13 +3742,13 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + pDCTstat->DimmLoadReduced[i] = 0; + } + /* Check ECC capable */ +- byte = mctRead_SPD(smbaddr, SPD_BusWidth); ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_BusWidth]; + if (byte & JED_ECC) { + /* DIMM is ECC capable */ + pDCTstat->DimmECCPresent |= 1 << i; + } + /* Check if x4 device */ +- devwidth = mctRead_SPD(smbaddr, SPD_Organization) & 0x7; /* 0:x4,1:x8,2:x16 */ ++ devwidth = pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x7; /* 0:x4,1:x8,2:x16 */ + if (devwidth == 0) { + /* DIMM is made with x4 or x16 drams */ + pDCTstat->Dimmx4Present |= 1 << i; +@@ -3749,7 +3758,7 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + pDCTstat->Dimmx16Present |= 1 << i; + } + +- byte = (mctRead_SPD(smbaddr, SPD_Organization) >> 3); ++ byte = (pDCTstat->spd_data.spd_bytes[i][SPD_Organization] >> 3); + byte &= 7; + if (byte == 3) { /* 4ranks */ + /* if any DIMMs are QR, we have to make two passes through DIMMs*/ +@@ -3784,7 +3793,7 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + + /* check address mirror support for unbuffered dimm */ + /* check number of registers on a dimm for registered dimm */ +- byte = mctRead_SPD(smbaddr, SPD_AddressMirror); ++ byte = pDCTstat->spd_data.spd_bytes[i][SPD_AddressMirror]; + if (RegDIMMPresent & (1 << i)) { + if ((byte & 3) > 1) + pDCTstat->MirrPresU_NumRegR |= 1 << i; +@@ -3793,20 +3802,20 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + pDCTstat->MirrPresU_NumRegR |= 1 << i; + } + /* Get byte62: Reference Raw Card information. We dont need it now. */ +- /* byte = mctRead_SPD(smbaddr, SPD_RefRawCard); */ ++ /* byte = pDCTstat->spd_data.spd_bytes[i][SPD_RefRawCard]; */ + /* Get Byte65/66 for register manufacture ID code */ +- if ((0x97 == mctRead_SPD(smbaddr, SPD_RegManufactureID_H)) && +- (0x80 == mctRead_SPD(smbaddr, SPD_RegManufactureID_L))) { +- if (0x16 == mctRead_SPD(smbaddr, SPD_RegManRevID)) ++ if ((0x97 == pDCTstat->spd_data.spd_bytes[i][SPD_RegManufactureID_H]) && ++ (0x80 == pDCTstat->spd_data.spd_bytes[i][SPD_RegManufactureID_L])) { ++ if (0x16 == pDCTstat->spd_data.spd_bytes[i][SPD_RegManRevID]) + pDCTstat->RegMan2Present |= 1 << i; + else + pDCTstat->RegMan1Present |= 1 << i; + } + /* Get Control word values for RC3. We dont need it. */ +- byte = mctRead_SPD(smbaddr, 70); ++ byte = pDCTstat->spd_data.spd_bytes[i][70]; + pDCTstat->CtrlWrd3 |= (byte >> 4) << (i << 2); /* C3 = SPD byte 70 [7:4] */ + /* Get Control word values for RC4, and RC5 */ +- byte = mctRead_SPD(smbaddr, 71); ++ byte = pDCTstat->spd_data.spd_bytes[i][71]; + pDCTstat->CtrlWrd4 |= (byte & 0xFF) << (i << 2); /* RC4 = SPD byte 71 [3:0] */ + pDCTstat->CtrlWrd5 |= (byte >> 4) << (i << 2); /* RC5 = SPD byte 71 [7:4] */ + } +@@ -6184,14 +6193,14 @@ static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct) { + * 1010 001111 16 3 10 4GB + * 1011 010111 16 3 11 8GB + */ +-u8 crcCheck(u8 smbaddr) ++uint8_t crcCheck(struct DCTStatStruc *pDCTstat, uint8_t dimm) + { + u8 byte_use; + u8 Index; + u16 CRC; + u8 byte, i; + +- byte_use = mctRead_SPD(smbaddr, SPD_ByteUse); ++ byte_use = pDCTstat->spd_data.spd_bytes[dimm][SPD_ByteUse]; + if (byte_use & 0x80) + byte_use = 117; + else +@@ -6199,7 +6208,7 @@ u8 crcCheck(u8 smbaddr) + + CRC = 0; + for (Index = 0; Index < byte_use; Index ++) { +- byte = mctRead_SPD(smbaddr, Index); ++ byte = pDCTstat->spd_data.spd_bytes[dimm][Index]; + CRC ^= byte << 8; + for (i=0; i<8; i++) { + if (CRC & 0x8000) { +@@ -6209,5 +6218,5 @@ u8 crcCheck(u8 smbaddr) + CRC <<= 1; + } + } +- return CRC == (mctRead_SPD(smbaddr, SPD_byte_127) << 8 | mctRead_SPD(smbaddr, SPD_byte_126)); ++ return CRC == (pDCTstat->spd_data.spd_bytes[dimm][SPD_byte_127] << 8 | pDCTstat->spd_data.spd_bytes[dimm][SPD_byte_126]); + } +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +index 50fbff7..5bb09b4 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +@@ -322,6 +322,11 @@ struct MCTStatStruc { + ===============================================================================*/ + #include "mwlc_d.h" /* I have to */ + ++struct amd_spd_node_data { ++ uint8_t spd_bytes[MAX_DIMMS_SUPPORTED][256]; /* [DIMM][byte] */ ++ uint8_t spd_address[MAX_DIMMS_SUPPORTED]; /* [DIMM] */ ++} __attribute__((packed)); ++ + struct DCTStatStruc { /* A per Node structure*/ + /* DCTStatStruct_F - start */ + u8 Node_ID; /* Node ID of current controller */ +@@ -615,6 +620,8 @@ struct DCTStatStruc { /* A per Node structure*/ + char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1]; + uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED]; + uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED]; ++ ++ struct amd_spd_node_data spd_data; + } __attribute__((packed)); + + struct amd_s3_persistent_mct_channel_data { +-- +1.9.1 + |