コード例 #1
0
BOOLEAN
MemNWritePmuSramMsgBlockKV (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT16 i;
  UINT16 *ImagePtr;
  LOCATE_HEAP_PTR LocHeap;

  LocHeap.BufferHandle = AMD_MEM_PMU_SRAM_MSG_BLOCK_HANDLE;

  if (HeapLocateBuffer (&LocHeap, &(NBPtr->MemPtr->StdHeader)) != AGESA_SUCCESS) {
    return FALSE; // Could not locate heap for PMU SRAM Message BLock.
  }

  ImagePtr = (UINT16 *) LocHeap.BufferPtr;

  MemNSetBitFieldNb (NBPtr, BFPmuReset, 0);

  // Write the word to D18F2x[B,0]9C_x0005_[27FF:0800]_dct[3:0] (using the broadcast port for all phys at
  // D18F2xB98_dct[MaxDctMstr:0], and using the autoincrement feature).
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tStart writing PMU SRAM Message Block...\n");

  MemNSetBitFieldNb (NBPtr, RegDctAddlOffset, PMU_FIRMWARE_SRAM_START | DCT_ACCESS_WRITE | DCT_OFFSET_AUTO_INC_EN);

  for (i = 0; i < sizeof (PMU_SRAM_MSG_BLOCK_KV) / sizeof (ImagePtr[0]); i++) {
    MemNSetBitFieldNb (NBPtr, RegDctAddlData, ImagePtr[i]);
    IDS_HDT_CONSOLE (MEM_SETREG, "~F2_9C_%x = %04x\n", PMU_FIRMWARE_SRAM_START + i, ImagePtr[i]);
  }

  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tEnd writing PMU SRAM Message Block!\n");
  MemNSetBitFieldNb (NBPtr, RegDctAddlOffset, 0);

  return TRUE;
}
コード例 #2
0
ファイル: mnphyor.c プロジェクト: B-Rich/coreboot
VOID
MemNBeforeDQSTrainingOr (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8   Dct;
  UINT32  PackageType;

  for (Dct = 0; Dct < MAX_DCTS_PER_NODE_OR; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      //
      // 2.10.6.8.2 - BIOS should program D18F2x210_dct[1:0]_nbp[3:0][MaxRdLatency] to 55h.
      //
      MemNSetBitFieldNb (NBPtr, BFMaxLatency, 0x55);
    }
    MemNSetBitFieldNb (NBPtr, BFTraceModeEn, 0);
  }

  // DisDatMsk: Reset: 0. BIOS: IF (G34r1 || C32r1) THEN 1 ELSE 0 ENDIF.
  PackageType = LibAmdGetPackageType (&(NBPtr->MemPtr->StdHeader));
  if (PackageType != PACKAGE_TYPE_AM3r2) {
    MemNSetBitFieldNb (NBPtr, BFDisDatMsk, 1);
  }
}
コード例 #3
0
ファイル: mnotdr.c プロジェクト: Godkey/coreboot
VOID
STATIC
MemNSetOtherTimingDR (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MemNSetBitFieldNb (NBPtr, BFTrdrd, MemNGetTrdrdNb (NBPtr));
  MemNSetBitFieldNb (NBPtr, BFTwrwr, MemNGetTwrwrNb (NBPtr));
  MemNSetBitFieldNb (NBPtr, BFTwrrd, MemNGetTwrrdNb (NBPtr));
  MemNSetBitFieldNb (NBPtr, BFTrwtTO, MemNGetTrwtTONb (NBPtr));
  MemNSetBitFieldNb (NBPtr, BFTrwtWB, MemNGetTrwtWBNb (NBPtr));
}
コード例 #4
0
ファイル: mnmctdr.c プロジェクト: AdriDlu/coreboot
BOOLEAN
MemNFinalizeMctDr (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MEM_DATA_STRUCT *MemPtr;
  S_UINT64 SMsr;

  MemPtr = NBPtr->MemPtr;

  MemNSetBitFieldNb (NBPtr, BFAdapPrefMissRatio, 1);
  MemNSetBitFieldNb (NBPtr, BFAdapPrefPosStep, 0);
  MemNSetBitFieldNb (NBPtr, BFAdapPrefNegStep, 0);
  MemNSetBitFieldNb (NBPtr, BFCohPrefPrbLmt, 1);
  // Recommended settings for F2x11C
  MemNSetBitFieldNb (NBPtr, BFMctWrLimit, 16);
  MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);
  MemNSetBitFieldNb (NBPtr, BFPrefIoDis, 0);
  MemNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1);

  if (NBPtr->Node == BSP_DIE) {
    if (!NBPtr->ClToNbFlag) {
      LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
      SMsr.lo &= ~((UINT32)1 << 15);                // ClLinesToNbDis
      LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
    }

    LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
    SMsr.hi &= ~((UINT32)1 << (48 - 32));               // WbEnhWsbDis
    LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
  }

  return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL);
}
コード例 #5
0
ファイル: mnmctc32.c プロジェクト: Godkey/coreboot
BOOLEAN
MemNFinalizeMctC32 (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MEM_DATA_STRUCT *MemPtr;
  S_UINT64 SMsr;
  UINT16 Speed;
  UINT32 ExtMctCfgLoRegVal;

  MemPtr = NBPtr->MemPtr;
  Speed = NBPtr->DCTPtr->Timings.Speed;
  MemNSetBitFieldNb (NBPtr, BFMctCfgHiReg, (!NBPtr->Ganged) ? 0x2CE00F60 : 0x2CE00F40);

  ExtMctCfgLoRegVal = MemNGetBitFieldNb (NBPtr, BFExtMctCfgLoReg);
  ExtMctCfgLoRegVal |= (NBPtr->Ganged) ? 0x0FC00001 : 0x0FC01001;

  ExtMctCfgLoRegVal &= 0x0FFFFFFF;
  if (Speed == DDR667_FREQUENCY) {
    ExtMctCfgLoRegVal |= 0x40000000;
  } else if (Speed == DDR800_FREQUENCY) {
    ExtMctCfgLoRegVal |= 0x50000000;
  } else if (Speed == DDR1066_FREQUENCY) {
    ExtMctCfgLoRegVal |= 0x60000000;
  } else if (Speed == DDR1333_FREQUENCY) {
    ExtMctCfgLoRegVal |= 0x80000000;
  } else {
    ExtMctCfgLoRegVal |= 0x90000000;
  }
  MemNSetBitFieldNb (NBPtr, BFExtMctCfgLoReg, ExtMctCfgLoRegVal);

  if (NBPtr->Node == BSP_DIE) {
    if (!NBPtr->ClToNbFlag) {
      LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
      SMsr.lo &= ~((UINT32)1 << 15);                // ClLinesToNbDis
      LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
    }

    LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
    SMsr.hi &= ~((UINT32)1 << (48 - 32));               // WbEnhWsbDis
    LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
  }

  return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL);
}
コード例 #6
0
ファイル: mnphyhy.c プロジェクト: Godkey/coreboot
VOID
MemNBeforeDQSTrainingHy (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 Dct;
  UINT8 ChipSel;
  UINT32 TestAddrRJ16;
  UINT32 RealAddr;

  MemTBeginTraining (NBPtr->TechPtr);

  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) {
        if (MemNGetMCTSysAddrNb (NBPtr, ChipSel, &TestAddrRJ16)) {

          RealAddr = MemUSetUpperFSbase (TestAddrRJ16, NBPtr->MemPtr);

          MemUDummyCLRead (RealAddr);

          MemNSetBitFieldNb (NBPtr, BFErr350, 0x8000);
          MemUWait10ns (60, NBPtr->MemPtr);   // Wait 300ns
          MemNSetBitFieldNb (NBPtr, BFErr350, 0x0000);
          MemUWait10ns (400, NBPtr->MemPtr);  // Wait 2us
          MemUProcIOClFlush (TestAddrRJ16, 1, NBPtr->MemPtr);
          break;
        }
      }
    }
    if (NBPtr->IsSupported[CheckEccDLLPwrDnConfig]) {
      if (!NBPtr->MCTPtr->Status[SbEccDimms]) {
        MemNSetBitFieldNb (NBPtr, BFEccDLLPwrDnConf, 0x0010);
      }
      if (NBPtr->DCTPtr->Timings.Dimmx4Present == 0) {
        MemNSetBitFieldNb (NBPtr, BFEccDLLConf, 0x0080);
      }
    }
  }

  MemTEndTraining (NBPtr->TechPtr);

  MemNSetBitFieldNb (NBPtr, BFDisDatMsk, 1);
}
コード例 #7
0
ファイル: mnphyon.c プロジェクト: AdriDlu/coreboot
BOOLEAN
MemNResetRxFifoPtrON (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN OUT   VOID *OptParam
  )
{
  if (NBPtr->TechPtr->Direction == DQS_READ_DIR) {
    MemNSetBitFieldNb (NBPtr, BFRxPtrInitReq, 1);
    MemNPollBitFieldNb (NBPtr, BFRxPtrInitReq, 0, PCI_ACCESS_TIMEOUT, FALSE);
  }
  return TRUE;
}
コード例 #8
0
ファイル: mnflow.c プロジェクト: Godkey/coreboot
VOID
STATIC
MemNCleanupDctRegsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  BIT_FIELD_NAME BitField;

  for (BitField = BFCSBaseAddr0Reg; BitField <= BFCSBaseAddr7Reg; BitField++) {
    MemNSetBitFieldNb (NBPtr, BitField, 0);
  }
}
コード例 #9
0
ファイル: mnotdr.c プロジェクト: Godkey/coreboot
VOID
STATIC
MemNPowerDownCtlDR (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MEM_PARAMETER_STRUCT *RefPtr;
  UINT8 PowerDownMode;

  RefPtr = NBPtr->RefPtr;

  // we can't enable powerdown mode when doing WL
  if (RefPtr->EnablePowerDown) {
    MemNSetBitFieldNb (NBPtr, BFPowerDownEn, 1);
    PowerDownMode = (UINT8) UserOptions.CfgPowerDownMode;
    IDS_OPTION_HOOK (IDS_POWERDOWN_MODE, &PowerDownMode, &(NBPtr->MemPtr->StdHeader));
    if (PowerDownMode) {
      MemNSetBitFieldNb (NBPtr, BFPowerDownMode, 1);
    }
  }
}
コード例 #10
0
ファイル: mmConditionalPso.c プロジェクト: Godkey/coreboot
/**
 *      Perform Slew Rate Platform Override
 *
 *      @param[in] NBPtr - Pointer to Current NBBlock
 *      @param[in] Buffer - Pointer to the Action Command Data (w/o Type and Len)
 *
 *     @return          BOOLEAN -             TRUE : Action was performed
 *                                            FALSE: Action was not performed
 *
 * ----------------------------------------------------------------------------
 */
BOOLEAN
STATIC
MemPSODoActionSlewRate (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 *Buffer
  )
{
  BOOLEAN Result;
  CH_DEF_STRUCT *ChannelPtr;
  UINT32 Speed;
  UINT16 DimmConfig;

  Result = FALSE;
  ChannelPtr = NBPtr->ChannelPtr;
  Speed = ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66));
  DimmConfig = *(UINT16 *) &(Buffer[4]);

  if ((Speed & ((UINT32 *) Buffer)[0]) != 0) {
    if (MemCheckRankType (ChannelPtr, DimmConfig)) {
      MemNSetBitFieldNb (NBPtr, BFD3Cmp0NCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp0NCal );
      MemNSetBitFieldNb (NBPtr, BFD3Cmp0PCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp0PCal );
      MemNSetBitFieldNb (NBPtr, BFD3Cmp1NCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp1NCal );
      MemNSetBitFieldNb (NBPtr, BFD3Cmp1PCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp1PCal );
      MemNSetBitFieldNb (NBPtr, BFD3Cmp2NCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp2NCal );
      MemNSetBitFieldNb (NBPtr, BFD3Cmp2PCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp2PCal );
      Result = TRUE;
      IDS_HDT_CONSOLE (MEM_FLOW, "      Platform Override: Slew Rate:%08x\n", *(UINT32 *) &(Buffer[6]));
    }
  }
  return Result;
 }
コード例 #11
0
ファイル: mnphyon.c プロジェクト: AdriDlu/coreboot
VOID
MemNAfterDQSTrainingON (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  if (NBPtr->DCTPtr->Timings.Speed <= DDR1066_FREQUENCY) {
    MemNSetBitFieldNb (NBPtr, BFAddrCmdTriEn, 1);
  }
  MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0);
  MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2);
  MemNSetBitFieldNb (NBPtr, BFEnRxPadStandby, (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) ? 0x1000 : 0);
  MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);
  MemNSetBitFieldNb (NBPtr, BFDctWrLimit, 0x1C);
  MemNSetBitFieldNb (NBPtr, BFDramTrainPdbDis, 1);
  MemNSetBitFieldNb (NBPtr, BFEnCpuSerRdBehindNpIoWr, 0);
}
コード例 #12
0
ファイル: mnreg.c プロジェクト: AdriDlu/coreboot
/**
 *
 *  Set bitfields of all enabled DCTs on a die to a value. Ignore
 *  DCTs that are disabled.
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]   FieldName - Bit Field name
 *     @param[in]   Field - Value to be set
 *
 * ----------------------------------------------------------------------------
 */
VOID
MemNBrdcstSetNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       BIT_FIELD_NAME FieldName,
  IN       UINT32 Field
  )
{
  UINT8 Dct;
  UINT8 CurrentDCT;
  Dct = NBPtr->Dct;
  for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) {
    MemNSwitchDCTNb (NBPtr, CurrentDCT);
    if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) {
      MemNSetBitFieldNb (NBPtr, FieldName, Field);
    }
  }
  MemNSwitchDCTNb (NBPtr, Dct);
}
コード例 #13
0
ファイル: mnmctda.c プロジェクト: Godkey/coreboot
BOOLEAN
MemNFinalizeMctDA (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 Dct;
  MEM_DATA_STRUCT *MemPtr;
  S_UINT64 SMsr;

  MemPtr = NBPtr->MemPtr;
  MemNSetBitFieldNb (NBPtr, BFAdapPrefMissRatio, 1);
  MemNSetBitFieldNb (NBPtr, BFAdapPrefPosStep, 0);
  MemNSetBitFieldNb (NBPtr, BFAdapPrefNegStep, 0);
  MemNSetBitFieldNb (NBPtr, BFCohPrefPrbLmt, 1);
  // Recommended settings for F2x11C
  MemNSetBitFieldNb (NBPtr, BFMctWrLimit, 16);
  MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);
  MemNSetBitFieldNb (NBPtr, BFPrefIoDis, 0);
  MemNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1);
  // For power saving
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    NBPtr->SwitchDCT (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      if (NBPtr->ChannelPtr->Dimmx4Present == 0) {
        MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F13, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D0F0F13) | 0x80));
      }
      if (!NBPtr->MCTPtr->Status[SbEccDimms]) {
        MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0830, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D0F0830) | 0x10));
      }
      MemNSetBitFieldNb (NBPtr, BFPhy0x0D07812F, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D07812F) | 0x01));
    }
  }

  if (NBPtr->Node == BSP_DIE) {
    if (!NBPtr->ClToNbFlag) {
      LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
      SMsr.lo &= ~((UINT32)1 << 15);                // ClLinesToNbDis
      LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
    }

    LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
    SMsr.hi &= ~((UINT32)1 << (48 - 32));               // WbEnhWsbDis
    LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
  }

  return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL);
}
コード例 #14
0
ファイル: mfRdWr2Dml.c プロジェクト: fishbaoz/MullinsPI
/**
 *
 *     This function programs the Data Pattern that will be sent and compared
 *     against.
 *
 *     @param[in,out] *NBPtr           - Pointer to the MEM_NB_BLOCK
 *     @param[in]     *PatternIndexPtr - Pointer to a generic index used to
 *                                         determine which pattern to program.
 *
 *     @return                 BOOLEAN
 *                                       TRUE
 *
 */
BOOLEAN
STATIC
MemFRdWr2DProgramDataPatternML (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       VOID* PatternIndexPtr
  )
{
  UINT8 SeedCount;
  UINT32 PrbsSeed;
  CONST STATIC UINT32 CmdStreamLenTbl[4] = {13, 61, 127, 251};

  ASSERT (NBPtr != 0);
  ASSERT (PatternIndexPtr != NULL);
  SeedCount = *(UINT8*)PatternIndexPtr;
  ASSERT (SeedCount <= (NBPtr->MaxSeedCount - 1));
  MemNSetBitFieldNb (NBPtr, BFCmdStreamLen, CmdStreamLenTbl[SeedCount]);
  PrbsSeed = 0x7EA05;
  switch (SeedCount) {
  case 0:
    MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x01);
    PrbsSeed = 0x7FFFF;
    break;
  case 1:
    MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x04);
    MemNSetBitFieldNb (NBPtr, BFXorPatOvr, 0xFF);
    PrbsSeed = 0x7EA05;
    break;
  case 2:
    MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x03);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern0, 0x55555549);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern1, 0x55555555);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern2, 0x55555555);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern3, 0x55555555);
    break;
  case 3:
    MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x03);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern0, 0xA5A5A55A);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern1, 0xA5A5A5A5);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern2, 0xA5A5A5A5);
    MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern3, 0xA5A5A5A5);
    break;
  default:
    ASSERT (FALSE);
  }
  ASSERT (PrbsSeed != 0);
  //
  // Program the PRBS Seed
  //
  NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, PrbsSeed);
  return TRUE;
}
コード例 #15
0
ファイル: mnottn.c プロジェクト: B-Rich/coreboot
VOID
MemNSetOtherTimingTN (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  INT8 ROD;
  INT8 WOD;
  INT8 LD;
  INT8 WrEarlyx2;
  INT8 CDDTrdrdSdDc;
  INT8 CDDTrdrdDd;
  INT8 CDDTwrwrDd;
  INT8 CDDTwrwrSdDc;
  INT8 CDDTrwtTO;
  INT8 CDDTwrrd;
  UINT8 TrdrdSdDc;
  UINT8 TrdrdDd;
  UINT8 TwrwrSdDc;
  UINT8 TwrwrDd;
  UINT8 TrdrdSdSc;
  UINT8 TwrwrSdSc;
  UINT8 Twrrd;
  UINT8 TrwtTO;
  BOOLEAN PerRankTimingEn;

  CH_DEF_STRUCT *ChannelPtr;
  ChannelPtr = NBPtr->ChannelPtr;

  PerRankTimingEn = (BOOLEAN) (MemNGetBitFieldNb (NBPtr, BFPerRankTimingEn));
  //
  // Latency Difference (LD) = Tcl - Tcwl
  //
  LD = (INT8) (MemNGetBitFieldNb (NBPtr, BFTcl)) - (INT8) (MemNGetBitFieldNb (NBPtr, BFTcwl));

  //
  // Read ODT Delay (ROD) = MAX ( 0, (RdOdtOnDuration - 6)) + MAX ( 0, (RdOdtTrnOnDly - LD))
  //
  ROD = MAX (0, (INT8) (MemNGetBitFieldNb (NBPtr, BFRdOdtOnDuration) - 6)) +
          MAX ( 0, (INT8) (MemNGetBitFieldNb (NBPtr, BFRdOdtTrnOnDly) - LD));
  //
  // Write ODT Delay (WOD) = MAX (0, (WrOdtOnDuration - 6))
  //
  WOD = MAX (0, (INT8) (MemNGetBitFieldNb (NBPtr, BFWrOdtOnDuration) - 6));
  //
  // WrEarly = ABS (WrDqDqsEarly) / 2
  //
  WrEarlyx2 = (INT8) MemNGetBitFieldNb (NBPtr, BFWrDqDqsEarly);

  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tLD: %d     ROD: %d     WOD: %d     WrEarlyx2: %d\n\n", LD, ROD, WOD, WrEarlyx2);
  //
  // Read to Read Timing (TrdrdSdSc, TrdrdScDc, TrdrdDd)
  //
  // TrdrdSdSc = 1.
  // TrdrdSdDc (in MEMCLKs) = MAX(TrdrdSdSc, 3 + (IF (D18F2xA8_dct[1:0][PerRankTimingEn])
  //             THEN CEIL(CDDTrdrdSdDc / 2 ) ELSE 0 ENDIF)).
  // TrdrdDd   = MAX(TrdrdSdDc, CEIL(MAX(ROD + 3, CDDTrdrdDd/2 + 3.5)))
  //
  TrdrdSdSc = 1;

  CDDTrdrdSdDc = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly, TRUE, FALSE);
  TrdrdSdDc = MAX (0, PerRankTimingEn ? (3 + (CDDTrdrdSdDc + 1) / 2) : 3);
  TrdrdSdDc = MAX (TrdrdSdSc, TrdrdSdDc);

  CDDTrdrdDd = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly, FALSE, TRUE);
  TrdrdDd = MAX (ROD + 3, (CDDTrdrdDd + 7 + 1) / 2);
  TrdrdDd = MAX (TrdrdSdDc, TrdrdDd);

  MemNSetBitFieldNb (NBPtr, BFTrdrdDd, (UINT32) TrdrdDd);
  MemNSetBitFieldNb (NBPtr, BFTrdrdSdDc, (UINT32) TrdrdSdDc);
  MemNSetBitFieldNb (NBPtr, BFTrdrdSdSc, (UINT32) TrdrdSdSc);
  //
  // Write to Write Timing (TwrwrSdSc, TwrwrScDc, TwrwrDd)
  //
  // TwrwrSdSc = 1.
  // TwrwrSdDc = CEIL(MAX(WOD + 3, CDDTwrwrSdDc / 2 +
  //            (IF (D18F2xA8_dct[1:0][PerRankTimingEn]) THEN 3.5 ELSE 3 ENDIF))).
  //
  // TwrwrDd = CEIL (MAX (WOD + 3, CDDTwrwrDd / 2 + 3.5))
  // TwrwrSdSc <= TwrwrSdDc <= TwrwrDd
  //
  TwrwrSdSc = 1;

  CDDTwrwrSdDc = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessWrDqsDly, TRUE, FALSE);
  TwrwrSdDc = (UINT8) MAX (WOD + 3, (CDDTwrwrSdDc + (PerRankTimingEn ? 7 : 6) + 1 ) / 2);

  CDDTwrwrDd = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessWrDqsDly, FALSE, TRUE);
  TwrwrDd = (UINT8) MAX ((UINT8) (WOD + 3), (CDDTwrwrDd + 7 + 1) / 2);

  TwrwrSdDc = (TwrwrSdSc <= TwrwrSdDc) ? TwrwrSdDc : TwrwrSdSc;
  TwrwrDd = (TwrwrSdDc <= TwrwrDd) ? TwrwrDd : TwrwrSdDc;

  MemNSetBitFieldNb (NBPtr, BFTwrwrDd, (UINT32) TwrwrDd);
  MemNSetBitFieldNb (NBPtr, BFTwrwrSdDc, (UINT32) TwrwrSdDc);
  MemNSetBitFieldNb (NBPtr, BFTwrwrSdSc, (UINT32) TwrwrSdSc);
  //
  // Write to Read DIMM Termination Turn-around
  //
  // Twrrd = MAX ( 1, CEIL (MAX (WOD, (CDDTwrrd / 2) + 0.5 - WrEarly) - LD + 3))
  //
  CDDTwrrd = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessRcvEnDly, TRUE, TRUE);
  Twrrd =  MAX (1, MAX (WOD, (CDDTwrrd + 1 - WrEarlyx2 + 1) / 2) - LD + 3);

  MemNSetBitFieldNb (NBPtr, BFTwrrd, (UINT32) Twrrd);
  //
  // Read to Write Turnaround for Data, DQS Contention
  //
  // TrwtTO = CEIL (MAX (ROD, (CDDTrwtTO / 2) - 0.5 + WrEarly) + LD + 3)
  //
  CDDTrwtTO = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessWrDqsDly, TRUE, TRUE);

  TrwtTO = MAX ((ChannelPtr->Dimms == 1 ? 0 : ROD) , (CDDTrwtTO - 1 + WrEarlyx2 + 1) / 2) + LD + 3;

  MemNSetBitFieldNb (NBPtr, BFTrwtTO, (UINT32) TrwtTO);
  //
  // Read to Write Turnaround for opportunistic Write Bursting
  //
  // TrwtWB = TrwtTO + 1
  //
  MemNSetBitFieldNb (NBPtr, BFTrwtWB, (UINT32) TrwtTO + 1);

  IDS_HDT_CONSOLE (MEM_FLOW, "\t\t                            TrdrdSdSc : %02x\n", TrdrdSdSc);
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrdrdSdDc : %02x           TrdrdSdDc : %02x\n", CDDTrdrdSdDc, TrdrdSdDc);
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrdrdDd   : %02x           TrdrdDd   : %02x\n\n", CDDTrdrdDd, TrdrdDd);

  IDS_HDT_CONSOLE (MEM_FLOW, "\t\t                            TwrwrSdSc  : %02x\n", TwrwrSdSc);
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrwrSdDc : %02x           TwrwrSdDc : %02x\n", CDDTwrwrSdDc, TwrwrSdDc );
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrwrDd   : %02x           TwrwrDd   : %02x\n\n", CDDTwrwrDd, TwrwrDd);

  IDS_HDT_CONSOLE (MEM_FLOW, "\t\t                            TrwtWB    : %02x\n", TrwtTO + 1);
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrrd     : %02x           Twrrd     : %02x\n", (UINT8) CDDTwrrd, (UINT8) Twrrd );
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrwtTO    : %02x           TrwtTO    : %02x\n\n", (UINT8) CDDTrwtTO, (UINT8) TrwtTO );
}
コード例 #16
0
ファイル: mnphyon.c プロジェクト: AdriDlu/coreboot
VOID
MemNBeforeDQSTrainingON (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MemTBeginTraining (NBPtr->TechPtr);

  MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1);
  MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0);
  MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 0);
  MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 0);
  MemNSetBitFieldNb (NBPtr, BFEnRxPadStandby, 0);
  MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 1);
  MemNSetBitFieldNb (NBPtr, BFDctWrLimit, 0x1F);
  MemNSetBitFieldNb (NBPtr, BFEnCpuSerRdBehindNpIoWr, 1);
  MemNSetBitFieldNb (NBPtr, BFDbeGskMemClkAlignMode, 0);
  MemNSetBitFieldNb (NBPtr, BFMaxLatency, 0x12);
  MemNSetBitFieldNb (NBPtr, BFTraceModeEn, 0);

  // Enable cut through mode for NB P0
  MemNSetBitFieldNb (NBPtr, BFDisCutThroughMode, 0);

  MemTEndTraining (NBPtr->TechPtr);
}
コード例 #17
0
ファイル: mnphy.c プロジェクト: fishbaoz/KaveriPI
UINT32
MemNcmnGetSetTrainDlyUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 IsSet,
  IN       TRN_DLY_TYPE TrnDly,
  IN       DRBN DrbnVar,
  IN       UINT16 Field
  )
{
  UINT16 Index;
  UINT16 Offset;
  UINT32 Value;
  UINT32 Address;
  UINT8 Dimm;
  UINT8 Rank;
  UINT8 Byte;
  UINT8 Nibble;
  UINT8 DimmNibble;

  Dimm = DRBN_DIMM (DrbnVar);
  Rank = DRBN_RANK (DrbnVar);
  Byte = DRBN_BYTE (DrbnVar);
  Nibble = DRBN_NBBL (DrbnVar);
  DimmNibble = DRBN_DIMM_NBBL (DrbnVar);

  ASSERT (Dimm < (NBPtr->CsPerChannel / NBPtr->CsPerDelay));
  ASSERT (Byte <= ECC_DLY);
  if ((Byte == ECC_DLY) && (!NBPtr->MCTPtr->Status[SbEccDimms] || !NBPtr->IsSupported[EccByteTraining])) {
    // When ECC is not enabled
    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 AccessRdDqs2dDly:
    Index = 0x00;
    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++;
    }
    if (Byte > 7) {
      Index += 2;
    }
    Offset = 16 * (Byte % 2);
    Index |= (Rank << 8);
    Index |= (Nibble << 9);
    Address = Index;
    break;

  case AccessRdDqsDly:
  case AccessWrDatDly:

    if (NBPtr->IsSupported[DimmBasedOnSpeed]) {
      if (NBPtr->DCTPtr->Timings.Speed < DDR800_FREQUENCY) {
        // if DDR speed is below 800, use DIMM 0 delays for all DIMMs.
        Dimm = 0;
      }
    }

    Index += (Dimm * 0x100);
    if (Nibble) {
      if (Rank) {
        Index += 0xA0;
      } else {
        Index += 0x70;
      }
    } else if (Rank) {
      Index += 0x60;
    }
    // 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);
    Address = Index;
    break;
  case AccessRdDqs2dDly:
    Address = 0x0D0F0000;
    Index += (DimmNibble >> 1) * 0x100;
    Index += 0x20;
    Index = Index + Dimm;
    Offset = 4 * ((DimmNibble & 0x01) * 2);
    Address += Index;
    break;
  default:
    Offset = 0;
    IDS_ERROR_TRAP;
    Address = Index;
  }
  MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
  MemNPollBitFieldNb (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, FALSE);
  Value = MemNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
  if (TrnDly == AccessRdDqsDly) {
    NBPtr->FamilySpecificHook[AdjustRdDqsDlyOffset] (NBPtr, &Offset);
  }

  if (IsSet) {
    if (TrnDly == AccessPhRecDly) {
      Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
    }
    if (TrnDly != AccessRdDqs2dDly) {
      Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) ((TrnDly == AccessRcvEnDly) ? 0x3FF : 0xFF) << Offset)));
    } else {
      Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) 0x1F << Offset)));
    }
    ASSERT (!NBPtr->IsSupported[ScrubberEn]);   // Phy CSR write is not allowed after scrubber is enabled
    MemNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
    Address |= DCT_ACCESS_WRITE;
    MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
    MemNPollBitFieldNb (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, FALSE);
    if (TrnDly == AccessPhRecDly) {
      NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
    }
  } else {
    if (TrnDly != AccessRdDqs2dDly) {
      Value = (Value >> Offset) & (UINT32) ((TrnDly == AccessRcvEnDly) ? 0x3FF : 0xFF);
    } else {
コード例 #18
0
ファイル: mnphy.c プロジェクト: fishbaoz/KaveriPI
VOID
MemNTrainPhyFenceNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 Byte;
  INT16 Avg;
  UINT8 PREvalue;

  if (MemNGetBitFieldNb (NBPtr, BFDisDramInterface)) {
    return;
  }

  // 1. BIOS first programs a seed value to the phase recovery
  //    engine registers.
  //
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tSeeds: ");
  for (Byte = 0; Byte < MAX_BYTELANES_PER_CHANNEL; Byte++) {
    // This includes ECC as byte 8
    MemNSetTrainDlyNb (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (0, Byte), 19);
    IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", 19);
  }

  IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tPhyFenceTrEn = 1");
  // 2. Set F2x[1, 0]9C_x08[PhyFenceTrEn]=1.
  MemNSetBitFieldNb (NBPtr, BFPhyFenceTrEn, 1);

  if (!NBPtr->IsSupported[UnifiedNbFence]) {
    // 3. Wait 200 MEMCLKs.
    MemNWaitXMemClksNb (NBPtr, 200);
  } else {
    // 3. Wait 2000 MEMCLKs.
    MemNWaitXMemClksNb (NBPtr, 2000);
  }

  // 4. Clear F2x[1, 0]9C_x08[PhyFenceTrEn]=0.
  MemNSetBitFieldNb (NBPtr, BFPhyFenceTrEn, 0);

  // 5. BIOS reads the phase recovery engine registers
  //    F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52.
  // 6. Calculate the average value of the fine delay and subtract 8.
  //
  Avg = 0;
  IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t  PRE: ");
  for (Byte = 0; Byte < MAX_BYTELANES_PER_CHANNEL; Byte++) {
    //
    // This includes ECC as byte 8.   ECC Byte lane (8) is ignored by MemNGetTrainDlyNb function where
    // ECC is not supported.
    //
    PREvalue = (UINT8) (0x1F & MemNGetTrainDlyNb (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (0, Byte)));
    Avg = Avg + ((INT16) PREvalue);
    IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", PREvalue);
  }
  Avg = ((Avg + 8) / 9);    // round up

  NBPtr->MemNPFenceAdjustNb (NBPtr, &Avg);

  IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFence: %02x\n", Avg);

  // 7. Write the value to F2x[1, 0]9C_x0C[PhyFence].
  MemNSetBitFieldNb (NBPtr, BFPhyFence, Avg);

  // 8. BIOS rewrites F2x[1, 0]9C_x04, DRAM Address/Command Timing Control
  //    Register delays for both channels. This forces the phy to recompute
  //    the fence.
  //
  MemNSetBitFieldNb (NBPtr, BFAddrTmgControl, MemNGetBitFieldNb (NBPtr, BFAddrTmgControl));
}
コード例 #19
0
ファイル: mnphy.c プロジェクト: fishbaoz/KaveriPI
VOID
MemNPhyFenceTrainingUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 FenceThresholdTxDll;
  UINT8 FenceThresholdRxDll;
  UINT8 FenceThresholdTxPad;
  UINT16 Fence2Data;

  MemNSetBitFieldNb (NBPtr, BFDataFence2, 0);
  MemNSetBitFieldNb (NBPtr, BFFence2, 0);
  // 1. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=10b.
  // 2. Perform phy fence training.
  // 3. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdTxDll].
  MemNSetBitFieldNb (NBPtr, BFFenceTrSel, 2);
  MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 30, 26, BFPhyFence);
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tFenceThresholdTxDll\n");
  MemNTrainPhyFenceNb (NBPtr);
  FenceThresholdTxDll = (UINT8) MemNGetBitFieldNb (NBPtr, BFPhyFence);
  NBPtr->FamilySpecificHook[DetectMemPllError] (NBPtr, &FenceThresholdTxDll);

  // 4. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0F[AlwaysEnDllClks]=001b.
  MemNSetBitFieldNb (NBPtr, BFAlwaysEnDllClks, 0x1000);

  // 5. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=01b.
  // 6. Perform phy fence training.
  // 7. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdRxDll].
  MemNSetBitFieldNb (NBPtr, BFFenceTrSel, 1);
  MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 25, 21, BFPhyFence);
  IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFenceThresholdRxDll\n");
  MemNTrainPhyFenceNb (NBPtr);
  FenceThresholdRxDll = (UINT8) MemNGetBitFieldNb (NBPtr, BFPhyFence);
  NBPtr->FamilySpecificHook[DetectMemPllError] (NBPtr, &FenceThresholdRxDll);

  // 8. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0F[AlwaysEnDllClks]=000b.
  MemNSetBitFieldNb (NBPtr, BFAlwaysEnDllClks, 0x0000);

  // 9. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=11b.
  // 10. Perform phy fence training.
  // 11. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdTxPad].
  MemNSetBitFieldNb (NBPtr, BFFenceTrSel, 3);
  MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 20, 16, BFPhyFence);
  IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFenceThresholdTxPad\n");
  MemNTrainPhyFenceNb (NBPtr);
  FenceThresholdTxPad = (UINT8) MemNGetBitFieldNb (NBPtr, BFPhyFence);
  NBPtr->FamilySpecificHook[DetectMemPllError] (NBPtr, &FenceThresholdTxPad);

  // Program Fence2 threshold for Clk, Cmd, and Addr
  if (FenceThresholdTxPad < 16) {
    MemNSetBitFieldNb (NBPtr, BFClkFence2, FenceThresholdTxPad | 0x10);
    MemNSetBitFieldNb (NBPtr, BFCmdFence2, FenceThresholdTxPad | 0x10);
    MemNSetBitFieldNb (NBPtr, BFAddrFence2, FenceThresholdTxPad | 0x10);
  } else {
    MemNSetBitFieldNb (NBPtr, BFClkFence2, 0);
    MemNSetBitFieldNb (NBPtr, BFCmdFence2, 0);
    MemNSetBitFieldNb (NBPtr, BFAddrFence2, 0);
  }

  // Program Fence2 threshold for data
  Fence2Data = 0;
  if (FenceThresholdTxPad < 16) {
    Fence2Data |= FenceThresholdTxPad | 0x10;
  }
  if (FenceThresholdRxDll < 16) {
    Fence2Data |= (FenceThresholdRxDll | 0x10) << 10;
  }
  if (FenceThresholdTxDll < 16) {
    Fence2Data |= (FenceThresholdTxDll | 0x10) << 5;
  }
  MemNSetBitFieldNb (NBPtr, BFDataFence2, Fence2Data);
  NBPtr->FamilySpecificHook[ProgramFence2RxDll] (NBPtr, &Fence2Data);

  if (NBPtr->MCTPtr->Status[SbLrdimms]) {
    // 18. If motherboard routing requires CS[7:6] to adopt address timings, e.g. 3 LRDIMMs/ch with CS[7:6]
    // routed across all DIMM sockets, BIOS performs the following:
    if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_NO_LRDIMM_CS67_ROUTING, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) {
      //   A. Program D18F2xA8_dct[1:0][CSTimingMux67] = 1.
      MemNSetBitFieldNb (NBPtr, BFCSTimingMux67, 1);
      //   B. Program D18F2x9C_x0D0F_8021_dct[1:0]:
      //       - DiffTimingEn = 1.
      //       - IF (D18F2x9C_x0000_0004_dct[1:0][AddrCmdFineDelay] >=
      //         D18F2x9C_x0D0F_E008_dct[1:0][FenceValue]) THEN Fence = 1 ELSE Fence = 0.
      //       - Delay = D18F2x9C_x0000_0004_dct[1:0][AddrCmdFineDelay].
      //
      MemNSetBitFieldNb (NBPtr, BFDiffTimingEn, 1);
      MemNSetBitFieldNb (NBPtr, BFFence, (MemNGetBitFieldNb (NBPtr, BFAddrCmdFineDelay) >= MemNGetBitFieldNb (NBPtr, BFFenceValue)) ? 1 : 0);
      MemNSetBitFieldNb (NBPtr, BFDelay, (MemNGetBitFieldNb (NBPtr, BFAddrCmdFineDelay)));
    }
  }

  // 19. Reprogram F2x9C_04.
  MemNSetBitFieldNb (NBPtr, BFAddrTmgControl, MemNGetBitFieldNb (NBPtr, BFAddrTmgControl));

}
コード例 #20
0
ファイル: mnphyhy.c プロジェクト: AdriDlu/coreboot
VOID
MemNInitPhyCompHy (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST UINT8 TableCompRiseSlew20x[] = {7, 3, 2, 2};
  CONST UINT8 TableCompRiseSlew15x[] = {7, 7, 3, 2};
  CONST UINT8 TableCompFallSlew20x[] = {7, 5, 3, 2};
  CONST UINT8 TableCompFallSlew15x[] = {7, 7, 5, 3};
  UINT8 i;
  UINT8 j;
  UINT8 CurrDct;
  UINT8 MaxDimmsPerChannel;
  UINT8 *DimmsPerChPtr;

  CurrDct = NBPtr->Dct;

  //
  // Get Platform Information
  //
  DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
  if (DimmsPerChPtr != NULL) {
    MaxDimmsPerChannel = *DimmsPerChPtr;
  } else {
    MaxDimmsPerChannel = 2;
  }

  // 1. BIOS disables the phy compensation register by programming F2x9C_x08[DisAutoComp]=1
  // 2. BIOS waits 5 us for the disabling of the compensation engine to complete.
  // DisAutoComp will be cleared after Dram init has completed
  //
  MemNSwitchDCTNb (NBPtr, 0);
  MemNSetBitFieldNb (NBPtr, BFDisAutoComp, 1);
  MemUWait10ns (500, NBPtr->MemPtr);
  MemNSwitchDCTNb (NBPtr, CurrDct);

  // 3. For each normalized driver strength code read from
  // F2x[1, 0]9C_x00[AddrCmdDrvStren], program the
  // corresponding 3 bit predriver code in F2x9C_x0A[D3Cmp1NCal, D3Cmp1PCal].
  //
  // 4. For each normalized driver strength code read from
  // F2x[1, 0]9C_x00[DataDrvStren], program the corresponding
  // 3 bit predriver code in F2x9C_x0A[D3Cmp0NCal, D3Cmp0PCal, D3Cmp2NCal,
  // D3Cmp2PCal].
  //
  j = (UINT8) MemNGetBitFieldNb (NBPtr, BFAddrCmdDrvStren);
  i = (UINT8) MemNGetBitFieldNb (NBPtr, BFDataDrvStren);

  MemNSwitchDCTNb (NBPtr, 0);
  ASSERT (j <= 3);
  MemNSetBitFieldNb (NBPtr, BFD3Cmp1NCal, TableCompRiseSlew20x[j]);
  MemNSetBitFieldNb (NBPtr, BFD3Cmp1PCal, TableCompFallSlew20x[j]);

  ASSERT (i <= 3);
  MemNSetBitFieldNb (NBPtr, BFD3Cmp0NCal, TableCompRiseSlew15x[i]);
  MemNSetBitFieldNb (NBPtr, BFD3Cmp0PCal, TableCompFallSlew15x[i]);
  MemNSetBitFieldNb (NBPtr, BFD3Cmp2NCal, TableCompRiseSlew15x[i]);
  MemNSetBitFieldNb (NBPtr, BFD3Cmp2PCal, TableCompFallSlew15x[i]);

  //
  // Special Case for certain configs
  //
  // 3DPCH Fully populated.
  if ((MaxDimmsPerChannel == 3) && (NBPtr->ChannelPtr->Dimms == 3)) {
    MemNSetBitFieldNb (NBPtr, BFD3Cmp0NCal, 3);
    MemNSetBitFieldNb (NBPtr, BFD3Cmp0PCal, 5);
    MemNSetBitFieldNb (NBPtr, BFD3Cmp2NCal, 3);
    MemNSetBitFieldNb (NBPtr, BFD3Cmp2PCal, 5);
  }

  MemNSwitchDCTNb (NBPtr, CurrDct);
}
コード例 #21
0
ファイル: mmflowd3kv.c プロジェクト: fishbaoz/KaveriPI
/**
 *
 *
 *      This function defines the DDR3 initialization flow
 *      when only DDR3 DIMMs are present in the system
 *
 *     @param[in,out]   *MemMainPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *
 *     @return          AGESA_STATUS
 *                          - AGESA_FATAL
 *                          - AGESA_CRITICAL
 *                          - AGESA_SUCCESS
 */
AGESA_STATUS
MemMD3FlowKV (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
  )
{
  UINT8            Dct;
  MEM_NB_BLOCK     *NBPtr;
  MEM_DATA_STRUCT  *MemPtr;
  ID_INFO          CallOutIdInfo;
  INT8             MemPstate;
  UINT8            LowestMemPstate;
  UINT8            PmuImage;
  BOOLEAN          ErrorRecovery;
  BOOLEAN          IgnoreErr;

  NBPtr = &MemMainPtr->NBPtr[BSP_DIE];
  MemPtr = MemMainPtr->MemPtr;
  ErrorRecovery = TRUE;
  IgnoreErr = FALSE;

  IDS_HDT_CONSOLE (MEM_FLOW, "DDR3 Mode\n");

  //----------------------------------------------------------------
  // Defines DDR3 registers
  //----------------------------------------------------------------
  MemNInitNBRegTableD3KV (NBPtr);

  //----------------------------------------------------------------
  // Clock and power gate unsued channels
  //----------------------------------------------------------------
  MemNClockAndPowerGateUnusedDctKV (NBPtr);

  //----------------------------------------------------------------
  // Set DDR3 mode
  //----------------------------------------------------------------
  MemNSetDdrModeD3KV (NBPtr);

  //----------------------------------------------------------------
  // Enable PHY Calibration
  //----------------------------------------------------------------
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctDimmValid != 0) {
      MemNEnablePhyCalibrationKV (NBPtr);
    }
  }

  //----------------------------------------------------------------
  // Low voltage DDR3
  //----------------------------------------------------------------
  // Levelize DDR3 voltage based on socket, as each socket has its own voltage for dimms.
  AGESA_TESTPOINT (TpProcMemLvDdr3, &(MemMainPtr->MemPtr->StdHeader));
  if (!MemFeatMain.LvDDR3 (MemMainPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // Find the maximum speed that all DCTs are capable running at
  //----------------------------------------------------------------
  if (!MemTSPDGetTargetSpeed3 (NBPtr->TechPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // Adjust memClkFreq based on MaxDdrRate
  //----------------------------------------------------------------
  MemNAdjustDdrSpeed3Unb (NBPtr);

  //------------------------------------------------
  // Finalize target frequency
  //------------------------------------------------
  if (!MemMLvDdr3PerformanceEnhFinalize (MemMainPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  //  Program DCT address map
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "DCT addr map\n");
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);
    MemNSwitchDCTNb (NBPtr, Dct);

    if (NBPtr->DCTPtr->Timings.DctDimmValid == 0) {
      MemNDisableDctKV (NBPtr);
    } else {
      IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCS Addr Map\n");
      if (MemTSPDSetBanks3 (NBPtr->TechPtr)) {
        if (MemNStitchMemoryNb (NBPtr)) {
          if (NBPtr->DCTPtr->Timings.CsEnabled == 0) {
            MemNDisableDctKV (NBPtr);
          } else {
            IDS_HDT_CONSOLE (MEM_FLOW, "\t\tAuto Cfg\n");
            MemNAutoConfigKV (NBPtr);
            IDS_HDT_CONSOLE (MEM_FLOW, "\t\tTraining Cfg\n");
            MemNConfigureDctForTrainingD3KV (NBPtr);
          }
        }
      }
    }
  }

  IDS_OPTION_HOOK (IDS_BEFORE_DRAM_INIT, NBPtr, &(MemMainPtr->MemPtr->StdHeader));
  //----------------------------------------------------------------
  //  Init Phy mode
  //----------------------------------------------------------------
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb  (NBPtr, Dct);

    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);

      // 1. Program D18F2x9C_x0002_0099_dct[3:0][PmuReset,PmuStall] = 1,1.
      // 2. Program D18F2x9C_x0002_000E_dct[3:0][PhyDisable]=0. Tester_mode=0.
      MemNPmuResetNb (NBPtr);

      // 3. According to the type of DRAM attached, program D18F2x9C_x00FFF04A_dct[3:0][MajorMode],
      //    D18F2x9C_x0002_000E_dct[3:0][G5_Mode], and D18F2x9C_x0002_0098_dct[3:0][CalG5D3].
      //    D18F2x9C_x0[3,1:0][F,7:0]1_[F,B:0]04A_dct[3:0].
      MemNSetPhyDdrModeKV (NBPtr, DRAM_TYPE_DDR3_KV);

      // Work-around for CPU A0/A1, PhyReceiverPowerMode
      if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F15_KV_A0) != 0) {
        MemNPrePhyReceiverLowPowerKV (NBPtr);
      }
    }
  }

  //----------------------------------------------------------------
  //  Temporary buffer for DRAM CAD Bus Configuration
  //----------------------------------------------------------------
  if (!MemNInitDramCadBusConfigKV (NBPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  //  Program Mem Pstate dependent registers
  //----------------------------------------------------------------
  IEM_SKIP_CODE (IEM_EARLY_DCT_CONFIG) {
    // PMU required M1 settings regardless Memory Pstate disabled.
    LowestMemPstate = 1;
  }

  for (MemPstate = LowestMemPstate; MemPstate >= 0; MemPstate--) {
    // When memory pstate is enabled, this loop will goes through M1 first then M0
    // Otherwise, this loop only goes through M0.
    MemNSwitchMemPstateKV (NBPtr, MemPstate);

    // By default, start up speed is DDR667 for M1
    // For M0, we need to set speed to highest possible frequency
    if (MemPstate == 0) {
      for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
        MemNSwitchDCTNb (NBPtr, Dct);
        NBPtr->DCTPtr->Timings.Speed = NBPtr->DCTPtr->Timings.TargetSpeed;
      }
    }
    IDS_HDT_CONSOLE (MEM_FLOW, "MemClkFreq = %d MHz\n", NBPtr->DCTPtr->Timings.Speed);

    // Program SPD timings and frequency dependent settings
    for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
      IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);
      MemNSwitchDCTNb (NBPtr, Dct);

      if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
        IDS_HDT_CONSOLE (MEM_FLOW, "\t\tSPD timings\n");
        if (MemTAutoCycTiming3 (NBPtr->TechPtr)) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMemPs Reg\n");
          MemNProgramMemPstateRegD3KV (NBPtr, MemPstate);
          IDS_HDT_CONSOLE (MEM_FLOW, "\t\tPlatform Spec\n");
          if (MemNPlatformSpecKV (NBPtr)) {
            MemNSetBitFieldNb (NBPtr, BFMemClkDis, 0);
            // 7. Program default CAD bus values.
            // 8. Program default data bus values.
            IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCAD Data Bus Cfg\n");
            MemNProgramCadDataBusD3KV (NBPtr);

            IDS_HDT_CONSOLE (MEM_FLOW, "\t\tPredriver\n");
            MemNPredriverInitKV (NBPtr);

            IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMode Register initialization\n");
            MemNModeRegisterInitializationKV (NBPtr);

            IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDRAM PHY Power Savings\n");
            MemNDramPhyPowerSavingsKV (NBPtr);
          }
        }
      }
    }

    MemFInitTableDrive (NBPtr, MTBeforeDInit);
  }


  //----------------------------------------------------------------
  //  Program Phy
  //----------------------------------------------------------------
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb  (NBPtr, Dct);

    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);

      // 4. Program general phy static configuration. See 2.10.7.3.1.
      MemNPhyGenCfgKV (NBPtr);

      // 5. Phy Voltage Level Programming. See 2.10.7.3.2.
      MemNPhyVoltageLevelKV (NBPtr);

      // 6. Program DRAM channel frequency. See 2.10.7.3.3.
      MemNProgramChannelFreqKV (NBPtr, DRAM_TYPE_DDR3_KV);

      // Step 7 and 8 are done in MemPs dependent section

      // 9. Program FIFO pointer init values. See 2.10.7.3.6.
      MemNPhyFifoConfigD3KV (NBPtr);
    }
  }

  IEM_INSERT_CODE (IEM_EARLY_DEVICE_INIT, IemEarlyDeviceInitD3KV, (NBPtr));

  //------------------------------------------------
  // Callout before Dram Init
  //------------------------------------------------
  AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(MemMainPtr->MemPtr->StdHeader));
  CallOutIdInfo.IdField.SocketId = NBPtr->MCTPtr->SocketId;
  CallOutIdInfo.IdField.ModuleId = NBPtr->MCTPtr->DieId;
  //------------------------------------------------------------------------
  // Callout to Platform BIOS to set the VDDP/VDDR voltage based upon Bit 21
  // ProductIdentification Register (Dev18Fun3x1FC)
  //------------------------------------------------------------------------
  if (MemNGetBitFieldNb (NBPtr, BFVddpVddrLowVoltSupp)) {
    MemMainPtr->MemPtr->ParameterListPtr->VddpVddrVoltage.Voltage = VOLT0_95;
    MemMainPtr->MemPtr->ParameterListPtr->VddpVddrVoltage.IsValid = TRUE;
    NBPtr->DCTPtr->Timings.TargetSpeed = DDR1600_FREQUENCY;
  } else {
    MemMainPtr->MemPtr->ParameterListPtr->VddpVddrVoltage.IsValid = FALSE;
  }
  IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS on Socket %d, Module %d...\n", CallOutIdInfo.IdField.SocketId, CallOutIdInfo.IdField.ModuleId);
  AgesaHookBeforeDramInit ((UINTN) CallOutIdInfo.IdInformation, MemMainPtr->MemPtr);
  NBPtr[BSP_DIE].FamilySpecificHook[AmpVoltageDisp] (&NBPtr[BSP_DIE], NULL);
  IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO = 1.%dV\n", (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) ? 5 :
                                        (NBPtr->RefPtr->DDR3Voltage == VOLT1_35) ? 35 :
                                        (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) ? 25 : 999);
  AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader));

  //----------------------------------------------------------------------------
  // Deassert MemResetL
  //----------------------------------------------------------------------------
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb  (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      // Deassert Procedure:
      //   MemResetL = 0
      //   Go to LP2
      //   Go to PS0
      MemNSetBitFieldNb (NBPtr, BFMemResetL, 0);
      MemNSetBitFieldNb (NBPtr, RegPwrStateCmd, 4);
      MemNSetBitFieldNb (NBPtr, RegPwrStateCmd, 0);
    }
  }
  MemUWait10ns (20000, NBPtr->MemPtr);

  //----------------------------------------------------------------------------
  //  Program PMU SRAM Message Block, Initiate PMU based Dram init and training
  //----------------------------------------------------------------------------
  for (PmuImage = 0; PmuImage < MemNNumberOfPmuFirmwareImageKV (NBPtr); ++PmuImage) {
    NBPtr->PmuFirmwareImage = PmuImage;
    NBPtr->FeatPtr->LoadPmuFirmware (NBPtr);

    for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
      MemNSwitchDCTNb  (NBPtr, Dct);
      if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
        IDS_HDT_CONSOLE (MEM_STATUS, "Dct %d\n", Dct);
        IDS_HDT_CONSOLE (MEM_FLOW, "Initialize the PMU SRAM Message Block buffer\n");
        if (MemNInitPmuSramMsgBlockKV (NBPtr) == FALSE) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tNot able to initialize the PMU SRAM Message Block buffer\n");
          // Not able to initialize the PMU SRAM Message Block buffer.  Log an event.
          PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_PMU_SRAM_MSG_BLOCK, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader));
          return AGESA_FATAL;
        }

        for (MemPstate = LowestMemPstate; MemPstate >= 0; MemPstate--) {
          // When memory pstate is enabled, this loop will goes through M1 first then M0
          // Otherwise, this loop only goes through M0.
          MemNSwitchMemPstateKV (NBPtr, MemPstate);

          IDS_HDT_CONSOLE (MEM_FLOW, "\t\tPMU MemPs Reg\n");
          MemNPopulatePmuSramTimingsD3KV (NBPtr);
        }

        MemNPopulatePmuSramConfigD3KV (NBPtr);
        MemNSetPmuSequenceControlKV (NBPtr);
        if (MemNWritePmuSramMsgBlockKV (NBPtr) == FALSE) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tNot able to load the PMU SRAM Message Block in to DMEM\n");
          // Not able to load the PMU SRAM Message Block in to DMEM.  Log an event.
          PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_LOCATE_FOR_PMU_SRAM_MSG_BLOCK, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader));
          return AGESA_FATAL;
        }

        // Query for the calibrate completion.
        MemNPendOnPhyCalibrateCompletionKV (NBPtr);

        // Set calibration rate.
        MemNStartPmuNb (NBPtr);
      }
    }

    for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
      MemNSwitchDCTNb  (NBPtr, Dct);
      if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
        IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);
        if (MemNPendOnPmuCompletionNb (NBPtr) == FALSE) {
          PutEventLog (AGESA_FATAL, MEM_ERROR_PMU_TRAINING, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader));
          AGESA_TESTPOINT (TpProcMemPmuFailed, &(MemMainPtr->MemPtr->StdHeader));

          IDS_OPTION_HOOK (IDS_MEM_ERROR_RECOVERY, &ErrorRecovery, &(MemMainPtr->MemPtr->StdHeader));
          if (ErrorRecovery) {
            IDS_HDT_CONSOLE (MEM_FLOW, "Chipselects that PMU failed training %x\n",MemNGetBitFieldNb (NBPtr, PmuTestFail));
            NBPtr->DCTPtr->Timings.CsTrainFail = (UINT16) MemNGetBitFieldNb (NBPtr, PmuTestFail);
            NBPtr->MCTPtr->ChannelTrainFail |= (UINT32)1 << Dct;
          } else {
            IDS_OPTION_HOOK (IDS_MEM_IGNORE_ERROR, &IgnoreErr, &(MemMainPtr->MemPtr->StdHeader));
            if (!(IgnoreErr)) {
              return AGESA_FATAL;
            }
          }
        }

        MemNRateOfPhyCalibrateKV (NBPtr);
      }
    }
  }
  //----------------------------------------------------------------
  //  De-allocate the PMU SRAM Message Block buffer.
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "De-allocate PMU SRAM Message Block buffer\n");
  if (MemNPostPmuSramMsgBlockKV (NBPtr) == FALSE) {
    IDS_HDT_CONSOLE (MEM_FLOW, "\tNot able to free the PMU SRAM Message Block buffer\n");
    // Not able to free the PMU SRAM Message Block buffer.  Log an event.
    PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_DEALLOCATE_FOR_PMU_SRAM_MSG_BLOCK, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader));
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  //  De-allocate temporary buffer for DRAM CAD Bus Configuration
  //----------------------------------------------------------------
  if (!MemNPostDramCadBusConfigKV (NBPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // Disable chipselects that failed training
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDIMM Excludes\n");
  MemNDimmExcludesKV (NBPtr);

  //----------------------------------------------------------------
  //  Synchronize Channels
  //----------------------------------------------------------------
  MemNSyncChannelInitKV (NBPtr);

  //----------------------------------------------------------------
  //  Train MaxRdLatency
  //----------------------------------------------------------------
  IEM_SKIP_CODE (IEM_LATE_DCT_CONFIG) {
    NBPtr->TechPtr->FindMaxDlyForMaxRdLat = MemTFindMaxRcvrEnDlyTrainedByPmuByte;
    NBPtr->TechPtr->ResetDCTWrPtr = MemNResetRcvFifoKV;
    MemTTrainMaxLatency (NBPtr->TechPtr);
    // The fourth loop will restore the Northbridge P-State control register
    // to the original value.
    for (NBPtr->NbFreqChgState = 1; NBPtr->NbFreqChgState <= 4; NBPtr->NbFreqChgState++) {
      if (!MemNChangeNbFrequencyWrapUnb (NBPtr, NBPtr->NbFreqChgState) || (NBPtr->NbFreqChgState == 4)) {
        break;
      }
      MemTTrainMaxLatency (NBPtr->TechPtr);
    }
  }

  //----------------------------------------------------------------
  // Set MajorMode
  //----------------------------------------------------------------
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);

    // Work-around for CPU A0/A1, PhyReceiverPowerMode
    if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F15_KV_A0) != 0) {
      MemNPostPhyReceiverLowPowerKV (NBPtr);
    }
  }

  //----------------------------------------------------------------
  //  Configure DCT for normal operation
  //----------------------------------------------------------------
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);

    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);
      IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMission mode cfg\n");
      MemNConfigureDctNormalD3KV (NBPtr);

      //----------------------------------------------------------------
      //  Program turnaround timings
      //----------------------------------------------------------------
      for (MemPstate = LowestMemPstate; MemPstate >= 0; MemPstate--) {
        MemNSwitchMemPstateKV (NBPtr, MemPstate);
        MemNProgramTurnaroundTimingsD3KV (NBPtr);

        //----------------------------------------------------------------
        // After Mem Pstate1 Partial Training Table values
        //----------------------------------------------------------------
        MemFInitTableDrive (NBPtr, MTAfterMemPstate1PartialTrn);
      }
    }
  }

  IEM_INSERT_CODE (IEM_LATE_DCT_CONFIG, IemLateDctConfigD3KV, (NBPtr));

  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      IDS_HDT_CONSOLE (MEM_FLOW, "\t\tAdditional DRAM PHY Power Savings\n");
      MemNAddlDramPhyPowerSavingsKV (NBPtr);
    }
  }

  //----------------------------------------------------------------
  //  Initialize Channels interleave address bit.
  //----------------------------------------------------------------
  MemNInitChannelIntlvAddressBitKV (NBPtr);

  //----------------------------------------------------------------
  // Assign physical address ranges for DCTs and node. Also, enable channel interleaving.
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tHT mem map\n");
  if (!NBPtr->FeatPtr->InterleaveChannels (NBPtr)) {
    MemNHtMemMapKV (NBPtr);
  }

  //----------------------------------------------------
  // If there is no dimm on the system, do fatal exit
  //----------------------------------------------------
  if (NBPtr->RefPtr->SysLimit == 0) {
    PutEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND_ON_SYSTEM, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader));
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // CpuMemTyping
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMem typing\n");
  MemNCPUMemTypingNb (NBPtr);

  IDS_OPTION_HOOK (IDS_BEFORE_DQS_TRAINING, MemMainPtr, &(MemMainPtr->MemPtr->StdHeader));

  //----------------------------------------------------------------
  // After Training Table values
  //----------------------------------------------------------------
  MemFInitTableDrive (NBPtr, MTAfterTrn);

  //----------------------------------------------------------------
  // Interleave banks
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tBank Intlv\n");
  if (NBPtr->FeatPtr->InterleaveBanks (NBPtr)) {
    if (NBPtr->MCTPtr->ErrCode == AGESA_FATAL) {
      return AGESA_FATAL;
    }
  }

  //----------------------------------------------------------------
  // After Programming Interleave registers
  //----------------------------------------------------------------
  MemFInitTableDrive (NBPtr, MTAfterInterleave);

  //----------------------------------------------------------------
  // Memory Clear
  //----------------------------------------------------------------
  AGESA_TESTPOINT (TpProcMemMemClr, &(MemMainPtr->MemPtr->StdHeader));
  if (!MemFeatMain.MemClr (MemMainPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // ECC
  //----------------------------------------------------------------
  if (!MemFeatMain.InitEcc (MemMainPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // C6 and ACP Engine Storage Allocation
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tC6 and ACP Engine Storage\n");
  MemNAllocateC6AndAcpEngineStorageKV (NBPtr);


  //----------------------------------------------------------------
  // UMA Allocation & UMAMemTyping
  //----------------------------------------------------------------
  AGESA_TESTPOINT (TpProcMemUMAMemTyping, &(MemMainPtr->MemPtr->StdHeader));
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tUMA Alloc\n");
  if (!MemFeatMain.UmaAllocation (MemMainPtr)) {
    return AGESA_FATAL;
  }

  //----------------------------------------------------------------
  // OnDimm Thermal
  //----------------------------------------------------------------
  if (NBPtr->FeatPtr->OnDimmThermal (NBPtr)) {
    if (NBPtr->MCTPtr->ErrCode == AGESA_FATAL) {
      return AGESA_FATAL;
    }
  }

  //----------------------------------------------------------------
  // Finalize MCT
  //----------------------------------------------------------------
  MemNFinalizeMctKV (NBPtr);
  MemFInitTableDrive (NBPtr, MTAfterFinalizeMCT);

  //----------------------------------------------------------------
  // Memory Context Save
  //----------------------------------------------------------------
  MemFeatMain.MemSave (MemMainPtr);

  //----------------------------------------------------------------
  // Memory DMI support
  //----------------------------------------------------------------
  if (!MemFeatMain.MemDmi (MemMainPtr)) {
    return AGESA_CRITICAL;
  }

  //----------------------------------------------------------------
  // Memory CRAT support
  //----------------------------------------------------------------
  if (!MemFeatMain.MemCrat (MemMainPtr)) {
    return AGESA_CRITICAL;
  }

  //----------------------------------------------------------------
  // Save memory S3 data
  //----------------------------------------------------------------
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tS3 Save\n");
  if (!MemMS3Save (MemMainPtr)) {
    return AGESA_CRITICAL;
  }

  //----------------------------------------------------------------
  // Switch back to DCT 0 before sending control back
  //----------------------------------------------------------------
  MemNSwitchDCTNb (NBPtr, 0);

  return AGESA_SUCCESS;
}
コード例 #22
0
ファイル: mnphyor.c プロジェクト: B-Rich/coreboot
VOID
MemNInitPhyCompOr (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  //
  // Phy Predriver Calibration Codes for Data/DQS
  //
  CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV15Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V
    {DDR667 + DDR800, {0x924, 0x924, 0x924, 0x924}},
    {DDR1066 + DDR1333, {0xFF6, 0xFF6, 0xFF6, 0xFF6}},
    {DDR1600 + DDR1866, {0xFF6, 0xFF6, 0xFF6, 0xFF6}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV135Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V
    {DDR667 + DDR800, {0xFF6, 0xB6D, 0xB6D, 0x924}},
    {DDR1066 + DDR1333, {0xFF6, 0xFF6, 0xFF6, 0xFF6}},
    {DDR1600 + DDR1866, {0xFF6, 0xFF6, 0xFF6, 0xFF6}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV125Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V
    {DDR667 + DDR800, {0xFF6, 0xDAD, 0xDAD, 0x924}},
    {DDR1066 + DDR1333, {0xFF6, 0xFF6, 0xFF6, 0xFF6}},
    {DDR1600 + DDR1866, {0xFF6, 0xFF6, 0xFF6, 0xFF6}}
  };
  CONST STATIC TXPREPN_ENTRY TxPrePNDataDqsOr[] = {
    {GET_SIZE_OF (TxPrePNDataDqsV15Or), (TXPREPN_STRUCT *)&TxPrePNDataDqsV15Or},
    {GET_SIZE_OF (TxPrePNDataDqsV135Or), (TXPREPN_STRUCT *)&TxPrePNDataDqsV135Or},
    {GET_SIZE_OF (TxPrePNDataDqsV125Or), (TXPREPN_STRUCT *)&TxPrePNDataDqsV125Or}
  };

  //
  // Phy Predriver Calibration Codes for Data/DQS
  //
  CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV15OrB1[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V
    {DDR667 + DDR800, {0xB6D, 0x6DB, 0x492, 0x492}},
    {DDR1066 + DDR1333, {0xFFF, 0x924, 0x6DB, 0x6DB}},
    {DDR1600 + DDR1866, {0xFFF, 0xFFF, 0xFFF, 0xB6D}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV135OrB1[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V
    {DDR667 + DDR800, {0xFFF, 0x924, 0x6DB, 0x492}},
    {DDR1066 + DDR1333, {0xFFF, 0xDB6, 0xB6D, 0x6DB}},
    {DDR1600 + DDR1866, {0xFFF, 0xFFF, 0xFFF, 0xDB6}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV125OrB1[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V
    {DDR667 + DDR800, {0xFFF, 0xB6D, 0x924, 0x6DB}},
    {DDR1066 + DDR1333, {0xFFF, 0xFFF, 0xDB6, 0x924}},
    {DDR1600 + DDR1866, {0xFFF, 0xFFF, 0xFFF, 0xFFF}}
  };
  CONST STATIC TXPREPN_ENTRY TxPrePNDataDqsOrB1[] = {
    {GET_SIZE_OF (TxPrePNDataDqsV15OrB1), (TXPREPN_STRUCT *)&TxPrePNDataDqsV15OrB1},
    {GET_SIZE_OF (TxPrePNDataDqsV135OrB1), (TXPREPN_STRUCT *)&TxPrePNDataDqsV135OrB1},
    {GET_SIZE_OF (TxPrePNDataDqsV125OrB1), (TXPREPN_STRUCT *)&TxPrePNDataDqsV125OrB1}
  };

  //
  // Phy Predriver Calibration Codes for Cmd/Addr
  //
  CONST STATIC TXPREPN_STRUCT TxPrePNCmdAddrV15Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V
    {DDR667 + DDR800, {0x492, 0x492, 0x492, 0x492}},
    {DDR1066 + DDR1333, {0x6DB, 0x6DB, 0x6DB, 0x6DB}},
    {DDR1600 + DDR1866, {0xB6D, 0xB6D, 0xB6D, 0xB6D}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNCmdAddrV135Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V
    {DDR667 + DDR800, {0x492, 0x492, 0x492, 0x492}},
    {DDR1066 + DDR1333, {0x924, 0x6DB, 0x6DB, 0x6DB}},
    {DDR1600 + DDR1866, {0xB6D, 0xB6D, 0x924, 0x924}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNCmdAddrV125Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V
    {DDR667 + DDR800, {0x492, 0x492, 0x492, 0x492}},
    {DDR1066 + DDR1333, {0xDAD, 0x924, 0x6DB, 0x492}},
    {DDR1600 + DDR1866, {0xFF6, 0xDAD, 0xB64, 0xB64}}
  };
  CONST STATIC TXPREPN_ENTRY TxPrePNCmdAddrOr[] = {
    {GET_SIZE_OF (TxPrePNCmdAddrV15Or), (TXPREPN_STRUCT *)&TxPrePNCmdAddrV15Or},
    {GET_SIZE_OF (TxPrePNCmdAddrV135Or), (TXPREPN_STRUCT *)&TxPrePNCmdAddrV135Or},
    {GET_SIZE_OF (TxPrePNCmdAddrV125Or), (TXPREPN_STRUCT *)&TxPrePNCmdAddrV125Or}
  };

  //
  // Phy Predriver Calibration Codes for Clock
  //
  CONST STATIC TXPREPN_STRUCT TxPrePNClockV15Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V
    {DDR667 + DDR800, {0x924, 0x924, 0x924, 0x924}},
    {DDR1066 + DDR1333, {0xFF6, 0xFF6, 0xFF6, 0xB6D}},
    {DDR1600 + DDR1866, {0xFF6, 0xFF6, 0xFF6, 0xFF6}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNClockV135Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V
    {DDR667 + DDR800, {0xDAD, 0xDAD, 0x924, 0x924}},
    {DDR1066 + DDR1333, {0xFF6, 0xFF6, 0xFF6, 0xDAD}},
    {DDR1600 + DDR1866, {0xFF6, 0xFF6, 0xFF6, 0xDAD}}
  };
  CONST STATIC TXPREPN_STRUCT TxPrePNClockV125Or[] = {
    //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V
    {DDR667 + DDR800, {0xDAD, 0xDAD, 0x924, 0x924}},
    {DDR1066 + DDR1333, {0xFF6, 0xFF6, 0xFF6, 0xFF6}},
    {DDR1600 + DDR1866, {0xFF6, 0xFF6, 0xFF6, 0xFF6}}
  };
  CONST STATIC TXPREPN_ENTRY TxPrePNClockOr[] = {
    {GET_SIZE_OF (TxPrePNClockV15Or), (TXPREPN_STRUCT *)&TxPrePNClockV15Or},
    {GET_SIZE_OF (TxPrePNClockV135Or), (TXPREPN_STRUCT *)&TxPrePNClockV135Or},
    {GET_SIZE_OF (TxPrePNClockV125Or), (TXPREPN_STRUCT *)&TxPrePNClockV125Or}
  };

  //
  // 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 PHY_COMP_INIT_NB PhyCompInitBitFieldOr[] = {
    // 3. Program TxPreP/TxPreN for Data and DQS according toTable 46 if VDDIO is 1.5V or Table 47 if 1.35V.
    //    A. Program D18F2x9C_x0D0F_0[F,8:0]0[A,6]_dct[1:0]={0000b, TxPreP, TxPreN}.
    //    B. Program D18F2x9C_x0D0F_0[F,8:0]0[A,6]_dct[1:0]={0000b, TxPreP, TxPreN}.
    {BFDqsDrvStren, BFDataByteTxPreDriverCal2Pad1, BFDataByteTxPreDriverCal2Pad1, 0, TxPrePNDataDqsOr},
    {BFDataDrvStren, BFDataByteTxPreDriverCal2Pad2, BFDataByteTxPreDriverCal2Pad2, 0, TxPrePNDataDqsOr},
    {BFDataDrvStren, BFDataByteTxPreDriverCal, BFDataByteTxPreDriverCal, 8, TxPrePNDataDqsOr},
    // 4. Program TxPreP/TxPreN for Cmd/Addr according to Table 49 if VDDIO is 1.5V or Table 50 if 1.35V.
    //    A. Program D18F2x9C_x0D0F_[C,8][1:0][12,0E,0A,06]_dct[1:0]={0000b, TxPreP, TxPreN}.
    //    B. Program D18F2x9C_x0D0F_[C,8][1:0]02_dct[1:0]={1000b, TxPreP, TxPreN}.
    {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCal2Pad1, BFCmdAddr0TxPreDriverCal2Pad2, 0, TxPrePNCmdAddrOr},
    {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCal2Pad1, BFAddrTxPreDriverCal2Pad4, 0, TxPrePNCmdAddrOr},
    {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCalPad0, BFCmdAddr0TxPreDriverCalPad0, 8, TxPrePNCmdAddrOr},
    {BFCkeDrvStren, BFAddrTxPreDriverCalPad0, BFAddrTxPreDriverCalPad0, 8, TxPrePNCmdAddrOr},
    {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCalPad0, BFCmdAddr1TxPreDriverCalPad0, 8, TxPrePNCmdAddrOr},
    // 5. Program TxPreP/TxPreN for Clock according to Table 52 if VDDIO is 1.5V or Table 53 if 1.35V.
    //    A. Program D18F2x9C_x0D0F_2[2:0]02_dct[1:0]={1000b, TxPreP, TxPreN}.
    {BFClkDrvStren, BFClock0TxPreDriverCalPad0, BFClock2TxPreDriverCalPad0, 8, TxPrePNClockOr}
  };

  BIT_FIELD_NAME CurrentBitField;
  UINT16 SpeedMask;
  UINT8 SizeOfTable;
  UINT8 Voltage;
  UINT8 i;
  UINT8 j;
  UINT8 k;
  UINT8 Dct;
  CONST TXPREPN_STRUCT *TblPtr;

  Dct = NBPtr->Dct;
  NBPtr->SwitchDCT (NBPtr, 0);
  // 1. Program D18F2x[1,0]9C_x0D0F_E003[DisAutoComp, DisablePreDriverCal] = {1b, 1b}.
  MemNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 0x6000);
  NBPtr->SwitchDCT (NBPtr, Dct);

  SpeedMask = (UINT16) 1 << (NBPtr->DCTPtr->Timings.Speed / 66);
  Voltage = (UINT8) CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage);

  for (j = 0; j < GET_SIZE_OF (PhyCompInitBitFieldOr); j ++) {
    i = (UINT8) MemNGetBitFieldNb (NBPtr, PhyCompInitBitFieldOr[j].IndexBitField);
    TblPtr = (PhyCompInitBitFieldOr[j].TxPrePN[Voltage]).TxPrePNTblPtr;
    SizeOfTable = (PhyCompInitBitFieldOr[j].TxPrePN[Voltage]).TxPrePNTblSize;

    // Uses different TxPrePNDataDqsOr table for OR B1 and later
    if (((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F15_OR_LT_B1) == 0) &&
        (PhyCompInitBitFieldOr[j].TxPrePN == TxPrePNDataDqsOr)) {
      ASSERT (Voltage < sizeof (TxPrePNDataDqsOrB1) / sizeof (TxPrePNDataDqsOrB1[0]));
      TblPtr = TxPrePNDataDqsOrB1[Voltage].TxPrePNTblPtr;
      SizeOfTable = TxPrePNDataDqsOrB1[Voltage].TxPrePNTblSize;
    }

    for (k = 0; k < SizeOfTable; k++, TblPtr++) {
      if ((TblPtr->Speed & SpeedMask) != 0) {
        for (CurrentBitField = PhyCompInitBitFieldOr[j].StartTargetBitField; CurrentBitField <= PhyCompInitBitFieldOr[j].EndTargetBitField; CurrentBitField ++) {
          MemNSetBitFieldNb (NBPtr, CurrentBitField, ((PhyCompInitBitFieldOr[j].ExtraValue << 12) | TblPtr->TxPrePNVal[i]));
        }
        break;
      }
    }
    // Asserting if no table is found corresponding to current memory speed.
    ASSERT (k < SizeOfTable);
  }
}
コード例 #23
0
ファイル: mnphyor.c プロジェクト: B-Rich/coreboot
VOID
MemNAfterDQSTrainingOr (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 Dct;
  UINT8 Dimm;
  UINT8 Byte;
  UINT16 Dly;
  BOOLEAN DllShutDownEn;

  DllShutDownEn = TRUE;
  IDS_OPTION_HOOK (IDS_DLL_SHUT_DOWN, &DllShutDownEn, &(NBPtr->MemPtr->StdHeader));

  for (Dct = 0; Dct < MAX_DCTS_PER_NODE_OR; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      //
      // 2.10.6.6 DCT Training Specific Configuration
      //
      MemNSetBitFieldNb (NBPtr, BFAddrCmdTriEn, 1);
      MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0);
      if (DllShutDownEn && NBPtr->IsSupported[SetDllShutDown]) {
        MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 0);
      }
      MemNSetBitFieldNb (NBPtr , BFForceAutoPchg, 0);
      MemNSetBitFieldNb (NBPtr , BFDynPageCloseEn, 0);
      if (NBPtr->RefPtr->EnableBankSwizzle) {
        MemNSetBitFieldNb (NBPtr, BFBankSwizzleMode, 1);
      }
      MemNSetBitFieldNb (NBPtr, BFDcqBypassMax, 0x0F);
      MemNPowerDownCtlOr (NBPtr);
      MemNSetBitFieldNb (NBPtr, BFDisSimulRdWr, 0);
      MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2);
      //
      // Post Training values for BFRxMaxDurDllNoLock, BFTxMaxDurDllNoLock,
      //  and BFEnRxPadStandby are handled by Power savings code
      //
      // BFBwCapEn and BFODTSEn are handled by OnDimmThermal Code
      //
      // BFDctSelIntLvEn is programmed by Interleaving feature
      //
      // BFL3Scrub, BFDramScrub, and DramScrubReDirEn are programmed by ECC Feature code
      //
      //
      MemNSetBitFieldNb (NBPtr, BFL3ScrbRedirDis, 0);
      // Doing DataTxFifoWrDly override for NB PState 0
      MemNDataTxFifoWrDlyOverrideOr (NBPtr, NBPtr);
    }
  }

  //
  // Synch RdDqs__Dly to RdDqsDly for S3 Save/Restore
  //
  for (Dct = 0; Dct < MAX_DCTS_PER_NODE_OR; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      if (!(NBPtr->DctCachePtr->Is__x4)) {
        // Only synch when 1D training has been performed or training with x8 DIMMs
        for (Dimm = 0; Dimm < 4; Dimm++) {
          for (Byte = 0; Byte < 9; Byte++) {
            Dly = (UINT16) MemNGetTrainDlyNb (NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS (Dimm, Byte));
            MemNSetTrainDlyNb (NBPtr, AccessRdDqs__Dly, DIMM_NBBL_ACCESS (Dimm, Byte * 2), Dly);
            MemNSetTrainDlyNb (NBPtr, AccessRdDqs__Dly, DIMM_NBBL_ACCESS (Dimm, (Byte * 2) + 1), Dly);
            NBPtr->ChannelPtr->RdDqs__Dlys[(Dimm * MAX_NUMBER_LANES) + (Byte * 2)] = (UINT8) Dly;
            NBPtr->ChannelPtr->RdDqs__Dlys[(Dimm * MAX_NUMBER_LANES) + (Byte * 2) + 1] = (UINT8) Dly;
          }
        }
      }
    }
  }
}