Multi-DIMMS on AMD ddr3 MCT channel B works.

Signed-off-by: Kerry She <Kerry.she@amd.com>
Acked-by: Stefan Reinauer <stepan@coresystems.de>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5748 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Kerry She 2010-08-30 07:31:31 +00:00 committed by Zheng Bao
parent 108d30ba86
commit 99cfa1e6bd
5 changed files with 37 additions and 13 deletions

View File

@ -332,7 +332,6 @@ static void TrainDQSRdWrPos_D(struct MCTStatStruc *pMCTstat,
if (pDCTstat->DIMMValidDCT[Channel] == 0) /* mct_BeforeTrainDQSRdWrPos_D */ if (pDCTstat->DIMMValidDCT[Channel] == 0) /* mct_BeforeTrainDQSRdWrPos_D */
continue; continue;
pDCTstat->DqsRdWrPos_Saved = 0; pDCTstat->DqsRdWrPos_Saved = 0;
for ( DQSWrDelay = 0; DQSWrDelay < dqsWrDelay_end; DQSWrDelay++) { for ( DQSWrDelay = 0; DQSWrDelay < dqsWrDelay_end; DQSWrDelay++) {
pDCTstat->DQSDelay = DQSWrDelay; pDCTstat->DQSDelay = DQSWrDelay;
@ -1174,12 +1173,12 @@ u32 mct_GetMCTSysAddr_D(struct MCTStatStruc *pMCTstat,
*valid = 0; *valid = 0;
if (!pDCTstat->GangedMode) { /* FIXME: not used. */ if (!pDCTstat->GangedMode) {
reg_off = 0x100 * Channel; reg_off = 0x100 * Channel;
} }
/* get the local base addr of the chipselect */ /* get the local base addr of the chipselect */
reg = 0x40 + (receiver << 2); reg = 0x40 + (receiver << 2) + reg_off;
val = Get_NB32(dev, reg); val = Get_NB32(dev, reg);
val &= ~0x0F; val &= ~0x0F;

View File

@ -22,6 +22,8 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
{ {
u8 Dimms, DimmNum, MaxDimm, Speed; u8 Dimms, DimmNum, MaxDimm, Speed;
u32 val; u32 val;
u32 dct = 0;
u32 reg_off = 0;
DimmNum = MrsChipSel >> 20; DimmNum = MrsChipSel >> 20;
@ -32,8 +34,14 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
MaxDimm = mctGet_NVbits(NV_MAX_DIMMS); MaxDimm = mctGet_NVbits(NV_MAX_DIMMS);
Speed = pDCTstat->DIMMAutoSpeed; Speed = pDCTstat->DIMMAutoSpeed;
/* if (dct == 0) */
Dimms = pDCTstat->MAdimms[0]; if (pDCTstat->CSPresent_DCT[0] > 0) {
dct = 0;
} else if (pDCTstat->CSPresent_DCT[1] > 0 ){
dct = 1;
}
reg_off = 0x100 * dct;
Dimms = pDCTstat->MAdimms[dct];
val = 0; val = 0;
if (CtrlWordNum == 0) if (CtrlWordNum == 0)
@ -87,14 +95,21 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
static void mct_SendCtrlWrd(struct MCTStatStruc *pMCTstat, static void mct_SendCtrlWrd(struct MCTStatStruc *pMCTstat,
struct DCTStatStruc *pDCTstat, u32 val) struct DCTStatStruc *pDCTstat, u32 val)
{ {
u32 reg_off = 0;
u32 dev = pDCTstat->dev_dct; u32 dev = pDCTstat->dev_dct;
val |= Get_NB32(dev, 0x7C) & ~0xFFFFFF; if (pDCTstat->CSPresent_DCT[0] > 0) {
reg_off = 0;
} else if (pDCTstat->CSPresent_DCT[1] > 0 ){
reg_off = 0x100;
}
val |= Get_NB32(dev, reg_off + 0x7C) & ~0xFFFFFF;
val |= 1 << SendControlWord; val |= 1 << SendControlWord;
Set_NB32(dev, 0x7C, val); Set_NB32(dev, reg_off + 0x7C, val);
do { do {
val = Get_NB32(dev, 0x7C); val = Get_NB32(dev, reg_off + 0x7C);
} while (val & (1 << SendControlWord)); } while (val & (1 << SendControlWord));
} }
@ -104,6 +119,7 @@ void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat,
u8 MrsChipSel; u8 MrsChipSel;
u32 dev = pDCTstat->dev_dct; u32 dev = pDCTstat->dev_dct;
u32 val, cw; u32 val, cw;
u32 reg_off = 0x100 * dct;
mct_Wait(1600); mct_Wait(1600);
@ -111,7 +127,7 @@ void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat,
for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel ++, MrsChipSel ++) { for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel ++, MrsChipSel ++) {
if (pDCTstat->CSPresent & (1 << MrsChipSel)) { if (pDCTstat->CSPresent & (1 << MrsChipSel)) {
val = Get_NB32(dev, 0xA8); val = Get_NB32(dev, reg_off + 0xA8);
val &= ~(0xF << 8); val &= ~(0xF << 8);
switch (MrsChipSel) { switch (MrsChipSel) {
@ -128,7 +144,7 @@ void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat,
case 7: case 7:
val |= (3 << 6) << 8; val |= (3 << 6) << 8;
} }
Set_NB32(dev, 0xA8, val); Set_NB32(dev, reg_off + 0xA8 , val);
for (cw=0; cw <=15; cw ++) { for (cw=0; cw <=15; cw ++) {
mct_Wait(1600); mct_Wait(1600);

View File

@ -86,7 +86,7 @@ void PrepareC_DCT(struct MCTStatStruc *pMCTstat,
for (dimm = 0; dimm < MAX_TOTAL_DIMMS; dimm++) { for (dimm = 0; dimm < MAX_TOTAL_DIMMS; dimm++) {
u8 DimmRanks; u8 DimmRanks;
if (DimmValid & (1 << dimm)) { if (DimmValid & (1 << (dimm << 1))) {
DimmRanks = 1; DimmRanks = 1;
if (pDCTstat->DimmDRPresent & (1 << (dimm+dct))) if (pDCTstat->DimmDRPresent & (1 << (dimm+dct)))
DimmRanks = 2; DimmRanks = 2;

View File

@ -51,9 +51,18 @@ COMMENT OUT ALL BUT 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
UPDATE AS NEEDED UPDATE AS NEEDED
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
#ifndef MAX_NODES_SUPPORTED
#define MAX_NODES_SUPPORTED 8 #define MAX_NODES_SUPPORTED 8
#endif
#ifndef MAX_DIMMS_SUPPORTED
#define MAX_DIMMS_SUPPORTED 8 #define MAX_DIMMS_SUPPORTED 8
#endif
#ifndef MAX_CS_SUPPORTED
#define MAX_CS_SUPPORTED 8 #define MAX_CS_SUPPORTED 8
#endif
#define MCT_TRNG_KEEPOUT_START 0x00000C00 #define MCT_TRNG_KEEPOUT_START 0x00000C00
#define MCT_TRNG_KEEPOUT_END 0x00000CFF #define MCT_TRNG_KEEPOUT_END 0x00000CFF

View File

@ -40,8 +40,8 @@ static u16 mctGet_NVbits(u8 index)
val = MAX_NODES_SUPPORTED; val = MAX_NODES_SUPPORTED;
break; break;
case NV_MAX_DIMMS: case NV_MAX_DIMMS:
//val = MAX_DIMMS_SUPPORTED; val = MAX_DIMMS_SUPPORTED;
val = 8; //val = 8;
break; break;
case NV_MAX_MEMCLK: case NV_MAX_MEMCLK:
/* Maximum platform supported memclk */ /* Maximum platform supported memclk */