Esempio n. 1
0
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));
}
Esempio n. 2
0
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;
          }
        }
      }
    }
  }
}