Fix ECC disable option for AMD Fam10 DDR2 and DDR3.
[coreboot.git] / src / northbridge / amd / amdmct / mct / mct_d.c
index 402b5d93a55bcff711fdb72d8ca47e1af46c1ea5..36b473a55fdd921c5aa23a27bdf809f0432fb270 100644 (file)
@@ -30,7 +30,7 @@
  * ordinarily in 64-bit mode.
  *
  * Trc precision does not use extra Jedec defined fractional component.
- * InsteadTrc (course) is rounded up to nearest 1 ns.
+ * Instead Trc (course) is rounded up to nearest 1 ns.
  *
  * Mini and Micro DIMM not supported. Only RDIMM, UDIMM, SO-DIMM defined types
  * supported.
@@ -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 };
@@ -183,7 +186,7 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
         * on setup options). It is the responsibility of PCI subsystem to
         * create an uncacheable IO region below 4GB and to adjust TOP_MEM
         * downward prior to any IO mapping or accesses. It is the same
-        * responsibility of the CPU sub-system prior toaccessing LAPIC.
+        * responsibility of the CPU sub-system prior to accessing LAPIC.
         *
         * Slot Number is an external convention, and is determined by OEM with
         * accompanying silk screening.  OEM may choose to use Slot number
@@ -297,7 +300,7 @@ restartinit:
        }
 
        mct_FinalMCT_D(pMCTstat, (pDCTstatA + 0) );     // Node 0
-       print_t("All Done\n");
+       print_tx("mctAutoInitMCT_D Done: Global Status: ", pMCTstat->GStatus);
        return;
 
 fatalexit:
@@ -633,7 +636,7 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat,
                devx = pDCTstat->dev_map;
 
                if (pDCTstat->NodePresent) {
-               printk(BIOS_DEBUG, " Copy dram map from Node 0 to Node %02x \n", Node);
+                       printk(BIOS_DEBUG, " Copy dram map from Node 0 to Node %02x \n", Node);
                        reg = 0x40;             /*Dram Base 0*/
                        do {
                                val = Get_NB32(dev, reg);
@@ -655,7 +658,7 @@ static void MCTMemClr_D(struct MCTStatStruc *pMCTstat,
 {
 
        /* Initiates a memory clear operation for all node. The mem clr
-        * is done in paralel. After the memclr is complete, all processors
+        * is done in parallel. After the memclr is complete, all processors
         * status are checked to ensure that memclr has completed.
         */
        u8 Node;
@@ -776,7 +779,7 @@ static u8 NodePresent_D(u8 Node)
                if (val  == dword)      /* current nodeID = requested nodeID ? */
                        ret = 1;
 finish:
-       ;
+               ;
        }
 
        return ret;
@@ -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);
        }
 }
 
@@ -856,7 +861,7 @@ static void StartupDCT_D(struct MCTStatStruc *pMCTstat,
         * HW memory clear process that the chip is capable of. The sooner
         * that dram init is set for all nodes, the faster the memory system
         * initialization can complete. Thus, the init loop is unrolled into
-        * two loops so as to start the processeses for non BSP nodes sooner.
+        * two loops so as to start the processes for non BSP nodes sooner.
         * This procedure will not wait for the process to finish.
         * Synchronization is handled elsewhere.
         */
@@ -878,7 +883,7 @@ static void StartupDCT_D(struct MCTStatStruc *pMCTstat,
                        reg = 0x78 + reg_off;
                        val = Get_NB32(dev, reg);
                        /* Setting this bit forces a 1T window with hard left
-                        * pass/fail edge and a probabalistic right pass/fail
+                        * pass/fail edge and a probabilistic right pass/fail
                         * edge.  LEFT edge is referenced for final
                         * receiver enable position.*/
                        val |= 1 << DqsRcvEnTrain;
@@ -1038,35 +1043,35 @@ static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat,
                        } else {
                                byte = mctRead_SPD(smbaddr, SPD_TRCRFC);
                                if (byte & 0xF0) {
-                                       val++;  /* round up in case fractional extention is non-zero.*/
+                                       val++;  /* round up in case fractional extension is non-zero.*/
                                }
-               }
-               if (Trc < val)
-                       Trc = val;
-
-               /* dev density=rank size/#devs per rank */
-               byte = mctRead_SPD(smbaddr, SPD_BANKSZ);
-
-               val = ((byte >> 5) | (byte << 3)) & 0xFF;
-               val <<= 2;
-
-               byte = mctRead_SPD(smbaddr, SPD_DEVWIDTH) & 0xFE;     /* dev density=2^(rows+columns+banks) */
-               if (byte == 4) {
-                       val >>= 4;
-               } else if (byte == 8) {
-                       val >>= 3;
-               } else if (byte == 16) {
-                       val >>= 2;
-               }
+                       }
+                       if (Trc < val)
+                               Trc = val;
 
-               byte = bsr(val);
+                       /* dev density=rank size/#devs per rank */
+                       byte = mctRead_SPD(smbaddr, SPD_BANKSZ);
 
-               if (Trfc[LDIMM] < byte)
-                       Trfc[LDIMM] = byte;
+                       val = ((byte >> 5) | (byte << 3)) & 0xFF;
+                       val <<= 2;
 
-               byte = mctRead_SPD(smbaddr, SPD_TRAS);
-               if (Tras < byte)
-                       Tras = byte;
+                       byte = mctRead_SPD(smbaddr, SPD_DEVWIDTH) & 0xFE;     /* dev density=2^(rows+columns+banks) */
+                       if (byte == 4) {
+                               val >>= 4;
+                       } else if (byte == 8) {
+                               val >>= 3;
+                       } else if (byte == 16) {
+                               val >>= 2;
+                       }
+
+                       byte = bsr(val);
+
+                       if (Trfc[LDIMM] < byte)
+                               Trfc[LDIMM] = byte;
+
+                       byte = mctRead_SPD(smbaddr, SPD_TRAS);
+                       if (Tras < byte)
+                               Tras = byte;
                }       /* Dimm Present */
        }
 
@@ -1129,7 +1134,7 @@ static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat,
        }
        pDCTstat->Trp = val;
 
-        /*Trrd*/
+       /*Trrd*/
        dword = Trrd * 10;
        pDCTstat->DIMMTrrd = dword;
        val = dword / Tk40;
@@ -1496,7 +1501,7 @@ static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat,
        DramConfigMisc = 0;
        DramConfigMisc2 = 0;
 
-       /* set bank addessing and Masks, plus CS pops */
+       /* set bank addressing and Masks, plus CS pops */
        SPDSetBanks_D(pMCTstat, pDCTstat, dct);
        if (pDCTstat->ErrCode == SC_StopError)
                goto AutoConfig_exit;
@@ -1582,14 +1587,14 @@ static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat,
        }
 
        if (!(Status & (1 << SB_Registered)))
-               DramConfigLo |= 1 << UnBuffDimm;        /* Unbufferd DIMMs */
+               DramConfigLo |= 1 << UnBuffDimm;        /* Unbuffered DIMMs */
 
        if (mctGet_NVbits(NV_ECC_CAP))
                if (Status & (1 << SB_ECCDIMMs))
                        if ( mctGet_NVbits(NV_ECC))
                                DramConfigLo |= 1 << DimmEcEn;
 
-
+       DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct);
 
        /* Build Dram Config Hi Register Value */
        dword = pDCTstat->Speed;
@@ -2183,8 +2188,8 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat,
                                                pDCTstat->DimmECCPresent |= 1 << i;
                                        }
                                        if (byte & JED_ADRCPAR) {
-                                       /* DIMM is ECC capable */
-                                       pDCTstat->DimmPARPresent |= 1 << i;
+                                               /* DIMM is ECC capable */
+                                               pDCTstat->DimmPARPresent |= 1 << i;
                                        }
                                        /* Check if x4 device */
                                        devwidth = mctRead_SPD(smbaddr, SPD_DEVWIDTH) & 0xFE;
@@ -2402,7 +2407,7 @@ static void mct_DramInit(struct MCTStatStruc *pMCTstat,
        // FIXME: for rev A: mct_BeforeDramInit_D(pDCTstat, dct);
 
        /* Disable auto refresh before Dram init when in ganged mode (Erratum 278) */
-       if (pDCTstat->LogicalCPUID & AMD_DR_LT_B2) {
+       if (pDCTstat->LogicalCPUID & (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_BA)) {
                if (pDCTstat->GangedMode) {
                        val = Get_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct));
                        val |= 1 << DisAutoRefresh;
@@ -2416,7 +2421,7 @@ static void mct_DramInit(struct MCTStatStruc *pMCTstat,
         * to ensure both DCTs are in sync (Erratum 278)
         */
 
-       if (pDCTstat->LogicalCPUID & AMD_DR_LT_B2) {
+       if (pDCTstat->LogicalCPUID & (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_BA)) {
                if (pDCTstat->GangedMode) {
                        do {
                                val = Get_NB32(pDCTstat->dev_dct, 0x90 + (0x100 * dct));
@@ -2455,8 +2460,8 @@ static u8 mct_setMode(struct MCTStatStruc *pMCTstat,
        if (byte != bytex) {
                pDCTstat->ErrStatus &= ~(1 << SB_DimmMismatchO);
        } else {
-       if ( mctGet_NVbits(NV_Unganged) )
-               pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO);
+               if ( mctGet_NVbits(NV_Unganged) )
+                       pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO);
 
                if (!(pDCTstat->ErrStatus & (1 << SB_DimmMismatchO))) {
                        pDCTstat->GangedMode = 1;
@@ -2872,7 +2877,7 @@ static void Get_Twrwr(struct MCTStatStruc *pMCTstat,
                dword = bsr(pDCTstat->DIMMValid);
                if (dword != val && dword != 0)  {
                        /*the largest WrDatGrossDlyByte of any DIMM minus the
-                       WrDatGrossDlyByte of any other DIMM is equal to CGDD */
+                         WrDatGrossDlyByte of any other DIMM is equal to CGDD */
                        val = Get_WrDatGross_Diff(pDCTstat, dct, dev, index_reg);
                }
                if (val == 0)
@@ -3128,7 +3133,7 @@ static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat,
                                        Largest = byte;
                        }
                }
-       index += 3;
+               index += 3;
        }       /* while ++i */
 
        word = Smallest;
@@ -3265,7 +3270,7 @@ static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat,
        dev = pDCTstat->dev_map;
 
        /* Copy dram map from F1x40/44,F1x48/4c,
-         to F1x120/124(Node0),F1x120/124(Node1),...*/
+          to F1x120/124(Node0),F1x120/124(Node1),...*/
        for (Node=0; Node < MAX_NODES_SUPPORTED; Node++) {
                pDCTstat = pDCTstatA + Node;
                devx = pDCTstat->dev_map;
@@ -3405,7 +3410,7 @@ static void SetODTTriState(struct MCTStatStruc *pMCTstat,
                if (pDCTstat->CSPresent & (1 << cs)) {
                        odt &= ~(1 << (cs / 2));
 
-                       /* if quad-rank capable platform clear adtitional pins */
+                       /* if quad-rank capable platform clear additional pins */
                        if (max_dimms != MAX_CS_SUPPORTED) {
                                if (pDCTstat->CSPresent & (1 << (cs + 1)))
                                        odt &= ~(4 << (cs / 2));
@@ -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)
@@ -3738,7 +3778,7 @@ void mct_SetDramConfigHi_D(struct DCTStatStruc *pDCTstat, u32 dct,
        Set_NB32_index_wait(dev, index_reg, index, val | (1 << DisAutoComp));
 
        //FIXME: check for Bx Cx CPU
-         // if Ax mct_SetDramConfigHi_Samp_D
+       // if Ax mct_SetDramConfigHi_Samp_D
 
        /* errata#177 */
        index = 0x4D014F00;     /* F2x[1, 0]9C_x[D0FFFFF:D000000] DRAM Phy Debug Registers */
@@ -3768,17 +3808,17 @@ static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat,
         * Silicon Status: Fixed In Rev B0
         *
         * Bug#15880: Determine validity of reset settings for DDR PHY timing.
-        * Solutiuon: At least, set WrDqs fine delay to be 0 for DDR2 training.
+        * Solution: At least, set WrDqs fine delay to be 0 for DDR2 training.
         */
 
        for (Node = 0; Node < 8; Node++) {
                pDCTstat = pDCTstatA + Node;
 
-               if (pDCTstat->NodePresent)
+               if (pDCTstat->NodePresent) {
                        mct_BeforeDQSTrain_Samp_D(pMCTstat, pDCTstat);
                        mct_ResetDLL_D(pMCTstat, pDCTstat, 0);
                        mct_ResetDLL_D(pMCTstat, pDCTstat, 1);
-
+               }
        }
 }