diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Proc/Recovery/Mem/NB/mrndct.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f14/Proc/Recovery/Mem/NB/mrndct.c | 226 |
1 files changed, 126 insertions, 100 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Proc/Recovery/Mem/NB/mrndct.c b/src/vendorcode/amd/agesa/f14/Proc/Recovery/Mem/NB/mrndct.c index 15ccaf3e8a..2769e1cc01 100644 --- a/src/vendorcode/amd/agesa/f14/Proc/Recovery/Mem/NB/mrndct.c +++ b/src/vendorcode/amd/agesa/f14/Proc/Recovery/Mem/NB/mrndct.c @@ -9,7 +9,7 @@ * @xrefitem bom "File Content Label" "Release Content" * @e project: AGESA * @e sub-project: (Proc/Recovery/Mem/NB) - * @e \$Revision: 38303 $ @e \$Date: 2010-09-22 00:22:47 +0800 (Wed, 22 Sep 2010) $ + * @e \$Revision: 48803 $ @e \$Date: 2011-03-10 20:18:28 -0700 (Thu, 10 Mar 2011) $ * **/ /* @@ -126,12 +126,6 @@ MemRecNTrainPhyFenceNb ( IN OUT MEM_NB_BLOCK *NBPtr ); -VOID -STATIC -MemRecNInitPhyCompClientNb ( - IN OUT MEM_NB_BLOCK *NBPtr - ); - /*---------------------------------------------------------------------------- * EXPORTED FUNCTIONS * @@ -338,6 +332,8 @@ MemRecNStartupDCTClientNb ( IN OUT MEM_NB_BLOCK *NBPtr ) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", NBPtr->Dct); + // Program D18F2x[1,0]9C_x0000_000B = 80000000h. #109999. MemRecNSetBitFieldNb (NBPtr, BFDramPhyStatusReg, 0x80000000); @@ -354,18 +350,15 @@ MemRecNStartupDCTClientNb ( MemRecNSetBitFieldNb (NBPtr, BFMemClkFreqVal, 1); MemRecNSetBitFieldNb (NBPtr, BFPllLockTime, 0x000F); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClkAlign=0\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\tEnDramInit = 1 for DCT%d\n", NBPtr->Dct); MemRecNSetBitFieldNb (NBPtr, BFDbeGskMemClkAlignMode, 0); MemRecNSetBitFieldNb (NBPtr, BFEnDramInit, 1); - // Phy fence programming - MemRecNPhyFenceTrainingNb (NBPtr); - - // Phy Compensation Initialization - MemRecNInitPhyCompClientNb (NBPtr); - // Run DramInit sequence AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader)); NBPtr->TechPtr->DramInit (NBPtr->TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq: %d MHz\n", DDR800_FREQUENCY); } /* -----------------------------------------------------------------------------*/ @@ -640,15 +633,6 @@ MemRecNTotalSyncComponentsClientNb ( AGESA_TESTPOINT (TpProcMemRcvrCalcLatency , &(NBPtr->MemPtr->StdHeader)); - // Before calculating MaxRdLatecny, program a number of registers. - MemRecNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 1); - MemRecNSetBitFieldNb (NBPtr, BFEnterSelfRef, 1); - while (MemRecNGetBitFieldNb (NBPtr, BFEnterSelfRef) != 0) {} - MemRecNSetBitFieldNb (NBPtr, BFDbeGskMemClkAlignMode, 2); - MemRecNSetBitFieldNb (NBPtr, BFExitSelfRef, 1); - while (MemRecNGetBitFieldNb (NBPtr, BFExitSelfRef) != 0) {} - MemRecNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 0); - // P = P + ((16 + RdPtrInitMin - D18F2x[1,0]78[RdPtrInit]) MOD 16) where RdPtrInitMin = RdPtrInit P = 0; @@ -862,8 +846,6 @@ MemRecNTrainPhyFenceNb ( } /* -----------------------------------------------------------------------------*/ -CONST UINT16 RecPllDivTab[10] = {1, 2, 4, 8, 16, 128, 256, 1, 3, 6}; - /** * * This function calculates and programs NB P-state dependent registers @@ -883,23 +865,38 @@ MemRecNProgNbPstateDependentRegClientNb ( UINT16 MemClkDid; UINT8 PllMult; UINT8 NclkDiv; + UINT8 RdPtrInit; UINT32 NclkPeriod; UINT32 MemClkPeriod; INT32 PartialSum2x; INT32 PartialSumSlotI2x; + INT32 RdPtrInitRmdr2x; NclkFid = (UINT8) (MemRecNGetBitFieldNb (NBPtr, BFMainPllOpFreqId) + 0x10); - MemClkDid = RecPllDivTab[MemRecNGetBitFieldNb (NBPtr, BFPllDiv)]; - PllMult = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFPllMult); + MemClkDid = 2; //BKDG recommended value for DDR800 + PllMult = 16; //BKDG recommended value for DDR800 NclkDiv = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFNbPs0NclkDiv); NclkPeriod = (2500 * NclkDiv) / NclkFid; MemClkPeriod = 1000000 / DDR800_FREQUENCY; + NBPtr->NBClkFreq = ((UINT32) NclkFid * 400) / NclkDiv; + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\tNB P%d Freq: %dMHz\n", 0, NBPtr->NBClkFreq); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClk Freq: %dMHz\n", DDR800_FREQUENCY); + + // D18F2x[1,0]78[RdPtrInit] = IF (D18F2x[1,0]94[MemClkFreq] >= 667 MHz) THEN 7 ELSE 8 ENDIF (Llano) + // THEN 2 ELSE 3 ENDIF (Ontario) + RdPtrInit = NBPtr->FreqChangeParam->RdPtrInitLower667; + MemRecNSetBitFieldNb (NBPtr, BFRdPtrInit, RdPtrInit); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tRdPtr: %d\n", RdPtrInit); // Program D18F2x[1,0]F4_x30[DbeGskFifoNumerator] and D18F2x[1,0]F4_x31[DbeGskFifoDenominator]. MemRecNSetBitFieldNb (NBPtr, BFDbeGskFifoNumerator, NclkFid * MemClkDid * 16); MemRecNSetBitFieldNb (NBPtr, BFDbeGskFifoDenominator, PllMult * NclkDiv); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDbeGskFifoNumerator: %d\n", NclkFid * MemClkDid * 16); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDbeGskFifoDenominator: %d\n", PllMult * NclkDiv); + // Program D18F2x[1,0]F4_x32[DataTxFifoSchedDlyNegSlot1, DataTxFifoSchedDlySlot1, // DataTxFifoSchedDlyNegSlot0, DataTxFifoSchedDlySlot0]. // PartialSum = ((7 * NclkPeriod) + (1.5 * MemClkPeriod) + 520ps)*MemClkFrequency - tCWL - @@ -909,6 +906,9 @@ MemRecNProgNbPstateDependentRegClientNb ( PartialSum2x = NBPtr->FreqChangeParam->NclkPeriodMul2x * NclkPeriod; PartialSum2x += NBPtr->FreqChangeParam->MemClkPeriodMul2x * MemClkPeriod; PartialSum2x += 520 * 2; + RdPtrInitRmdr2x = ((NBPtr->FreqChangeParam->SyncTimeMul4x * MemClkPeriod) / 2) - 2 * (NBPtr->FreqChangeParam->TDataPropLower800 + 520); + RdPtrInitRmdr2x %= MemClkPeriod; + PartialSum2x -= RdPtrInitRmdr2x; PartialSum2x = (PartialSum2x + MemClkPeriod - 1) / MemClkPeriod; // round-up here PartialSum2x -= 2 * 5; //Tcwl + 5 if ((MemRecNGetBitFieldNb (NBPtr, BFAddrTmgControl) & 0x0202020) == 0) { @@ -916,8 +916,6 @@ MemRecNProgNbPstateDependentRegClientNb ( } else { PartialSum2x -= 2; } - // ((16 + RdPtrInitMin - D18F2x78[RdPtrInit]) MOD 16)/2 where RdPtrInitMin = RdPtrInit - PartialSum2x -= 0; PartialSum2x -= 2; // If PartialSumSlotN is positive: @@ -928,14 +926,18 @@ MemRecNProgNbPstateDependentRegClientNb ( // DataTxFifoSchedDlyNegSlotN=1. for (i = 0; i < 2; i++) { PartialSumSlotI2x = PartialSum2x; + if (i == 0) { PartialSumSlotI2x += 2; + } if (PartialSumSlotI2x > 0) { MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlyNegSlot0 + i, 0); MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlySlot0 + i, (PartialSumSlotI2x + 1) / 2); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDataTxFifoSchedDlySlot%d: %d\n", i, (PartialSumSlotI2x + 1) / 2); } else { MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlyNegSlot0 + i, 1); PartialSumSlotI2x = ((-PartialSumSlotI2x) * MemClkPeriod) / (2 * NclkPeriod); MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlySlot0 + i, PartialSumSlotI2x); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDataTxFifoSchedDlySlot%d: -%d\n", i, PartialSumSlotI2x); } } // Program ProcOdtAdv @@ -1416,87 +1418,111 @@ MemRecNGetPsRankType ( return DIMMRankType; } -/* -----------------------------------------------------------------------------*/ -/** - * - * - * This function initializes the DDR phy compensation logic - * - * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK - * - */ - -VOID -STATIC -MemRecNInitPhyCompClientNb ( - IN OUT MEM_NB_BLOCK *NBPtr +UINT32 +MemRecNcmnGetSetTrainDlyClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field ) { - // Slew rate table array [x] - // array[0]: slew rate for VDDIO 1.5V - // array[1]: slew rate for VDDIO 1.35V - CONST STATIC UINT16 RecTxPrePNDataDqs[2][4] = { - //{TxPreP, TxPreN}[VDDIO][Drive Strength] - {0x924, 0x924, 0x924, 0x924}, - {0xFF6, 0xB6D, 0xB6D, 0x924} - }; + UINT16 Index; + UINT16 Offset; + UINT32 Value; + UINT32 Address; + UINT8 Dimm; + UINT8 Byte; - CONST STATIC UINT16 RecTxPrePNCmdAddr[2][4] = { - //{TxPreP, TxPreN}[VDDIO][Drive Strength] - {0x492, 0x492, 0x492, 0x492}, - {0x492, 0x492, 0x492, 0x492} - }; - CONST STATIC UINT16 RecTxPrePNClock[2][4] = { - //{TxPreP, TxPreN}[VDDIO][Drive Strength] - {0x924, 0x924, 0x924, 0x924}, - {0xDAD, 0xDAD, 0x924, 0x924} - }; + Dimm = DRBN_DIMM (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); - // - // Tables to describe the relationship between drive strength bit fields, PreDriver Calibration bit fields and also - // the extra value that needs to be written to specific PreDriver bit fields - // - CONST REC_PHY_COMP_INIT_CLIENTNB RecPhyCompInitBitField[] = { - // 3. Program TxPreP/TxPreN for Data and DQS according toTable 14 if VDDIO is 1.5V or Table 15 if 1.35V. - // A. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0[A,6]={0000b, TxPreP, TxPreN}. - // B. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]02={1000b, TxPreP, TxPreN}. - {BFDqsDrvStren, BFDataByteTxPreDriverCal2Pad1, BFDataByteTxPreDriverCal2Pad1, 0, RecTxPrePNDataDqs}, - {BFDataDrvStren, BFDataByteTxPreDriverCal2Pad2, BFDataByteTxPreDriverCal2Pad2, 0, RecTxPrePNDataDqs}, - {BFDataDrvStren, BFDataByteTxPreDriverCal, BFDataByteTxPreDriverCal, 8, RecTxPrePNDataDqs}, - // 4. Program TxPreP/TxPreN for Cmd/Addr according toTable 16 if VDDIO is 1.5V or Table 17 if 1.35V. - // A. Program D18F2x[1,0]9C_x0D0F_[C,8][1:0][12,0E,0A,06]={0000b, TxPreP, TxPreN}. - // B. Program D18F2x[1,0]9C_x0D0F_[C,8][1:0]02={1000b, TxPreP, TxPreN}. - {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCal2Pad1, BFCmdAddr0TxPreDriverCal2Pad2, 0, RecTxPrePNCmdAddr}, - {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCal2Pad1, BFAddrTxPreDriverCal2Pad4, 0, RecTxPrePNCmdAddr}, - {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCalPad0, BFCmdAddr0TxPreDriverCalPad0, 8, RecTxPrePNCmdAddr}, - {BFCkeDrvStren, BFAddrTxPreDriverCalPad0, BFAddrTxPreDriverCalPad0, 8, RecTxPrePNCmdAddr}, - {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCalPad0, BFCmdAddr1TxPreDriverCalPad0, 8, RecTxPrePNCmdAddr}, - // 5. Program TxPreP/TxPreN for Clock according toTable 18 if VDDIO is 1.5V or Table 19 if 1.35V. - // A. Program D18F2x[1,0]9C_x0D0F_2[1:0]02={1000b, TxPreP, TxPreN}. - {BFClkDrvStren, BFClock0TxPreDriverCalPad0, BFClock1TxPreDriverCalPad0, 8, RecTxPrePNClock} - }; + ASSERT (Dimm < 2); + ASSERT (Byte <= ECC_DLY); - BIT_FIELD_NAME CurrentBitField; - CONST UINT16 *TxPrePNArray; - UINT8 Voltage; - UINT8 CurDct; - UINT8 i; - UINT8 j; + if ((Byte > 7)) { + // LN and ON do not support ECC delay, so: + if (IsSet) { + // On write, ignore + return 0; + } else { + // On read, redirect to byte 0 to correct fence averaging + Byte = 0; + } + } + + switch (TrnDly) { + case AccessRcvEnDly: + Index = 0x10; + break; + case AccessWrDqsDly: + Index = 0x30; + break; + case AccessWrDatDly: + Index = 0x01; + break; + case AccessRdDqsDly: + Index = 0x05; + break; + case AccessPhRecDly: + Index = 0x50; + break; + default: + Index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + Index += (Dimm * 3); + if (Byte & 0x04) { + // if byte 4,5,6,7 + Index += 0x10; + } + if (Byte & 0x02) { + // if byte 2,3,6,7 + Index++; + } + Offset = 16 * (Byte % 2); + break; + + case AccessRdDqsDly: + case AccessWrDatDly: + Index += (Dimm * 0x100); + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + Index += (Byte / 4); + Offset = 8 * (Byte % 4); + break; + default: + Offset = 0; + IDS_ERROR_TRAP; + } - CurDct = NBPtr->Dct; - NBPtr->SwitchDCT (NBPtr, 0); - // 1. Program D18F2x[1,0]9C_x0D0F_E003[DisAutoComp, DisalbePredriverCal]={1b, 1b} - MemRecNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 0x6000); + Address = Index; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); - NBPtr->SwitchDCT (NBPtr, CurDct); + if (IsSet) { + if (TrnDly == AccessPhRecDly) { + Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03]; + } - Voltage = (UINT8) NBPtr->RefPtr->DDR3Voltage; + Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) ((TrnDly == AccessRcvEnDly) ? 0x1FF : 0xFF) << Offset))); + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); - for (j = 0; j < GET_SIZE_OF (RecPhyCompInitBitField); j ++) { - i = (UINT8) MemRecNGetBitFieldNb (NBPtr, RecPhyCompInitBitField[j].IndexBitField); - TxPrePNArray = RecPhyCompInitBitField[j].TxPrePN[Voltage]; - for (CurrentBitField = RecPhyCompInitBitField[j].StartTargetBitField; CurrentBitField <= RecPhyCompInitBitField[j].EndTargetBitField; CurrentBitField ++) { - MemRecNSetBitFieldNb (NBPtr, CurrentBitField, ((RecPhyCompInitBitField[j].ExtraValue << 12) | TxPrePNArray[i])); + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value; } + // Gross WrDatDly and WrDqsDly cannot be larger than 4 + ASSERT (((TrnDly == AccessWrDatDly) || (TrnDly == AccessWrDqsDly)) ? (NBPtr->IsSupported[WLNegativeDelay] || (Field < 0xA0)) : TRUE); + } else { + Value = (Value >> Offset) & (UINT32) ((TrnDly == AccessRcvEnDly) ? 0x1FF : 0xFF); } + + return Value; } |