diff --git a/src/northbridge/amd/amdfam10/raminit_amdmct.c b/src/northbridge/amd/amdfam10/raminit_amdmct.c index f87428ba0c..61a6c0f4cd 100644 --- a/src/northbridge/amd/amdfam10/raminit_amdmct.c +++ b/src/northbridge/amd/amdfam10/raminit_amdmct.c @@ -65,6 +65,7 @@ static void print_t(const char *strval) #include "../amdmct/mct_ddr3/mcthdi.c" #include "../amdmct/mct_ddr3/mctndi_d.c" #include "../amdmct/mct_ddr3/mctchi_d.c" +#include "../amdmct/mct_ddr3/modtrd.c" #if CONFIG_CPU_SOCKET_TYPE == 0x10 //TODO: S1G1? diff --git a/src/northbridge/amd/amdmct/amddefs.h b/src/northbridge/amd/amdmct/amddefs.h index ec894edb07..2d0a12e089 100644 --- a/src/northbridge/amd/amdmct/amddefs.h +++ b/src/northbridge/amd/amdmct/amddefs.h @@ -69,6 +69,8 @@ #define AMD_DRBH_Cx (AMD_DR_Cx | AMD_HY_D0 ) #define AMD_DRBA23_RBC2 (AMD_DR_BA | AMD_DR_B2 | AMD_DR_B3 | AMD_RB_C2 ) +#define AMD_DR_GT_Bx (AMD_DR_ALL & ~(AMD_DR_Ax | AMD_DR_Bx)) +#define AMD_DR_DAC2_OR_C3 (AMD_DA_C2 | AMD_DA_C3) /* * Public Platforms - USE THESE VERSIONS TO MAKE COMPARE WITH CPUPLATFORMTYPE RETURN VALUE diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c index d73bd7d75a..68d16afbf3 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ b/src/northbridge/amd/amdmct/mct/mct_d.c @@ -154,7 +154,10 @@ static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat, static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct); static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); - +static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct); +static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct); /*See mctAutoInitMCT header for index relationships to CL and T*/ static const u16 Table_F_k[] = {00,200,266,333,400,533 }; @@ -822,6 +825,8 @@ static void DCTInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTst all of the MemClkDis bits should also be set.*/ val = 0xFF000000; Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val); + } else { + mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct); } } @@ -1589,7 +1594,7 @@ static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, if ( mctGet_NVbits(NV_ECC)) DramConfigLo |= 1 << DimmEcEn; - + DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct); /* Build Dram Config Hi Register Value */ dword = pDCTstat->Speed; @@ -3630,6 +3635,41 @@ static void mct_AdjustDelayRange_D(struct MCTStatStruc *pMCTstat, } } +static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct) +{ + u32 reg_off = 0x100 * dct; + u32 dev = pDCTstat->dev_dct; + + /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ + if (pDCTstat->LogicalCPUID & (AMD_DA_C2 | AMD_RB_C3)) { + Set_NB32(dev, 0x9C + reg_off, 0x7D0); + Set_NB32(dev, 0x98 + reg_off, 0x4D0FE006); + Set_NB32(dev, 0x9C + reg_off, 0x190); + Set_NB32(dev, 0x98 + reg_off, 0x4D0FE007); + } + + return DramConfigLo | /* DisDllShutdownSR */ 1 << 27; +} + +static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct) +{ + u32 reg_off = 0x100 * dct; + u32 dev = pDCTstat->dev_dct, val; + + /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ + if (pDCTstat->LogicalCPUID & (AMD_DA_C2 | AMD_RB_C3)) { + Set_NB32(dev, 0x9C + reg_off, 0x1C); + Set_NB32(dev, 0x98 + reg_off, 0x4D0FE006); + Set_NB32(dev, 0x9C + reg_off, 0x13D); + Set_NB32(dev, 0x98 + reg_off, 0x4D0FE007); + + val = Get_NB32(dev, 0x90 + reg_off); + val &= ~(1 << 27/* DisDllShutdownSR */); + Set_NB32(dev, 0x90 + reg_off, val); + } +} void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 53aed58447..0894b3f88d 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -80,6 +80,8 @@ static void mct_DramInit(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); +static u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct); static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat); static void Get_Trdrd(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); @@ -133,7 +135,7 @@ static void mct_OtherTiming(struct MCTStatStruc *pMCTstat, static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); + struct DCTStatStruc *pDCTstat, u8 dct); static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat, @@ -153,7 +155,11 @@ static void mct_DramInit_Sw_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct); +static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct); +static u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel); static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dimm); static u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, u8 dct, u32 misc2); @@ -163,6 +169,8 @@ 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 void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat); +static void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat); /*See mctAutoInitMCT header for index relationships to CL and T*/ static const u16 Table_F_k[] = {00,200,266,333,400,533 }; @@ -334,7 +342,7 @@ restartinit: MCTMemClr_D(pMCTstat,pDCTstatA); } - mct_FinalMCT_D(pMCTstat, (pDCTstatA + 0) ); /* Node 0 */ + mct_FinalMCT_D(pMCTstat, pDCTstatA); printk(BIOS_DEBUG, "All Done\n"); return; @@ -819,7 +827,7 @@ static void DCTInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTst val = 0xFF000000; Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val); } else { - /* mct_EnDllShutdownSR */ + mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct); } } @@ -902,7 +910,14 @@ static void ClearDCT_D(struct MCTStatStruc *pMCTstat, } while(reg < reg_end) { + if ((reg & 0xFF) == 0x90) { + if (pDCTstat->LogicalCPUID & AMD_DR_Dx) { + val = Get_NB32(dev, reg); /* get DRAMConfigLow */ + val |= 0x08000000; /* preserve value of DisDllShutdownSR for only Rev.D */ + } + } Set_NB32(dev, reg, val); + val = 0; reg += 4; } @@ -1485,6 +1500,7 @@ static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, if (pDCTstat->GangedMode == 1) { mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1); + mct_BeforePlatformSpec(pMCTstat, pDCTstat, 1); } if ( pDCTstat->_2Tmode == 2) { @@ -1495,6 +1511,7 @@ static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, Set_NB32(dev, reg, val); } + mct_BeforePlatformSpec(pMCTstat, pDCTstat, dct); mct_PlatformSpec(pMCTstat, pDCTstat, dct); if (pDCTstat->DIMMAutoSpeed == 4) InitPhyCompensation(pMCTstat, pDCTstat, dct); @@ -1674,7 +1691,7 @@ static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, dword = Get_NB32(dev, 0x94 + reg_off); DramConfigHi |= dword; mct_SetDramConfigHi_D(pDCTstat, dct, DramConfigHi); - mct_EarlyArbEn_D(pMCTstat, pDCTstat); + mct_EarlyArbEn_D(pMCTstat, pDCTstat, dct); mctHookAfterAutoCfg(); /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */ @@ -2341,6 +2358,25 @@ void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data) } +static u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct) +{ + /* mct_checkForCxDxSupport_D */ + if (pDCTstat->LogicalCPUID & AMD_DR_GT_Bx) { + /* 1. Write 00000000h to F2x[1,0]9C_xD08E000 */ + Set_NB32_index_wait(pDCTstat->dev_dct, 0x98 + dct * 0x100, 0x0D08E000, 0); + /* 2. If DRAM Configuration Register[MemClkFreq] (F2x[1,0]94[2:0]) is + greater than or equal to 011b (DDR-800 and higher), + then write 00000080h to F2x[1,0]9C_xD02E001, + else write 00000090h to F2x[1,0]9C_xD02E001. */ + if (pDCTstat->Speed >= 4) + Set_NB32_index_wait(pDCTstat->dev_dct, 0x98 + dct * 0x100, 0xD02E001, 0x80); + else + Set_NB32_index_wait(pDCTstat->dev_dct, 0x98 + dct * 0x100, 0xD02E001, 0x90); + } + return pDCTstat->ErrCode; +} + static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { @@ -2368,7 +2404,6 @@ static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, } return pDCTstat->ErrCode; - } static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat) @@ -2870,11 +2905,97 @@ static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, return word; } -static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) +static void mct_PhyController_Config(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct) { + u32 index_reg = 0x98 + 0x100 * dct; + u32 dev = pDCTstat->dev_dct; + u32 val; + + if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3 | AMD_RB_C3)) { + if (pDCTstat->Dimmx4Present == 0) { + /* Set bit7 RxDqsUDllPowerDown to register F2x[1, 0]98_x0D0F0F13 for power saving */ + val = Get_NB32_index_wait(dev, index_reg, 0x0D0F0F13); /* Agesa v3 v6 might be wrong here. */ + val |= 1 << 7; /* BIOS should set this bit when x4 DIMMs are not present */ + Set_NB32_index_wait(dev, index_reg, 0x0D0F0F13, val); + } + } + + if (pDCTstat->LogicalCPUID & AMD_DR_DAC2_OR_C3) { + if (pDCTstat->DimmECCPresent == 0) { + /* Set bit4 PwrDn to register F2x[1, 0]98_x0D0F0830 for power saving */ + val = Get_NB32_index_wait(dev, index_reg, 0x0D0F0830); + val |= 1 << 4; /* BIOS should set this bit if ECC DIMMs are not present */ + Set_NB32_index_wait(dev, index_reg, 0x0D0F0830, val); + } + } + +} + +static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstatA) +{ + u8 Node; + struct DCTStatStruc *pDCTstat; + u32 val; + + for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { + pDCTstat = pDCTstatA + Node; + + if (pDCTstat->NodePresent) { + mct_PhyController_Config(pMCTstat, pDCTstat, 0); + mct_PhyController_Config(pMCTstat, pDCTstat, 1); + } + if (!(pDCTstat->LogicalCPUID & AMD_DR_Dx)) { /* mct_checkForDxSupport */ + mct_ExtMCTConfig_Cx(pDCTstat); + mct_ExtMCTConfig_Bx(pDCTstat); + } else { /* For Dx CPU */ + val = 0x0CE00F00 | 1 << 29/* FlushWrOnStpGnt */; + if (!(pDCTstat->GangedMode)) + val |= 0x20; /* MctWrLimit = 8 for Unganed mode */ + else + val |= 0x40; /* MctWrLimit = 16 for ganed mode */ + Set_NB32(pDCTstat->dev_dct, 0x11C, val); + + val = Get_NB32(pDCTstat->dev_dct, 0x1B0); + val &= 0xFFFFF8C0; + val |= 0x101; /* BKDG recommended settings */ + val |= 0x0FC00000; /* Agesa V5 */ + if (!(pDCTstat->GangedMode)) + val |= 1 << 12; + else + val &= ~(1 << 12); + + val &= 0x0FFFFFFF; + switch (pDCTstat->Speed) { + case 4: + val |= 0x50000000; /* 5 for DDR800 */ + break; + case 5: + val |= 0x60000000; /* 6 for DDR1066 */ + break; + case 6: + val |= 0x80000000; /* 8 for DDR800 */ + break; + default: + val |= 0x90000000; /* 9 for DDR1600 */ + break; + } + Set_NB32(pDCTstat->dev_dct, 0x1B0, val); + } + } + /* ClrClToNB_D postponed until we're done executing from ROM */ mct_ClrWbEnhWsbDis_D(pMCTstat, pDCTstat); + + /* set F3x8C[DisFastTprWr] on all DR, if L3Size=0 */ + if (pDCTstat->LogicalCPUID & AMD_DR_ALL) { + if (!(cpuid_edx(0x80000006) & 0xFFFC0000)) { + val = Get_NB32(pDCTstat->dev_nbmisc, 0x8C); + val |= 1 << 24; + Set_NB32(pDCTstat->dev_nbmisc, 0x8C, val); + } + } } static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) @@ -3138,7 +3259,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, } static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) + struct DCTStatStruc *pDCTstat, u8 dct) { u32 reg; u32 val; @@ -3150,10 +3271,10 @@ static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, * bit 19 of F2x[1,0]78 Dram Control Register, set this bit only when * NB CLK : Memclk ratio is between 3:1 (inclusive) to 4:5 (inclusive) */ - reg = 0x78; + reg = 0x78 + 0x100 * dct; val = Get_NB32(dev, reg); - if (pDCTstat->LogicalCPUID & (AMD_DR_Bx | AMD_DR_Cx)) + if (pDCTstat->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Dx)) val |= (1 << EarlyArbEn); else if (CheckNBCOFEarlyArbEn(pMCTstat, pDCTstat)) val |= (1 << EarlyArbEn); @@ -3272,6 +3393,25 @@ static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, } } +static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct) +{ + u32 reg_off = 0x100 * dct; + u32 dev = pDCTstat->dev_dct, val; + + /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ + if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3)) { + Set_NB32(dev, 0x9C + reg_off, 0x1C); + Set_NB32(dev, 0x98 + reg_off, 0x4D0FE006); + Set_NB32(dev, 0x9C + reg_off, 0x13D); + Set_NB32(dev, 0x98 + reg_off, 0x4D0FE007); + + val = Get_NB32(dev, 0x90 + reg_off); + val &= ~(1 << 27/* DisDllShutdownSR */); + Set_NB32(dev, 0x90 + reg_off, val); + } +} + static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct) { @@ -3279,14 +3419,16 @@ static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, u32 dev = pDCTstat->dev_dct; /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ - if (pDCTstat->LogicalCPUID & (AMD_DA_C2 | AMD_RB_C3)) { - Set_NB32(dev, 0x9C + reg_off, 0x1c); + if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3)) { + Set_NB32(dev, 0x9C + reg_off, 0x7D0); Set_NB32(dev, 0x98 + reg_off, 0x4D0FE006); - Set_NB32(dev, 0x9C + reg_off, 0x13d); + Set_NB32(dev, 0x9C + reg_off, 0x190); Set_NB32(dev, 0x98 + reg_off, 0x4D0FE007); + + DramConfigLo |= /* DisDllShutdownSR */ 1 << 27; } - return DramConfigLo | /* DisDllShutdownSR */ 1 << 27; + return DramConfigLo; } void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat, @@ -3352,40 +3494,6 @@ void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, _WRMSR(msr, lo, hi); } -static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dimm) -{ - u8 DimmsInstalled = dimm; - u32 DramTermDyn = 0; - u8 Speed = pDCTstat->Speed; - - if (mctGet_NVbits(NV_MAX_DIMMS) == 4) { - if (pDCTstat->CSPresent & 0xF0) { - if (DimmsInstalled == 1) - if (Speed == 7) - DramTermDyn |= 1 << 10; - else - DramTermDyn |= 1 << 11; - else - if (Speed == 4) - DramTermDyn |= 1 << 11; - else - DramTermDyn |= 1 << 10; - } else { - if (DimmsInstalled != 1) { - if (Speed == 7) - DramTermDyn |= 1 << 10; - else - DramTermDyn |= 1 << 11; - } - } - } else { - if (DimmsInstalled != 1) - DramTermDyn |= 1 << 11; - } - return DramTermDyn; -} - void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c index c89a32528e..54fdedf08c 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c @@ -552,6 +552,18 @@ static void TrainDQSPos_D(struct MCTStatStruc *pMCTstat, } if (BanksPresent) { + #if 0 /* show the bitmap */ + for (ByteLane = 0; ByteLane < 8; ByteLane++) { /* just print ByteLane 0 */ + for (DQSDelay = 0; DQSDelay < dqsDelay_end; DQSDelay++) { + if (!(MutualCSPassW[DQSDelay] &(1 << ByteLane))) { + printk(BIOS_DEBUG, "."); + } else { + printk(BIOS_DEBUG, "*"); + } + } + printk(BIOS_DEBUG, "\n"); + } + #endif for (ByteLane = 0; ByteLane < 8; ByteLane++) { print_debug_dqs("\t\t\t\tTrainDQSPos: 31 ByteLane ",ByteLane, 4); if (!(pDCTstat->DqsRdWrPos_Saved &(1 << ByteLane))) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c index bf9222339d..79875faa71 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c @@ -190,7 +190,6 @@ static void WriteLevelization_HW(struct MCTStatStruc *pMCTstat, SetTargetFreq(pMCTstat, pDCTstat); PhyWLPass2(pMCTstat, pDCTstat, 0); PhyWLPass2(pMCTstat, pDCTstat, 1); - } SetEccWrDQS_D(pMCTstat, pDCTstat); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c b/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c index cfd4adfa6f..118d8eb80b 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c @@ -35,3 +35,10 @@ void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat) Set_NB32(pDCTstat->dev_dct, 0x198, 0x4D0F4F07); } } + +void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat) +{ + if (pDCTstat->LogicalCPUID & (AMD_DR_Bx)) { + Set_NB32(pDCTstat->dev_dct, 0x11C, 0x0FE40FC0 | 1 << 29/* FlushWrOnStpGnt */); + } +} diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c index a40dda42c7..d758dada39 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/* mct_SetDramConfigMisc2_Cx & mct_SetDramConfigMisc2_Dx */ u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, u8 dct, u32 misc2) { u32 val; @@ -40,6 +41,22 @@ u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, u8 dct, u32 misc2) val &= 0xFF; misc2 &= 0xFFF8FFFF; misc2 |= val << 16; /* DataTxFifoWrDly */ + if (pDCTstat->LogicalCPUID & AMD_DR_Dx) + misc2 |= 1 << 7; /* ProgOdtEn */ } return misc2; } + +void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat) +{ + u32 val; + + if (pDCTstat->LogicalCPUID & (AMD_DR_Cx)) { + Set_NB32(pDCTstat->dev_dct, 0x11C, 0x0CE00FC0 | 1 << 29/* FlushWrOnStpGnt */); + + val = Get_NB32(pDCTstat->dev_dct, 0x1B0); + val &= 0xFFFFF8C0; + val |= 0x101; /* BKDG recommended settings */ + Set_NB32(pDCTstat->dev_dct, 0x1B0, val); + } +} diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c index 4f5a360f94..b7bcd15c45 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c @@ -25,7 +25,7 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, u32 dct = 0; u32 reg_off = 0; - DimmNum = MrsChipSel >> 20; + DimmNum = (MrsChipSel >> 20) & 0xFE; /* assume dct=0; */ /* if (dct == 1) */ @@ -39,6 +39,7 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, dct = 0; } else if (pDCTstat->CSPresent_DCT[1] > 0 ){ dct = 1; + DimmNum ++; } reg_off = 0x100 * dct; Dimms = pDCTstat->MAdimms[dct]; @@ -49,27 +50,26 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, else if (CtrlWordNum == 1) { if (!((pDCTstat->DimmDRPresent | pDCTstat->DimmQRPresent) & (1 << DimmNum))) val |= 0xC; /* if single rank, set DBA1 and DBA0 */ - } - else if (CtrlWordNum == 2) { + } else if (CtrlWordNum == 2) { if (MaxDimm == 4) { if (Speed == 4) { - if (((pDCTstat->DimmQRPresent & (1 << DimmNum)) && (Dimms == 1)) || Dimms == 2) + if (((pDCTstat->DimmQRPresent & (1 << DimmNum)) && (Dimms == 1)) || (Dimms == 2)) if (!(pDCTstat->MirrPresU_NumRegR & (1 << DimmNum))) val |= 1 << 2; } else { if (pDCTstat->MirrPresU_NumRegR & (1 << DimmNum)) - val |= 2; + val |= 1 << 2; } } else { if (Dimms > 1) - val |= 2; + val |= 1 << 2; } } else if (CtrlWordNum == 3) { - val = pDCTstat->CtrlWrd3 >> (DimmNum << 2); + val |= (pDCTstat->CtrlWrd3 >> (DimmNum << 2)) & 0xFF; } else if (CtrlWordNum == 4) { - val = pDCTstat->CtrlWrd4 >> (DimmNum << 2); + val |= (pDCTstat->CtrlWrd4 >> (DimmNum << 2)) & 0xFF; } else if (CtrlWordNum == 5) { - val = pDCTstat->CtrlWrd5 >> (DimmNum << 2); + val |= (pDCTstat->CtrlWrd5 >> (DimmNum << 2)) & 0xFF; } else if (CtrlWordNum == 8) { if (MaxDimm == 4) if (Speed == 4) @@ -78,9 +78,9 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, } else if (CtrlWordNum == 9) { val |= 0xD; /* DBA1, DBA0, DA3 = 0 */ } - val &= 0xf; + val &= 0xffffff0f; - val = MrsChipSel | ((val >> 2) & 3) << 16 | MrsChipSel | ((val >> 2) & 3); + val = MrsChipSel | ((val >> 2) & 3) << 16 | ((val & 3) << 3); /* transfer Control word number to address [BA2,A2,A1,A0] */ if (CtrlWordNum > 7) { @@ -170,17 +170,19 @@ void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat, pDCTstat->DIMMAutoSpeed = pDCTstat->TargetFreq; for (MrsChipSel=0; MrsChipSel < 8; MrsChipSel++, MrsChipSel++) { if (pDCTstat->CSPresent & (1 << MrsChipSel)) { - val = Get_NB32(dev, 0xA8); + /* 2. Program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects. */ + val = Get_NB32(dev, 0xA8); /* TODO: dct * 0x100 + 0xA8 */ val &= ~(0xFF << 8); - val |= (0x3 << MrsChipSel) << 8; - Set_NB32(dev, 0xA8, val); + val |= (0x3 << (MrsChipSel & 0xFE)) << 8; + Set_NB32(dev, 0xA8, val); /* TODO: dct * 0x100 + 0xA8 */ + /* Resend control word 10 */ mct_Wait(1600); switch (pDCTstat->TargetFreq) { - case 6: + case 5: mct_SendCtrlWrd(pMCTstat, pDCTstat, MrsChipSel << 20 | 0x4000A); break; - case 5: + case 6: mct_SendCtrlWrd(pMCTstat, pDCTstat, MrsChipSel << 20 | 0x40012); break; case 7: @@ -190,6 +192,7 @@ void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat, mct_Wait(1600); + /* Resend control word 2 */ val = mct_ControlRC(pMCTstat, pDCTstat, MrsChipSel << 20, 2); mct_SendCtrlWrd(pMCTstat, pDCTstat, val); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c index 18ef4770e2..3318896fe4 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c @@ -158,7 +158,7 @@ static u32 mct_MR1(struct MCTStatStruc *pMCTstat, if (dword & (1 << 7)) ret |= 1 << 2; } else { - /* TODO: mct_MR1Odt_RDimm */ + ret |= mct_MR1Odt_RDimm(pMCTstat, pDCTstat, dct, MrsChipSel); } /* program MrsAddress[11]=TDQS: based on F2x[1,0]94[RDqsEn] */ diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c index 76ddb88d53..e0cda14b8a 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c @@ -1012,7 +1012,7 @@ static void fenceDynTraining_D(struct MCTStatStruc *pMCTstat, /* Write the (averaged value -8) to F2x[1,0]9C_x0C[PhyFence]. */ /* inlined mct_AdjustFenceValue() */ - /* The RBC0 is not supported. */ + /* TODO: The RBC0 is not supported. */ /* if (pDCTstat->LogicalCPUID & AMD_RB_C0) avRecValue -= 3; else diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c index d4b531f3af..57d56814c1 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c @@ -351,7 +351,7 @@ static void Modify_OnDimmMirror(struct DCTStatStruc *pDCTstat, u8 dct, u8 set) { u32 val; u32 reg_off = dct * 0x100 + 0x44; - while (reg_off < 0x60) { + while (reg_off < (dct * 0x100 + 0x60)) { val = Get_NB32(pDCTstat->dev_dct, reg_off); if (val & (1 << CSEnable)) set ? (val |= 1 << onDimmMirror) : (val &= ~(1<Speed; + u32 ret; + u8 DimmsInstalled, DimmNum, ChipSelect; + + ChipSelect = (MrsChipSel >> 20) & 0xF; + DimmNum = ChipSelect & 0xFE; + DimmsInstalled = pDCTstat->MAdimms[dct]; + if (dct == 1) + DimmNum ++; + ret = 0; + + if (mctGet_NVbits(NV_MAX_DIMMS) == 4) { + if (DimmsInstalled == 1) + ret |= 1 << 2; + else { + if (pDCTstat->CSPresent & 0xF0) { + if (pDCTstat->DimmQRPresent & (1 << DimmNum)) { + if (!(ChipSelect & 1)) + ret |= 1 << 2; + } else + ret |= 0x204; + } else { + if (Speed < 6) + ret |= 0x44; + else + ret |= 0x204; + } + } + } else if (DimmsInstalled == 1) + ret |= 1 << 2; + else if (Speed < 6) + ret |= 0x44; + else + ret |= 0x204; + + //ret = 0; + return ret; +} + +static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dimm) +{ + u8 DimmsInstalled = dimm; + u32 DramTermDyn = 0; + u8 Speed = pDCTstat->Speed; + + if (mctGet_NVbits(NV_MAX_DIMMS) == 4) { + if (pDCTstat->CSPresent & 0xF0) { + if (DimmsInstalled == 1) + if (Speed == 7) + DramTermDyn |= 1 << 10; + else + DramTermDyn |= 1 << 11; + else + if (Speed == 4) + DramTermDyn |= 1 << 11; + else + DramTermDyn |= 1 << 10; + } else { + if (DimmsInstalled != 1) { + if (Speed == 7) + DramTermDyn |= 1 << 10; + else + DramTermDyn |= 1 << 11; + } + } + } else { + if (DimmsInstalled != 1) + DramTermDyn |= 1 << 11; + } + return DramTermDyn; +}