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);
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,
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);
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 };
MCTMemClr_D(pMCTstat,pDCTstatA);
}
- mct_FinalMCT_D(pMCTstat, (pDCTstatA + 0) ); /* Node 0 */
- printk(BIOS_DEBUG, "All Done\n");
+ mct_FinalMCT_D(pMCTstat, pDCTstatA);
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D Done: Global Status: %x\n", pMCTstat->GStatus);
return;
fatalexit:
{
/* 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;
val = 0xFF000000;
Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val);
} else {
- /* mct_EnDllShutdownSR */
+ mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct);
}
}
* 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.
*/
}
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;
}
Set_NB32(dev, 0x88 + reg_off, DramTimingLo); /*DCT Timing Low*/
if (pDCTstat->Speed > 4) {
- DramTimingLo |= 1 << DisAutoRefresh;
+ DramTimingHi |= 1 << DisAutoRefresh;
}
DramTimingHi |= 0x000018FF;
Set_NB32(dev, 0x8c + reg_off, DramTimingHi); /*DCT Timing Hi*/
* Specific information. Return the least of these three in
* DCTStatStruc.PresetmaxFreq.
*/
+ /* TODO: Set the proper max frequency in wrappers/mcti_d.c. */
u16 proposedFreq;
u16 word;
/* Get CPU Si Revision defined limit (NPT) */
- proposedFreq = 533; /* Rev F0 programmable max memclock is */
+ proposedFreq = 800; /* Rev F0 programmable max memclock is */
/*Get User defined limit if "limit" mode */
if ( mctGet_NVbits(NV_MCTUSRTMGMODE) == 1) {
u16 tCKproposed16x;
u8 CLactual, CLdesired, CLT_Fail;
- u8 smbaddr, byte, bytex;
+ u8 smbaddr, byte = 0, bytex = 0;
CASLatLow = 0xFF;
CASLatHigh = 0xFF;
if (pDCTstat->GangedMode == 1) {
mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1);
+ mct_BeforePlatformSpec(pMCTstat, pDCTstat, 1);
}
if ( pDCTstat->_2Tmode == 2) {
Set_NB32(dev, reg, val);
}
+ mct_BeforePlatformSpec(pMCTstat, pDCTstat, dct);
mct_PlatformSpec(pMCTstat, pDCTstat, dct);
if (pDCTstat->DIMMAutoSpeed == 4)
InitPhyCompensation(pMCTstat, pDCTstat, dct);
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;
else
val = 6;
DramControl &= ~0xFF;
- DramControl |= val; /* RdPrtInit = 6 for Cx CPU */
+ DramControl |= val; /* RdPtrInit = 6 for Cx CPU */
if (mctGet_NVbits(NV_CLKHZAltVidC3))
DramControl |= 1<<16; /* check */
}
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))
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)); */
RegDIMMPresent = 0;
pDCTstat->DimmQRPresent = 0;
- for (i = 0; i< MAX_DIMMS_SUPPORTED; i++) {
+ for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) {
if (i >= MaxDimms)
break;
pDCTstat->MirrPresU_NumRegR |= 1 << i;
}
/* Get byte62: Reference Raw Card information. We dont need it now. */
- /* byte = mctRead_SPD(smbaddr, 62); */
+ /* byte = mctRead_SPD(smbaddr, SPD_RefRawCard); */
+ /* Get Byte65/66 for register manufacture ID code */
+ if ((0x97 == mctRead_SPD(smbaddr, SPD_RegManufactureID_H)) &&
+ (0x80 == mctRead_SPD(smbaddr, SPD_RegManufactureID_L))) {
+ if (0x16 == mctRead_SPD(smbaddr, SPD_RegManRevID))
+ pDCTstat->RegMan2Present |= 1 << i;
+ else
+ pDCTstat->RegMan1Present |= 1 << i;
+ }
/* Get Control word values for RC3. We dont need it. */
byte = mctRead_SPD(smbaddr, 70);
pDCTstat->CtrlWrd3 |= (byte >> 4) << (i << 2); /* C3 = SPD byte 70 [7:4] */
} else {
/* Configure DCT1 if unganged and enabled*/
if (!pDCTstat->GangedMode) {
- if ( pDCTstat->DIMMValidDCT[1] > 0) {
+ if (pDCTstat->DIMMValidDCT[1] > 0) {
err_code = pDCTstat->ErrCode; /* save DCT0 errors */
pDCTstat->ErrCode = 0;
DCTInit_D(pMCTstat, pDCTstat, 1);
}
+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)
{
}
return pDCTstat->ErrCode;
-
}
static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat)
{
u8 ret;
- if ( dct == 0)
+ if (dct == 0)
ret = DIMMPresence_D(pMCTstat, pDCTstat);
else
ret = pDCTstat->ErrCode;
static void Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat,
u8 dct, u32 dev, u32 index_reg)
{
- u8 Smallest, Largest;
+ u8 Smallest = 0, Largest = 0;
u32 val;
u8 byte, bytex;
Largest = byte;
}
}
- index += 3;
+ index += 3;
} /* while ++i */
word = Smallest;
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)
{
- mct_ClrClToNB_D(pMCTstat, pDCTstat);
+ 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)
i = 0; /* use i for the dct setting required */
if (pDCTstat->MAdimms[0] < 4)
i = 1;
- if (((pDCTstat->Speed == 2) || (pDCTstat->Speed == 3)) && (pDCTstat->MAdimms[i] == 4))
+ if (((pDCTstat->Speed == 2) || (pDCTstat->Speed == 3)) && (pDCTstat->MAdimms[i] == 4)) {
dword &= 0xF18FFF18;
index_reg = 0x98; /* force dct = 0 */
+ }
}
Set_NB32_index_wait(dev, index_reg, 0x0a, dword);
}
static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
+ struct DCTStatStruc *pDCTstat, u8 dct)
{
u32 reg;
u32 val;
* 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);
}
}
+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)
{
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,
_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)
{
* 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 DDR3 training.
+ * Solution: At least, set WrDqs fine delay to be 0 for DDR3 training.
*/
for (Node = 0; Node < 8; Node++) {
pDCTstat = pDCTstatA + Node;
- if (pDCTstat->NodePresent)
+ if (pDCTstat->NodePresent) {
mct_BeforeDQSTrainSamp(pDCTstat); /* only Bx */
mct_ResetDLL_D(pMCTstat, pDCTstat, 0);
mct_ResetDLL_D(pMCTstat, pDCTstat, 1);
+ }
}
}