From aabb2b44191d7a2716dd89a0b9f3488b2d657cb9 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 27 Aug 2015 23:37:38 -0500 Subject: [PATCH 127/139] northbridge/amd/amdmct/mct_ddr3: Fix broken support for multiple DIMMs on single channel Change-Id: I0278656e98461882d0a64519dfde54a6cf28ab0f Signed-off-by: Timothy Pearson --- src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 336 ++++++++++++++++++++----- src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 8 +- src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c | 2 +- src/northbridge/amd/amdmct/mct_ddr3/mctrci.c | 26 +- src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 4 + src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c | 8 +- 6 files changed, 310 insertions(+), 74 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index a11b227..5bc80f4 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -1360,6 +1360,224 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc return slow_access; } +static uint8_t fam15h_odt_tristate_enable_code(struct DCTStatStruc *pDCTstat, uint8_t dct) +{ + uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); + + uint8_t package_type; + uint8_t odt_tristate_code = 0; + + package_type = mctGet_NVbits(NV_PACK_TYPE); + + /* Obtain number of DIMMs on channel */ + uint8_t dimm_count = pDCTstat->MAdimms[dct]; + uint8_t rank_count_dimm0; + uint8_t rank_count_dimm1; + + if (package_type == PT_GR) { + /* Socket G34 */ + if (pDCTstat->Status & (1 << SB_Registered)) { + /* RDIMM */ + /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 104 */ + if (MaxDimmsInstallable == 1) { + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm0 == 1) + odt_tristate_code = 0xe; + else + odt_tristate_code = 0xa; + } else if (MaxDimmsInstallable == 2) { + if (dimm_count == 1) { + /* 1 DIMM detected */ + rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm1 == 1) + odt_tristate_code = 0xd; + else + odt_tristate_code = 0x5; + } else if (dimm_count == 2) { + /* 2 DIMMs detected */ + rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; + rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) + odt_tristate_code = 0xc; + else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 >= 2)) + odt_tristate_code = 0x4; + else if ((rank_count_dimm0 >= 2) && (rank_count_dimm1 == 1)) + odt_tristate_code = 0x8; + else + odt_tristate_code = 0x0; + } + } else if (MaxDimmsInstallable == 3) { + /* TODO + * 3 DIMM/channel support unimplemented + */ + } + } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { + /* LRDIMM */ + + /* TODO + * Implement LRDIMM support + * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 105 + */ + } else { + /* UDIMM */ + /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 103 */ + if (MaxDimmsInstallable == 1) { + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm0 == 1) + odt_tristate_code = 0xe; + else + odt_tristate_code = 0xa; + } else if (MaxDimmsInstallable == 2) { + if (dimm_count == 1) { + /* 1 DIMM detected */ + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm0 == 1) + odt_tristate_code = 0xd; + else + odt_tristate_code = 0x5; + } else if (dimm_count == 2) { + /* 2 DIMMs detected */ + rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; + rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) + odt_tristate_code = 0xc; + else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) + odt_tristate_code = 0x4; + else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) + odt_tristate_code = 0x8; + else + odt_tristate_code = 0x0; + } + } else if (MaxDimmsInstallable == 3) { + /* TODO + * 3 DIMM/channel support unimplemented + */ + } + } + } else { + /* TODO + * Other socket support unimplemented + */ + } + + return odt_tristate_code; +} + +static uint8_t fam15h_cs_tristate_enable_code(struct DCTStatStruc *pDCTstat, uint8_t dct) +{ + uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); + + uint8_t package_type; + uint8_t cs_tristate_code = 0; + + package_type = mctGet_NVbits(NV_PACK_TYPE); + + /* Obtain number of DIMMs on channel */ + uint8_t dimm_count = pDCTstat->MAdimms[dct]; + uint8_t rank_count_dimm0; + uint8_t rank_count_dimm1; + + if (package_type == PT_GR) { + /* Socket G34 */ + if (pDCTstat->Status & (1 << SB_Registered)) { + /* RDIMM */ + /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 104 */ + if (MaxDimmsInstallable == 1) { + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm0 < 4) + cs_tristate_code = 0xfc; + else + cs_tristate_code = 0xcc; + } else if (MaxDimmsInstallable == 2) { + if (dimm_count == 1) { + /* 1 DIMM detected */ + rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm1 < 4) + cs_tristate_code = 0xf3; + else + cs_tristate_code = 0x33; + } else if (dimm_count == 2) { + /* 2 DIMMs detected */ + rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; + rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) + cs_tristate_code = 0xf0; + else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4)) + cs_tristate_code = 0x30; + else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4)) + cs_tristate_code = 0xc0; + else + cs_tristate_code = 0x0; + } + } else if (MaxDimmsInstallable == 3) { + /* TODO + * 3 DIMM/channel support unimplemented + */ + } + } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { + /* LRDIMM */ + + /* TODO + * Implement LRDIMM support + * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 105 + */ + } else { + /* UDIMM */ + /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 103 */ + if (MaxDimmsInstallable == 1) { + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm0 == 1) + cs_tristate_code = 0xfe; + else + cs_tristate_code = 0xfc; + } else if (MaxDimmsInstallable == 2) { + if (dimm_count == 1) { + /* 1 DIMM detected */ + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if (rank_count_dimm0 == 1) + cs_tristate_code = 0xfb; + else + cs_tristate_code = 0xf3; + } else if (dimm_count == 2) { + /* 2 DIMMs detected */ + rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; + rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; + + if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) + cs_tristate_code = 0xfa; + else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) + cs_tristate_code = 0xf2; + else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) + cs_tristate_code = 0xf8; + else + cs_tristate_code = 0xf0; + } + } else if (MaxDimmsInstallable == 3) { + /* TODO + * 3 DIMM/channel support unimplemented + */ + } + } + } else { + /* TODO + * Other socket support unimplemented + */ + } + + return cs_tristate_code; +} + static void set_2t_configuration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { @@ -2299,20 +2517,16 @@ static void fam15EnableTrainingMode(struct MCTStatStruc *pMCTstat, if (memclk_index <= 0x6) { delay = 0x5; delay2 = 0x3; - } - else if (memclk_index == 0xa) { + } else if (memclk_index == 0xa) { delay = 0x6; delay2 = 0x3; - } - else if (memclk_index == 0xe) { + } else if (memclk_index == 0xe) { delay = 0x7; delay2 = 0x4; - } - else if (memclk_index == 0x12) { + } else if (memclk_index == 0x12) { delay = 0x8; delay2 = 0x4; - } - else if (memclk_index == 0x16) { + } else if (memclk_index == 0x16) { delay = 0xa; delay2 = 0x5; } @@ -3329,8 +3543,7 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, tCK16x = 40; else tCK16x = 48; - } - else { + } else { if (byte == 7) tCK16x = 20; else if (byte == 6) @@ -4657,13 +4870,13 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, else pDCTstat->RegMan1Present |= 1 << i; } - /* Get Control word values for RC3. We dont need it. */ + /* Get control word value for RC3 */ 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 */ + pDCTstat->CtrlWrd3 |= ((byte >> 4) & 0xf) << (i << 2); /* RC3 = SPD byte 70 [7:4] */ + /* Get control word values for RC4 and RC5 */ 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] */ + pDCTstat->CtrlWrd4 |= (byte & 0xf) << (i << 2); /* RC4 = SPD byte 71 [3:0] */ + pDCTstat->CtrlWrd5 |= ((byte >> 4) & 0xf) << (i << 2); /* RC5 = SPD byte 71 [7:4] */ } } } @@ -5849,23 +6062,27 @@ static void SetCSTriState(struct MCTStatStruc *pMCTstat, u32 val; u32 dev = pDCTstat->dev_dct; u32 index_reg = 0x98; - u32 index; u16 word; - /* Tri-state unused chipselects when motherboard - termination is available */ + if (is_fam15h()) { + word = fam15h_cs_tristate_enable_code(pDCTstat, dct); + } else { + /* Tri-state unused chipselects when motherboard + termination is available */ - /* FIXME: skip for Ax */ + /* FIXME: skip for Ax */ - word = pDCTstat->CSPresent; - if (pDCTstat->Status & (1 << SB_Registered)) { - word |= (word & 0x55) << 1; + word = pDCTstat->CSPresent; + if (pDCTstat->Status & (1 << SB_Registered)) { + word |= (word & 0x55) << 1; + } + word = (~word) & 0xff; } - word = (~word) & 0xFF; - index = 0x0c; - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); + + val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c); + val &= ~0xff; val |= word; - Set_NB32_index_wait_DCT(dev, dct, index_reg, index, val); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, val); } static void SetCKETriState(struct MCTStatStruc *pMCTstat, @@ -5874,7 +6091,6 @@ static void SetCKETriState(struct MCTStatStruc *pMCTstat, u32 val; u32 dev; u32 index_reg = 0x98; - u32 index; u16 word; /* Tri-state unused CKEs when motherboard termination is available */ @@ -5884,15 +6100,13 @@ static void SetCKETriState(struct MCTStatStruc *pMCTstat, dev = pDCTstat->dev_dct; word = pDCTstat->CSPresent; - index = 0x0c; - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); + val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c); + val &= ~(0x3 << 12); if ((word & 0x55) == 0) val |= 1 << 12; - - if ((word & 0xAA) == 0) + if ((word & 0xaa) == 0) val |= 1 << 13; - - Set_NB32_index_wait_DCT(dev, dct, index_reg, index, val); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, val); } static void SetODTTriState(struct MCTStatStruc *pMCTstat, @@ -5902,42 +6116,44 @@ static void SetODTTriState(struct MCTStatStruc *pMCTstat, u32 dev; u32 index_reg = 0x98; u8 cs; - u32 index; u8 odt; u8 max_dimms; - /* FIXME: skip for Ax */ - dev = pDCTstat->dev_dct; - /* Tri-state unused ODTs when motherboard termination is available */ - max_dimms = (u8) mctGet_NVbits(NV_MAX_DIMMS); - odt = 0x0F; /* ODT tri-state setting */ - - if (pDCTstat->Status & (1 <CSPresent & (1 << cs)) { - odt &= ~(1 << (cs / 2)); - if (mctGet_NVbits(NV_4RANKType) != 0) { /* quad-rank capable platform */ - if (pDCTstat->CSPresent & (1 << (cs + 1))) - odt &= ~(4 << (cs / 2)); + if (is_fam15h()) { + odt = fam15h_odt_tristate_enable_code(pDCTstat, dct); + } else { + /* FIXME: skip for Ax */ + + /* Tri-state unused ODTs when motherboard termination is available */ + max_dimms = (u8) mctGet_NVbits(NV_MAX_DIMMS); + odt = 0x0f; /* ODT tri-state setting */ + + if (pDCTstat->Status & (1 <CSPresent & (1 << cs)) { + odt &= ~(1 << (cs / 2)); + if (mctGet_NVbits(NV_4RANKType) != 0) { /* quad-rank capable platform */ + if (pDCTstat->CSPresent & (1 << (cs + 1))) + odt &= ~(4 << (cs / 2)); + } } } + } else { /* AM3 package */ + val = ~(pDCTstat->CSPresent); + odt = val & 9; /* swap bits 1 and 2 */ + if (val & (1 << 1)) + odt |= 1 << 2; + if (val & (1 << 2)) + odt |= 1 << 1; } - } else { /* AM3 package */ - val = ~(pDCTstat->CSPresent); - odt = val & 9; /* swap bits 1 and 2 */ - if (val & (1 << 1)) - odt |= 1 << 2; - if (val & (1 << 2)) - odt |= 1 << 1; } - index = 0x0C; - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); - val |= ((odt & 0xFF) << 8); /* set bits 11:8 ODTTriState[3:0] */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, index, val); - + val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c); + val &= ~(0xf << 8); /* ODTTri = odt */ + val |= (odt & 0xf) << 8; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, val); } /* Family 15h */ @@ -6507,7 +6723,7 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat, dword |= (read_odt_delay & 0xf); Set_NB32_DCT(dev, dct, 0x240, dword); - printk(BIOS_SPEW, "Programmed ODT pattern %08x %08x %08x %08x\n", odt_pattern_0, odt_pattern_1, odt_pattern_2, odt_pattern_3); + printk(BIOS_SPEW, "Programmed DCT %d ODT pattern %08x %08x %08x %08x\n", dct, odt_pattern_0, odt_pattern_1, odt_pattern_2, odt_pattern_3); } else if (pDCTstat->LogicalCPUID & AMD_DR_Dx) { if (pDCTstat->Speed == 3) dword = 0x00000800; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h index ec5658e..8bc4ec2 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h @@ -582,7 +582,7 @@ struct DCTStatStruc { /* A per Node structure*/ uint8_t NbPstateThreshold; uint8_t NbPstateHi; -/* New for LB Support */ + /* New for LB Support */ u8 NodePresent; u32 dev_host; u32 dev_map; @@ -592,9 +592,9 @@ struct DCTStatStruc { /* A per Node structure*/ u32 dev_nbctl; u8 TargetFreq; u8 TargetCASL; - u8 CtrlWrd3; - u8 CtrlWrd4; - u8 CtrlWrd5; + uint32_t CtrlWrd3; + uint32_t CtrlWrd4; + uint32_t CtrlWrd5; u8 DqsRdWrPos_Saved; u8 DqsRcvEnGrossMax; u8 DqsRcvEnGrossMin; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c index d870f17..553a54a 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c @@ -1021,7 +1021,7 @@ static void Calc_SetMaxRdLatency_D_Fam15(struct MCTStatStruc *pMCTstat, pDCTstat->CH_MaxRdLat[dct] = n - 1; #if DQS_TRAIN_DEBUG > 0 - printk(BIOS_DEBUG, "%s: CH_MaxRdLat[%d]: %03x\n", __func__, dct, pDCTstat->CH_MaxRdLat[dct]); + printk(BIOS_DEBUG, "%s: CH_MaxRdLat[%d]: %03x\n", __func__, dct, pDCTstat->CH_MaxRdLat[dct]); #endif } diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c index 8fd2523..dec2bf8 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c @@ -18,7 +18,7 @@ * Foundation, Inc. */ -static uint8_t fam15h_rdimm_rc2_control_code(struct DCTStatStruc *pDCTstat, uint8_t dct) +static uint8_t fam15h_rdimm_rc2_ibt_code(struct DCTStatStruc *pDCTstat, uint8_t dct) { uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); @@ -161,7 +161,7 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, val = 0xc; /* if single rank, set DBA1 and DBA0 */ } else if (CtrlWordNum == 2) { if (is_fam15h()) { - val = fam15h_rdimm_rc2_control_code(pDCTstat, dct); + val = (fam15h_rdimm_rc2_ibt_code(pDCTstat, dct) & 0x1) << 2; } else { if (package_type == PT_GR) { /* Socket G34 */ @@ -178,10 +178,14 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, } else if (CtrlWordNum == 5) { val = (pDCTstat->CtrlWrd5 >> (DimmNum << 2)) & 0xff; } else if (CtrlWordNum == 8) { - if (package_type == PT_GR) { - /* Socket G34 */ - if (MaxDimmsInstallable == 2) { - val = 0x0; + if (is_fam15h()) { + val = (fam15h_rdimm_rc2_ibt_code(pDCTstat, dct) & 0xe) >> 1; + } else { + if (package_type == PT_GR) { + /* Socket G34 */ + if (MaxDimmsInstallable == 2) { + val = 0x0; + } } } } else if (CtrlWordNum == 9) { @@ -233,7 +237,11 @@ void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat, mct_Wait(1200); - for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel ++, MrsChipSel ++) { + pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct]; + if (pDCTstat->GangedMode & 1) + pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0]; + + for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel += 2) { if (pDCTstat->CSPresent & (1 << MrsChipSel)) { val = Get_NB32_DCT(dev, dct, 0xa8); val &= ~(0xff << 8); @@ -276,6 +284,10 @@ void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat, u32 val; uint16_t mem_freq; + pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct]; + if (pDCTstat->GangedMode & 1) + pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0]; + pDCTstat->DIMMAutoSpeed = pDCTstat->TargetFreq; mem_freq = memclk_to_freq(pDCTstat->TargetFreq); for (MrsChipSel=0; MrsChipSel < 8; MrsChipSel++, MrsChipSel++) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c index 7804a38..5019faa 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c @@ -845,6 +845,10 @@ void mct_DramInit_Sw_D(struct MCTStatStruc *pMCTstat, */ } + pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct]; + if (pDCTstat->GangedMode & 1) + pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0]; + /* The following steps are performed once for unbuffered DIMMs and once for each * chip select on registered DIMMs: */ for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel++) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c index 73b231e..5cbadc3 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c @@ -925,7 +925,7 @@ void prepareDimms(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, * OUT * ---------------------------------------------------------------------------- */ -void programODT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, u8 dimm) +void programODT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm) { sMCTStruct *pMCTData = pDCTstat->C_MCTPtr; sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct]; @@ -933,6 +933,10 @@ void programODT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, ui u8 WrLvOdt1=0; if (is_fam15h()) { + /* On Family15h processors, the value for the specific CS being targetted + * is taken from F2x238 / F2x23C as appropriate, then loaded into F2x9C_x0000_0008 + */ + /* Convert DIMM number to CS */ uint32_t dword; uint8_t cs; @@ -967,7 +971,7 @@ void programODT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, ui set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT, DRAM_ADD_DCT_PHY_CONTROL_REG, 8, 11, (u32)WrLvOdt1); - printk(BIOS_SPEW, "Programmed DCT %d write levelling ODT pattern %08x\n", dct, WrLvOdt1); + printk(BIOS_SPEW, "Programmed DCT %d write levelling ODT pattern %08x from DIMM %d data\n", dct, WrLvOdt1, dimm); } -- 1.9.1