Fix some settings fo AMD MCT. It is based on BIOS test suite.
authorZheng Bao <zheng.bao@amd.com>
Thu, 6 Jan 2011 02:18:12 +0000 (02:18 +0000)
committerZheng Bao <Zheng.Bao@amd.com>
Thu, 6 Jan 2011 02:18:12 +0000 (02:18 +0000)
Signed-off-by: Zheng Bao <zheng.bao@amd.com>
Acked-by: Stefan Reinauer <stepan@coreboot.org>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6246 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

13 files changed:
src/northbridge/amd/amdfam10/raminit_amdmct.c
src/northbridge/amd/amdmct/amddefs.h
src/northbridge/amd/amdmct/mct/mct_d.c
src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c
src/northbridge/amd/amdmct/mct_ddr3/mctprob.c
src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
src/northbridge/amd/amdmct/mct_ddr3/modtrd.c [new file with mode: 0644]

index f87428ba0cb479c9ea13eca0a5aa64edd77071ef..61a6c0f4cd49d8b1d01dfead002817176cffa3b5 100644 (file)
@@ -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?
index ec894edb07a1809b23d8437ca8b6573e3ecc9b86..2d0a12e089bbb6ee076c939cb1e5a59969b84547 100644 (file)
@@ -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
index d73bd7d75a1058f97bc44ab85eb7d65b3e474303..68d16afbf3c3f0fe5539806659711eedae70b276 100644 (file)
@@ -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)
index 53aed58447ec15bc4c505c315621866abf2973f2..0894b3f88d8be0cca2875cae9f3379ec53bc9d55 100644 (file)
@@ -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_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 *pDCTstat)
+                               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)
 {
index c89a32528efef9ec6c30c5a867ec04173e31f0a5..54fdedf08cf33418011028388371a1b7bd30302e 100644 (file)
@@ -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))) {
index bf9222339d6103350df44d2badf32dcf69764324..79875faa714f204a1fb920302ca5e057ded8a22d 100644 (file)
@@ -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);
index cfd4adfa6ffe69d5d6475136ac2361768a30f1e7..118d8eb80b2aa3360481fc8cefaa54aec297672b 100644 (file)
@@ -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 */);
+       }
+}
index a40dda42c74cf7317568945e595bd723221a9a7d..d758dada3987cb1baa7f1d015b9e54b62df4af3f 100644 (file)
@@ -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);
+       }
+}
index 4f5a360f946e772719229476e74d956d300c2431..b7bcd15c457a28beb76e418f5d5186513decd2ec 100644 (file)
@@ -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);
 
index 18ef4770e2574a8efd6fc9911be68c5a6b822329..3318896fe48a2e450a70ded1aff8fd92a0cb73c1 100644 (file)
@@ -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] */
index 76ddb88d53bb2a6b8a6811ab931ed3397d501831..e0cda14b8a4a84ccf2e1277adcdca50d53898a5b 100644 (file)
@@ -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
index d4b531f3afc124b11ef2f9e66bd62c9150327b4c..57d56814c1acbc702f56ac2de61070bab35ce9ca 100644 (file)
@@ -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<<onDimmMirror));
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c b/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c
new file mode 100644 (file)
index 0000000..58ddf59
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+static u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat,
+                               struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
+{
+       u8 Speed = pDCTstat->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;
+}