Fix some settings of AMD MCT. It is based on BIOS test suite.

Signed-off-by: <zheng.bao@amd.com>

Index: src/northbridge/amd/amdmct/mct/mct_d.c
===================================================================
--- src/northbridge/amd/amdmct/mct/mct_d.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct/mct_d.c	(working copy)
@@ -154,8 +154,11 @@
 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 };
 static const u8 Table_T_k[]	= {0x00,0x50,0x3D,0x30,0x25, 0x18 };
@@ -822,6 +825,8 @@
 		  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,8 +1594,8 @@
 			if ( mctGet_NVbits(NV_ECC))
 				DramConfigLo |= 1 << DimmEcEn;
 
+	DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct);
 
-
 	/* Build Dram Config Hi Register Value */
 	dword = pDCTstat->Speed;
 	DramConfigHi |= dword - 1;	/* get MemClk encoding */
@@ -3630,7 +3635,42 @@
 	}
 }
 
+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: src/northbridge/amd/amdmct/amddefs.h
===================================================================
--- src/northbridge/amd/amdmct/amddefs.h	(revision 6244)
+++ src/northbridge/amd/amdmct/amddefs.h	(working copy)
@@ -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: src/northbridge/amd/amdfam10/raminit_amdmct.c
===================================================================
--- src/northbridge/amd/amdfam10/raminit_amdmct.c	(revision 6244)
+++ src/northbridge/amd/amdfam10/raminit_amdmct.c	(working copy)
@@ -65,6 +65,7 @@
 #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: src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c	(working copy)
@@ -190,7 +190,6 @@
 		SetTargetFreq(pMCTstat, pDCTstat);
 		PhyWLPass2(pMCTstat, pDCTstat, 0);
 		PhyWLPass2(pMCTstat, pDCTstat, 1);
-
 	}
 
 	SetEccWrDQS_D(pMCTstat, pDCTstat);
Index: src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c	(working copy)
@@ -552,6 +552,18 @@
 	}
 
 	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: src/northbridge/amd/amdmct/mct_ddr3/mctprob.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctprob.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctprob.c	(working copy)
@@ -35,3 +35,10 @@
 		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: src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctproc.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctproc.c	(working copy)
@@ -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 @@
 		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: src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctrci.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctrci.c	(working copy)
@@ -25,7 +25,7 @@
 	u32 dct = 0;
 	u32 reg_off = 0;
 
-	DimmNum = MrsChipSel >> 20;
+	DimmNum = (MrsChipSel >> 20) & 0xFE;
 
 	/* assume dct=0; */
 	/* if (dct == 1) */
@@ -39,6 +39,7 @@
 		dct = 0;
 	} else if (pDCTstat->CSPresent_DCT[1] > 0 ){
 		dct = 1;
+		DimmNum ++;
 	}
 	reg_off = 0x100 * dct;
 	Dimms = pDCTstat->MAdimms[dct];
@@ -49,27 +50,26 @@
 	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 @@
 	} 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 @@
 	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 @@
 
 			mct_Wait(1600);
 
+			/* Resend control word 2 */
 			val = mct_ControlRC(pMCTstat, pDCTstat, MrsChipSel << 20, 2);
 			mct_SendCtrlWrd(pMCTstat, pDCTstat, val);
 
Index: src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c	(working copy)
@@ -158,7 +158,7 @@
 		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: src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mct_d.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c	(working copy)
@@ -80,6 +80,8 @@
 				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_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 @@
 					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 @@
 					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 @@
 		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 @@
 		val = 0xFF000000;
 		Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val);
 	} else {
-		/* mct_EnDllShutdownSR */
+		mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct);
 	}
 }
 
@@ -902,7 +910,14 @@
 	}
 
 	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 @@
 
 	if (pDCTstat->GangedMode == 1) {
 		mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1);
+		mct_BeforePlatformSpec(pMCTstat, pDCTstat, 1);
 	}
 
 	if ( pDCTstat->_2Tmode == 2) {
@@ -1495,6 +1511,7 @@
 		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 @@
 	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 @@
 
 }
 
+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 @@
 	}
 
 	return pDCTstat->ErrCode;
-
 }
 
 static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat)
@@ -2870,11 +2905,97 @@
 	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 mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat,
-					struct DCTStatStruc *pDCTstat)
+					struct DCTStatStruc *pDCTstat, u8 dct)
 {
 	u32 reg;
 	u32 val;
@@ -3150,10 +3271,10 @@
 	 * 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_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 @@
 	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 @@
 	_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: src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctwl.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctwl.c	(working copy)
@@ -351,7 +351,7 @@
 {
 	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));
Index: src/northbridge/amd/amdmct/mct_ddr3/modtrd.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/modtrd.c	(revision 0)
+++ src/northbridge/amd/amdmct/mct_ddr3/modtrd.c	(revision 0)
@@ -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;
+}
Index: src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
===================================================================
--- src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c	(revision 6244)
+++ src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c	(working copy)
@@ -1012,7 +1012,7 @@
 
 	/* 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
