/* $NoKeywords:$ */
/**
 * @file
 *
 * mndct.c
 *
 * Common Northbridge DCT support
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project: AGESA
 * @e sub-project: (Mem/NB)
 * @e \$Revision: 48511 $ @e \$Date: 2011-03-09 13:53:13 -0700 (Wed, 09 Mar 2011) $
 *
 **/
/*
 *****************************************************************************
 *
 * Copyright (c) 2011, Advanced Micro Devices, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of 
 *       its contributors may be used to endorse or promote products derived 
 *       from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * ***************************************************************************
 *
 */


/*
 *----------------------------------------------------------------------------
 *                                MODULES USED
 *
 *----------------------------------------------------------------------------
 */



#include "AGESA.h"
#include "amdlib.h"
#include "Ids.h"
#include "mport.h"
#include "mm.h"
#include "mn.h"
#include "mt.h"
#include "mu.h"
#include "mftds.h"
#include "merrhdl.h"
#include "OptionMemory.h"
#include "PlatformMemoryConfiguration.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_MEM_NB_MNDCT_FILECODE
/*----------------------------------------------------------------------------
 *                          DEFINITIONS AND MACROS
 *
 *----------------------------------------------------------------------------
 */
#define UNUSED_CLK 4

/*----------------------------------------------------------------------------
 *                           TYPEDEFS AND STRUCTURES
 *
 *----------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------
 *                        PROTOTYPES OF LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

VOID
STATIC
MemNAfterStitchMemNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

UINT8
MemNGet1KTFawTkNb (
  IN       UINT8 k
  );

UINT8
MemNGet2KTFawTkNb (
  IN       UINT8 k
  );

VOID
STATIC
MemNQuarterMemClk2NClkNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN OUT   UINT16 *SubTotalPtr
  );

/*----------------------------------------------------------------------------
 *                            EXPORTED FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

extern BUILD_OPT_CFG UserOptions;

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function combines all the memory into a contiguous map.
 *      Requires that Mask values for each bank be programmed first and that
 *      the chip-select population indicator is correctly set.
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return          TRUE - An Error value lower than AGESA_FATAL may have occurred
 *     @return          FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred
 */

BOOLEAN
MemNStitchMemoryNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  BOOLEAN DSpareEn;
  UINT32 NxtCSBase;
  UINT32 CurCSBase;
  UINT32 CsSize;
  UINT32 BiggestBank;
  UINT8 p;
  UINT8 q;
  UINT8 BiggestDimm;
  MEM_PARAMETER_STRUCT *RefPtr;
  DIE_STRUCT *MCTPtr;
  DCT_STRUCT *DCTPtr;
  RefPtr = NBPtr->RefPtr;
  MCTPtr = NBPtr->MCTPtr;
  DCTPtr = NBPtr->DCTPtr;
  DSpareEn = FALSE;
  if (NBPtr->IsSupported[SetSpareEn]) {
    DSpareEn = FALSE;
    if (RefPtr->GStatus[GsbEnDIMMSpareNW]) {
      DSpareEn = TRUE;
    }
  }

  DCTPtr->Timings.CsEnabled = 0;
  NxtCSBase = 0;
  for (p = 0; p < MAX_CS_PER_CHANNEL; p++) {
    BiggestBank = 0;
    BiggestDimm = 0;
    for (q = 0; q < MAX_CS_PER_CHANNEL; q++) {
      if (((DCTPtr->Timings.CsPresent & ~DCTPtr->Timings.CsTestFail) & ((UINT16)1 << q)) != 0) {
        if ((MemNGetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + q) & 7) == 0) {
          // (CSEnable|Spare==1)bank is not enabled yet
          CsSize = MemNGetBitFieldNb (NBPtr, BFCSMask0Reg + (q >> 1));
          if (CsSize != 0) {
            CsSize += ((UINT32)1 << 19);
            CsSize &= 0xFFF80000;
          }
          if (CsSize > BiggestBank) {
            BiggestBank = CsSize;
            BiggestDimm = q;
          }
        }
      }
    }

    if (BiggestBank != 0) {
      CurCSBase = NxtCSBase;
      if (NBPtr->IsSupported[CheckSpareEn]) {
        if (DSpareEn) {
          CurCSBase = ((UINT32)1 << BFSpare);
          DSpareEn = FALSE;
        } else {
          CurCSBase |= ((UINT32)1 << BFCSEnable);
          NxtCSBase += BiggestBank;
        }
      } else {
        CurCSBase |= ((UINT32)1 << BFCSEnable);
        NxtCSBase += BiggestBank;
      }
      if ((BiggestDimm & 1) != 0) {
        if (!(MCTPtr->Status[SbLrdimms])) {
          // For LRDIMMS, On Dimm Mirroring is enabled after SDI
          if ((DCTPtr->Timings.DimmMirrorPresent & (1 << (BiggestDimm >> 1))) != 0) {
            CurCSBase |= ((UINT32)1 << BFOnDimmMirror);
          }
        }
      }
      MemNSetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + BiggestDimm, CurCSBase);
      DCTPtr->Timings.CsEnabled |= (1 << BiggestDimm);
    }
    if ((DCTPtr->Timings.CsTestFail & ((UINT16)1 << p)) != 0) {
      IDS_HDT_CONSOLE (MEM_FLOW, "Node %d Dct %d exclude CS %d\n", NBPtr->Node, NBPtr->Dct, p);
      MemNSetBitFieldNb (NBPtr, (BFCSBaseAddr0Reg + p), (UINT32)1 << BFTestFail);
    }
  }

  if (NxtCSBase != 0) {
    DCTPtr->Timings.DctMemSize = NxtCSBase >> 8;    // Scale base address from [39:8] to [47:16]
    MemNAfterStitchMemNb (NBPtr);
  }

  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets platform specific config/timing values from the interface layer and
 *   programs them into DCT.
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return          TRUE - An Error value lower than AGESA_FATAL may have occurred
 *     @return          FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred
 */

BOOLEAN
MemNPlatformSpecNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST BIT_FIELD_NAME ChipletPDRegs[] = {
  BFPhyClkConfig0,
  BFPhyClkConfig3,
  BFPhyClkConfig1,
  BFPhyClkConfig2
  };
  CONST UINT8 ChipletPDClkDisMap[][2] = {
  //F2[1, 0]x9C_x0D0F2030 -> F2x[1, 0]88[MemClkDis[1:0]]
  {0, 1},
  //F2[1, 0]x9C_x0D0F2330 -> F2x[1, 0]88[MemClkDis[7:6]]
  {6, 7},
  //F2x09C_x0D0F2130 -> F2x88[MemClkDis[5:4]]
  {4, 5},
  //F2x09C_x0D0F2230 -> F2x88[MemClkDis[3:2]]
  {2, 3},
  //F2x19C_x0D0F2130 -> F2x188[MemClkDis[5:2]]
  {2, 5},
  //F2x19C_x0D0F2230 -> F2x188[MemClkDis[4:3]]
  {3, 4}
  };

  UINT8 MemClkDis;
  UINT8 i;
  UINT8 MemoryAllClocks;
  UINT8 *MemClkDisMap;
  UINT16 CsPresent;
  UINT8 RegIndex;
  UINT8 Cs1;
  UINT8 Cs2;

  if (!MemNGetPlatformCfgNb (NBPtr)) {
    IDS_ERROR_TRAP;
  }

  if (!NBPtr->PsPtr->MemPDoPs (NBPtr)) {
    IDS_ERROR_TRAP;
  }
  MemNProgramPlatformSpecNb (NBPtr);

  MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ODT, ALL_DIMMS);

  if (NBPtr->MCTPtr->GangedMode) {
    MemNSwitchDCTNb (NBPtr, 1);
    if (!MemNGetPlatformCfgNb (NBPtr)) {
      IDS_ERROR_TRAP;
    }
    MemNProgramPlatformSpecNb (NBPtr);
    MemNSwitchDCTNb (NBPtr, 0);
  }

  //======================================================================
  // Disable unused MemClk to save power
  //======================================================================
  //
  MemClkDis = 0;
  MemoryAllClocks = UserOptions.CfgMemoryAllClocksOn;
  IDS_OPTION_HOOK (IDS_ALL_MEMORY_CLOCK, &MemoryAllClocks, &(NBPtr->MemPtr->StdHeader));
  if (!MemoryAllClocks) {
    // Special Jedec SPD diagnostic bit - "enable all clocks"
    if (!NBPtr->MCTPtr->Status[SbDiagClks]) {
      MemClkDisMap = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MEMCLK_DIS, NBPtr->MCTPtr->SocketId, MemNGetSocketRelativeChannelNb (NBPtr, NBPtr->Dct, 0));
      if (MemClkDisMap == NULL) {
        MemClkDisMap = NBPtr->ChannelPtr->MemClkDisMap;
      }

      // Turn off the unused CS clocks
      CsPresent = NBPtr->DCTPtr->Timings.CsPresent;

      if (NBPtr->IsSupported[CheckMemClkCSPresent]) {
        if (NBPtr->ChannelPtr->RegDimmPresent != 0) {
          // All DDR3 RDIMM use only one MEMCLOCK from edge finger to the register
          // regardless of how many Ranks are on the DIMM (Single, Dual or Quad)
          CsPresent = (CsPresent | (CsPresent >> 1)) & 0x5555;
        }
      }
      for (i = 0; i < 8; i++) {
        if ((CsPresent & MemClkDisMap[i]) == 0) {
          MemClkDis |= (UINT8) (1 << i);
        }
      }
      //Chiplet power down
      for (RegIndex = 0; RegIndex < GET_SIZE_OF (ChipletPDRegs); RegIndex++) {
        if ((NBPtr->Dct == 1) && (RegIndex >= 2)) {
          Cs1 =  MemClkDisMap[ChipletPDClkDisMap[RegIndex + 2][0]];
          Cs2 =  MemClkDisMap[ChipletPDClkDisMap[RegIndex + 2][1]];
        } else {
          Cs1 =  MemClkDisMap[ChipletPDClkDisMap[RegIndex][0]];
          Cs2 =  MemClkDisMap[ChipletPDClkDisMap[RegIndex][1]];
        }
        if ((CsPresent & (UINT16) (Cs1 | Cs2)) == 0) {
          MemNSetBitFieldNb (NBPtr, ChipletPDRegs[RegIndex], (MemNGetBitFieldNb (NBPtr, ChipletPDRegs[RegIndex]) | 0x10));
        }
      }
    }
  }
  MemNSetBitFieldNb (NBPtr, BFMemClkDis, MemClkDis);

  AGESA_TESTPOINT (TPProcMemPhyCompensation, &(NBPtr->MemPtr->StdHeader));
  NBPtr->MemNInitPhyComp (NBPtr);

  MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_SLEWRATE, ALL_DIMMS);

  // Program DramTerm for DDR2
  if ((MemNGetBitFieldNb (NBPtr, BFDdr3Mode)) == 0) {
    MemNSetBitFieldNb (NBPtr, BFDramTerm, NBPtr->PsPtr->DramTerm);
  } else {
    // Dynamic Dynamic DramTerm for DDR3
    // Dram Term for DDR3 may vary based on chip selects
    MemNSetBitFieldNb (NBPtr, BFDramTermDyn, NBPtr->PsPtr->DynamicDramTerm);
  }

  MemFInitTableDrive (NBPtr, MTAfterPlatformSpec);

  return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets platform specific config/timing values from the interface layer and
 *   programs them into DCT.
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return          TRUE - An Error value lower than AGESA_FATAL may have occurred
 *     @return          FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred
 */

BOOLEAN
MemNPlatformSpecUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 MemClkDis;
  UINT8 i;
  UINT8 MemoryAllClocks;
  UINT8 *MemClkDisMap;
  UINT16 CsPresent;

  if (!MemNGetPlatformCfgNb (NBPtr)) {
    IDS_ERROR_TRAP;
  }

  if (!NBPtr->PsPtr->MemPDoPs (NBPtr)) {
    IDS_HDT_CONSOLE (MEM_FLOW, "\tDisable DCT%d due to unsupported DIMM configuration\n", NBPtr->Dct);
    NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader);
    NBPtr->DisableDCT (NBPtr);
  } else {

    MemNProgramPlatformSpecNb (NBPtr);
    MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ODT, ALL_DIMMS);

    //======================================================================
    // Disable unused MemClk to save power
    //======================================================================
    //
    MemClkDis = 0;
    MemoryAllClocks = UserOptions.CfgMemoryAllClocksOn;
    IDS_OPTION_HOOK (IDS_ALL_MEMORY_CLOCK, &MemoryAllClocks, &(NBPtr->MemPtr->StdHeader));
    if (!MemoryAllClocks) {
      // Special Jedec SPD diagnostic bit - "enable all clocks"
      if (!NBPtr->MCTPtr->Status[SbDiagClks]) {
        MemClkDisMap = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MEMCLK_DIS, NBPtr->MCTPtr->SocketId, NBPtr->Dct);
        if (MemClkDisMap == NULL) {
          MemClkDisMap = NBPtr->ChannelPtr->MemClkDisMap;
        }

        // Turn off unused clocks
        CsPresent = NBPtr->DCTPtr->Timings.CsPresent;

        for (i = 0; i < 8; i++) {
          if ((CsPresent & MemClkDisMap[i]) == 0) {
            MemClkDis |= (UINT8) (1 << i);
          }
        }

        // Turn off unused chiplets
        for (i = 0; i < 3; i++) {
          if (((MemClkDis >> (i * 2)) & 0x3) == 0x3) {
            MemNSetBitFieldNb (NBPtr, BFPhyClkConfig0 + i, 0x0010);
          }
        }
      }
    }
    MemNSetBitFieldNb (NBPtr, BFMemClkDis, MemClkDis);
    MemFInitTableDrive (NBPtr, MTAfterPlatformSpec);
  }

  return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function disables the DCT and mem clock
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNDisableDCTNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MemNSetBitFieldNb (NBPtr, BFCKETri, 0x03);
  MemNSetBitFieldNb (NBPtr, BFODTTri, 0x0F);
  MemNSetBitFieldNb (NBPtr, BFChipSelTri, 0xFF);

  // To maximize power savings when DisDramInterface=1b,
  // all of the MemClkDis bits should also be set.
  //
  MemNSetBitFieldNb (NBPtr, BFMemClkDis, 0xFF);
  MemNSetBitFieldNb (NBPtr, BFDisDramInterface, 1);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function disables the DCT and mem clock for client NB
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNDisableDCTClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MemNSetBitFieldNb (NBPtr, BFCKETri, 0x03);
  MemNSetBitFieldNb (NBPtr, BFODTTri, 0x0F);
  MemNSetBitFieldNb (NBPtr, BFChipSelTri, 0xFF);

  //Wait for 24 MEMCLKs
  MemNWaitXMemClksNb (NBPtr, 24);

  // To maximize power savings when DisDramInterface=1b,
  // all of the MemClkDis bits should also be set.
  //
  MemNSetBitFieldNb (NBPtr, BFMemClkDis, 0xFF);

  MemNSetBitFieldNb (NBPtr, BFDramPhyStatusReg, 0x80800000);

  MemNSetBitFieldNb (NBPtr, BFDisDramInterface, 1);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *  This function initializes the DRAM devices on all DCTs at the same time
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNStartupDCTNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  // 1. Ensure F2x[1, 0]9C_x08[DisAutoComp] = 1.
  // 2. BIOS waits 5 us for the disabling of the compensation engine to complete.
  // DisAutoComp is still being set since InitPhyComp

  if (NBPtr->MCTPtr->NodeMemSize != 0) {
    // Init MemClk frequency
    MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 1);


    AGESA_TESTPOINT (TpProcMemBeforeDramInit, &(NBPtr->MemPtr->StdHeader));
    NBPtr->MemNBeforeDramInitNb (NBPtr);
    IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq: %d MHz\n", NBPtr->DCTPtr->Timings.Speed);
    AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader));
    NBPtr->FeatPtr->DramInit (NBPtr->TechPtr);
  }

  // 7. Program F2x[1, 0]9C_x08[DisAutoComp] = 0.
  // 8. BIOS must wait 750 us for the phy compensation engine
  //    to reinitialize.
  // DisAutoComp will be cleared after DramEnabled turns to 1

}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *  This function initializes the DRAM devices on all DCTs at the same time
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNStartupDCTUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 Dct;

  if (NBPtr->MCTPtr->NodeMemSize != 0) {
    // Update NB frequency for startup DDR speed
    NBPtr->ChangeNbFrequency (NBPtr);

    // Program D18F2x[1,0]9C_x0000_000B = 80000000h. #109999.
    MemNBrdcstSetNb (NBPtr, BFDramPhyStatusReg, 0x80000000);

    // Program D18F2x[1,0]9C_x0D0F_E013[PllRegWaitTime] = 0118h. #194060.
    MemNBrdcstSetNb (NBPtr, BFPllRegWaitTime, 0x118);

    // Phy Voltage Level Programming
    MemNPhyVoltageLevelNb (NBPtr);

    // Run frequency change sequence
    MemNBrdcstSetNb (NBPtr, BFPllLockTime, NBPtr->FreqChangeParam->PllLockTimeDefault);
    MemNBrdcstSetNb (NBPtr, BFMemClkFreq, NBPtr->GetMemClkFreqId (NBPtr, NBPtr->DCTPtr->Timings.Speed));
    NBPtr->ProgramNbPsDependentRegs (NBPtr);
    MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 1);
    MemNPollBitFieldNb (NBPtr, BFFreqChgInProg, 0, PCI_ACCESS_TIMEOUT, TRUE);
    NBPtr->FamilySpecificHook[AfterMemClkFreqVal] (NBPtr, &Dct);
    MemNBrdcstSetNb (NBPtr, BFPllLockTime, 0x000F);

    NBPtr->FamilySpecificHook[BeforePhyFenceTraining] (NBPtr, 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);

        // Phy fence programming
        AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader));
        NBPtr->PhyFenceTraining (NBPtr);

        // Phy compensation initialization
        AGESA_TESTPOINT (TPProcMemPhyCompensation, &(NBPtr->MemPtr->StdHeader));
        NBPtr->MemNInitPhyComp (NBPtr);
        MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_SLEWRATE, ALL_DIMMS);
      }
    }

    AGESA_TESTPOINT (TpProcMemBeforeDramInit, &(NBPtr->MemPtr->StdHeader));
    NBPtr->MemNBeforeDramInitNb (NBPtr);

    AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader));
    IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq: %d MHz\n", NBPtr->DCTPtr->Timings.Speed);
    NBPtr->FeatPtr->DramInit (NBPtr->TechPtr);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 * MemNChangeFrequencyHy:
 *
 *  This function change MemClk frequency to the value that is specified by DCTPtr->Timings.Speed
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNChangeFrequencyNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MEM_TECH_BLOCK *TechPtr;
  UINT8 Dct;
  UINT8 ChipSel;
  UINT32 Dummy;

  TechPtr = NBPtr->TechPtr;
  if (NBPtr->IsSupported[CheckDisDllShutdownSR] && !(NBPtr->IsSupported[SetDllShutDown])) {
    // #107421
    MemNBrdcstSetNb (NBPtr, BFDisDllShutdownSR, 1);
  }

  //Program F2x[1,0]90[EnterSelfRefresh]=1.
  //Wait until the hardware resets F2x[1,0]90[EnterSelfRefresh]=0.
  MemNBrdcstSetNb (NBPtr, BFEnterSelfRef, 1);
  MemNPollBitFieldNb (NBPtr, BFEnterSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE);

  //Program F2x9C_x08[DisAutoComp]=1
  MemNSwitchDCTNb (NBPtr, 0);
  MemNSetBitFieldNb (NBPtr, BFDisAutoComp, 1);

  //Program F2x[1, 0]94[MemClkFreqVal] = 0.
  MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 0);

  //Program F2x[1, 0]94[MemClkFreq] to specify the target MEMCLK frequency.
  MemNBrdcstSetNb (NBPtr, BFMemClkFreq, NBPtr->GetMemClkFreqId (NBPtr, NBPtr->DCTPtr->Timings.Speed));

  IDS_OPTION_HOOK (IDS_BEFORE_MEM_FREQ_CHG, NBPtr, &(NBPtr->MemPtr->StdHeader));
  //Program F2x[1, 0]94[MemClkFreqVal] = 1.
  MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 1);

  //Wait until F2x[1, 0]94[FreqChgInProg]=0.
  MemNPollBitFieldNb (NBPtr, BFFreqChgInProg, 0, PCI_ACCESS_TIMEOUT, TRUE);

  if (NBPtr->IsSupported[CheckPhyFenceTraining]) {
    //Perform Phy Fence retraining after frequency changed
    AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader));
    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);
        AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader));
        MemNPhyFenceTrainingNb (NBPtr);
      }
    }
  }

  //Program F2x9C_x08[DisAutoComp]=0
  MemNSwitchDCTNb (NBPtr, 0);
  MemNSetBitFieldNb (NBPtr, BFDisAutoComp, 0);

  //Program F2x[1,0]90[ExitSelfRef]=1 for both DCTs.
  //Wait until the hardware resets F2x[1, 0]90[ExitSelfRef]=0.
  MemNBrdcstSetNb (NBPtr, BFExitSelfRef, 1);
  MemNPollBitFieldNb (NBPtr, BFExitSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE);

  if (NBPtr->MCTPtr->Status[SbRegistered]) {
    for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
      MemNSwitchDCTNb (NBPtr, Dct);
      if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
        TechPtr->FreqChgCtrlWrd (TechPtr);
      }
    }
  }

  //wait for 500 MCLKs after ExitSelfRef, 500*2.5ns=1250ns
  MemNWaitXMemClksNb (NBPtr, 500);

  if (NBPtr->IsSupported[CheckDisDllShutdownSR] && !(NBPtr->IsSupported[SetDllShutDown])) {
    // #107421
    MemNBrdcstSetNb (NBPtr, BFDisDllShutdownSR, 0);
  }

  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) {

      //9.Configure the DCT to send initialization MR commands:
      //  BIOS must reprogram Twr, Tcwl, and Tcl based on the new MEMCLK frequency.
      //  Program F2x[1, 0]7C similar to step #2 in Pass 1 above for the new Dimm values.
      TechPtr->AutoCycTiming (TechPtr);
      if (!MemNPlatformSpecNb (NBPtr)) {
        IDS_ERROR_TRAP;
      }

      for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) {
        if (NBPtr->IsSupported[CheckGetMCTSysAddr]) {
          if (MemNGetMCTSysAddrNb (NBPtr, ChipSel, &Dummy)) {
            // if chip select present
            TechPtr->SendAllMRCmds (TechPtr, ChipSel);
            // NOTE: wait 512 clocks for DLL-relock
            MemUWait10ns (50000, NBPtr->MemPtr);  // wait 500us
          }
        }
        if (NBPtr->IsSupported[CheckSendAllMRCmds]) {
          if (MemNGetMCTSysAddrNb (NBPtr, ChipSel, &Dummy)) {
            // if chip select present
            TechPtr->SendAllMRCmds (TechPtr, ChipSel);
          }
        }
      }
      if ((NBPtr->DCTPtr->Timings.Speed == DDR1600_FREQUENCY) && (NBPtr->IsSupported[CheckDllSpeedUp])) {
        MemNSetBitFieldNb (NBPtr, BFPhy0x0D080F11, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D080F11) | 0x2000));
        MemNSetBitFieldNb (NBPtr, BFPhy0x0D080F10, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D080F10) | 0x2000));
        MemNSetBitFieldNb (NBPtr, BFPhy0x0D088F30, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D088F30) | 0x2000));
        MemNSetBitFieldNb (NBPtr, BFPhy0x0D08C030, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D08C030) | 0x2000));
        if (Dct == 0) {
          MemNSetBitFieldNb (NBPtr, BFPhy0x0D082F30, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D082F30) | 0x2000));
        }
        // NOTE: wait 512 clocks for DLL-relock
        MemUWait10ns (50000, NBPtr->MemPtr);  // wait 500us
      }
    }
  }
  // Re-enable phy compensation since it had been disabled during InitPhyComp
  MemNSwitchDCTNb (NBPtr, 0);
  MemNSetBitFieldNb (NBPtr, BFDisAutoComp, 0);
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function ramp up frequency the next level if it have not reached
 *      its TargetSpeed yet.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return          TRUE -  No fatal error occurs.
 *     @return          FALSE - Fatal error occurs.
 */

BOOLEAN
MemNRampUpFrequencyNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST UINT16 FreqList[] = {
    DDR400_FREQUENCY,
    DDR533_FREQUENCY,
    DDR667_FREQUENCY,
    DDR800_FREQUENCY,
    DDR1066_FREQUENCY,
    DDR1333_FREQUENCY,
    DDR1600_FREQUENCY,
    DDR1866_FREQUENCY
  };
  UINT8 Dct;
  UINT8 i;
  UINT16 NewSpeed;
  DIE_STRUCT *MCTPtr;

  MCTPtr = NBPtr->MCTPtr;

  // Do not change frequency when it is already at TargetSpeed
  if (NBPtr->DCTPtr->Timings.Speed == NBPtr->DCTPtr->Timings.TargetSpeed) {
    return TRUE;
  }

  // Find the next supported frequency level
  NewSpeed = NBPtr->DCTPtr->Timings.TargetSpeed;
  for (i = 0; i < (GET_SIZE_OF (FreqList) - 1); i++) {
    if (NBPtr->DCTPtr->Timings.Speed == FreqList[i]) {
      NewSpeed = FreqList[i + 1];
      break;
    }
  }
  ASSERT (i < (GET_SIZE_OF (FreqList) - 1));
  ASSERT (NewSpeed <= NBPtr->DCTPtr->Timings.TargetSpeed);

  // BIOS must program both DCTs to the same frequency.
  IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq changed: %d MHz", NBPtr->DCTPtr->Timings.Speed);
  for (Dct = 0; Dct < MCTPtr->DctCount; Dct++) {
    NBPtr->SwitchDCT (NBPtr, Dct);
    NBPtr->DCTPtr->Timings.Speed = NewSpeed;
  }
  IDS_HDT_CONSOLE (MEM_FLOW, " -> %d MHz", NewSpeed);

  NBPtr->ChangeFrequency (NBPtr);

  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function uses calculated values from DCT.Timings structure to
 *      program its registers.
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNProgramCycTimingsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST CTENTRY TmgAdjTab[] = {
    // BitField, Min, Max, Bias, Ratio_x2
    {BFTcl, 4, 12, 4, 2},
    {BFTrcd, 5, 12, 5, 2},
    {BFTrp, 5, 12, 5, 2},
    {BFTrtp, 4, 7, 4, 2},
    {BFTras, 15, 30, 15, 2},
    {BFTrc, 11, 42, 11, 2},
    {BFTwrDDR3, 5, 12, 4, 2},
    {BFTrrd, 4, 7, 4, 2},
    {BFTwtr, 4, 7, 4, 2},
    {BFFourActWindow, 16, 32, 14, 1}
  };

  DCT_STRUCT *DCTPtr;
  UINT8  *MiniMaxTmg;
  UINT8  *MiniMaxTrfc;
  UINT8  Value8;
  UINT8  j;
  BIT_FIELD_NAME BitField;

  DCTPtr = NBPtr->DCTPtr;

  //======================================================================
  // Program turnaround timings to their max during DRAM init and training
  //======================================================================
  //
  MemNSetBitFieldNb (NBPtr, BFNonSPD, 0x28FF);

  MemNSetBitFieldNb (NBPtr, BFNonSPDHi, 0x2A);

  //======================================================================
  // Program DRAM Timing values
  //======================================================================
  //
  MiniMaxTmg = &DCTPtr->Timings.CasL;
  for (j = 0; j < GET_SIZE_OF (TmgAdjTab); j++) {
    BitField = TmgAdjTab[j].BitField;

    if (MiniMaxTmg[j] < TmgAdjTab[j].Min) {
      MiniMaxTmg[j] = TmgAdjTab[j].Min;
    } else if (MiniMaxTmg[j] > TmgAdjTab[j].Max) {
      MiniMaxTmg[j] = TmgAdjTab[j].Max;
    }

    Value8 = (UINT8) MiniMaxTmg[j];

    if (BitField == BFTwrDDR3) {
      Value8 = (Value8 == 10) ? 9 : (Value8 >= 11) ? 10 : Value8;
    } else if (BitField == BFTrtp) {
      Value8 = (DCTPtr->Timings.Speed <= DDR1066_FREQUENCY) ? 4 : (DCTPtr->Timings.Speed == DDR1333_FREQUENCY) ? 5 : 6;
    }

    Value8 = Value8 - TmgAdjTab[j].Bias;
    Value8 = (Value8 * TmgAdjTab[j].Ratio_x2) >> 1;

    ASSERT ((BitField == BFTcl ) ? (Value8 <= 8) :
            (BitField == BFTrcd) ? (Value8 <= 7) :
            (BitField == BFTrp ) ? (Value8 <= 7) :
            (BitField == BFTrtp) ? (Value8 <= 3) :
            (BitField == BFTras) ? (Value8 <= 15) :
            (BitField == BFTrc ) ? (Value8 <= 31) :
            (BitField == BFTrrd) ? (Value8 <= 3) :
            (BitField == BFTwtr) ? (Value8 <= 3) :
            (BitField == BFTwrDDR3) ? ((Value8 >= 1) && (Value8 <= 6)) :
            (BitField == BFFourActWindow) ? ((Value8 >= 1) && (Value8 <= 9)) : FALSE);
    MemNSetBitFieldNb (NBPtr, BitField, Value8);
  }

  MiniMaxTrfc = &DCTPtr->Timings.Trfc0;
  for (j = 0; j < 4; j++) {
    ASSERT (MiniMaxTrfc[j] <= 4);
    MemNSetBitFieldNb (NBPtr, BFTrfc0 + j, MiniMaxTrfc[j]);
  }

  MemNSetBitFieldNb (NBPtr, BFTcwl, ((DCTPtr->Timings.Speed >= DDR800_FREQUENCY) ?
                                     (NBPtr->GetMemClkFreqId (NBPtr, DCTPtr->Timings.Speed) - 3) : 0));

  MemNSetBitFieldNb (NBPtr, BFTref, 2);      // 7.8 us

  //======================================================================
  // DRAM MRS Register, set ODT
  //======================================================================
  //
  // DrvImpCtrl: drive impedance control.01b(34 ohm driver; Ron34 = Rzq/7)
  MemNSetBitFieldNb (NBPtr, BFDrvImpCtrl, 1);

  // burst length control
  if (NBPtr->MCTPtr->Status[Sb128bitmode]) {
    MemNSetBitFieldNb (NBPtr, BFBurstCtrl, 2);
  }

  // ASR=1, auto self refresh; SRT=0
  MemNSetBitFieldNb (NBPtr, BFASR, 1);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function uses calculated values from DCT.Timings structure to
 *      program its registers.
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNProgramCycTimingsClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST CTENTRY TmgAdjTab[] = {
    // BitField, Min, Max, Bias, Ratio_x2
    {BFTcl, 5, 14, 4, 2},
    {BFTrcd, 5, 14, 5, 2},
    {BFTrp, 5, 14, 5, 2},
    {BFTrtp, 4, 8, 4, 2},
    {BFTras, 15, 36, 15, 2},
    {BFTrc, 20, 49, 11, 2},
    {BFTwrDDR3, 5, 16, 4, 2},
    {BFTrrd, 4, 8, 4, 2},
    {BFTwtr, 4, 8, 4, 2},
    {BFFourActWindow, 16, 40, 14, 1}
  };

  DCT_STRUCT *DCTPtr;
  UINT8  *MiniMaxTmg;
  UINT8  *MiniMaxTrfc;
  UINT8  Value8;
  UINT8  j;
  UINT8  Tcwl;
  UINT8  Trcd;
  INT32  TCK_ps;
  BIT_FIELD_NAME BitField;

  DCTPtr = NBPtr->DCTPtr;

  //======================================================================
  // Program DRAM Timing values
  //======================================================================
  //
  MiniMaxTmg = &DCTPtr->Timings.CasL;
  for (j = 0; j < GET_SIZE_OF (TmgAdjTab); j++) {
    BitField = TmgAdjTab[j].BitField;

    if (MiniMaxTmg[j] < TmgAdjTab[j].Min) {
      MiniMaxTmg[j] = TmgAdjTab[j].Min;
    } else if (MiniMaxTmg[j] > TmgAdjTab[j].Max) {
      MiniMaxTmg[j] = TmgAdjTab[j].Max;
    }

    Value8 = (UINT8) MiniMaxTmg[j];

    if (BitField == BFTwrDDR3) {
      if (NBPtr->IsSupported[AdjustTwr]) {
        Value8 ++;
      }
      Value8 = (Value8 >= 10) ? (((Value8 + 1) / 2) + 4) : Value8;
    }

    if ((BitField == BFTrc) && NBPtr->IsSupported[AdjustTrc]) {
      Value8 -= 5;
    }

    Value8 = Value8 - TmgAdjTab[j].Bias;
    Value8 = (Value8 * TmgAdjTab[j].Ratio_x2) >> 1;

    ASSERT ((BitField == BFTcl ) ? ((Value8 >= 1) && (Value8 <= 10)) :
            (BitField == BFTrcd) ? (Value8 <= 9) :
            (BitField == BFTrp ) ? (Value8 <= 9) :
            (BitField == BFTrtp) ? (Value8 <= 4) :
            (BitField == BFTras) ? (Value8 <= 21) :
            (BitField == BFTrc ) ? (NBPtr->IsSupported[AdjustTrc] ? ((Value8 >= 4) && (Value8 <= 38)) : ((Value8 >= 9) && (Value8 <= 38))) :
            (BitField == BFTrrd) ? (Value8 <= 4) :
            (BitField == BFTwtr) ? (Value8 <= 4) :
            (BitField == BFTwrDDR3) ? (Value8 <= 7) :
            (BitField == BFFourActWindow) ? ((Value8 >= 1) && (Value8 <= 13)) : FALSE);
    MemNSetBitFieldNb (NBPtr, BitField, Value8);
  }

  MiniMaxTrfc = &DCTPtr->Timings.Trfc0;
  for (j = 0; j < 4; j++) {
    ASSERT (MiniMaxTrfc[j] <= 5);
    MemNSetBitFieldNb (NBPtr, BFTrfc0 + j, MiniMaxTrfc[j]);
  }

  Tcwl = (UINT8) (DCTPtr->Timings.Speed / 133) + 2;
  MemNSetBitFieldNb (NBPtr, BFTcwl, ((Tcwl > 5) ? (Tcwl - 5) : 0));

  MemNSetBitFieldNb (NBPtr, BFTref, 2);      // Tref = 7.8 us

  // Skid buffer can only be programmed once before Dram init
  if (NBPtr->DCTPtr->Timings.Speed == DDR800_FREQUENCY) {
    TCK_ps = 1000500 / DCTPtr->Timings.TargetSpeed;
    Trcd = (UINT8) ((((1000 / 40) * (UINT32)DCTPtr->Timings.DIMMTrcd) + TCK_ps - 1) / TCK_ps);
    MemNSetBitFieldNb (NBPtr, BFDbeSkidBufDis, (Trcd > 10) ? 0 : 1);
  }

  MemNSetBitFieldNb (NBPtr, BFRdOdtTrnOnDly, (DCTPtr->Timings.CasL > Tcwl) ? (DCTPtr->Timings.CasL - Tcwl) : 0);

}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets platform specific settings for the current channel
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return          TRUE - All platform types defined have initialized successfully
 *     @return          FALSE - At least one of the platform types gave not been initialized successfully
 */

BOOLEAN
MemNGetPlatformCfgNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 p;

  for (p = 0; p < MAX_PLATFORM_TYPES; p++) {
    ASSERT (NBPtr->MemPtr->GetPlatformCfg[p] != NULL);
    if (NBPtr->MemPtr->GetPlatformCfg[p] (NBPtr->MemPtr, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr) == AGESA_SUCCESS) {
      break;
    }
  }
  return (p < MAX_PLATFORM_TYPES);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function retrieves the Max latency parameters
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @param[in]  *MinDlyPtr - Pointer to variable to store the Minimum Delay value
 *     @param[in]  *MaxDlyPtr - Pointer to variable to store the Maximum Delay value
 *     @param[in]  *DlyBiasPtr - Pointer to variable to store Delay Bias value
 *     @param[in]  MaxRcvEnDly - Maximum receiver enable delay value
 */

VOID
MemNGetMaxLatParamsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT16 MaxRcvEnDly,
  IN OUT   UINT16 *MinDlyPtr,
  IN OUT   UINT16 *MaxDlyPtr,
  IN OUT   UINT16 *DlyBiasPtr
  )
{
  *MinDlyPtr = (MemNTotalSyncComponentsNb (NBPtr) + (MaxRcvEnDly >> 5)) * 2;
  MemNQuarterMemClk2NClkNb (NBPtr, MinDlyPtr);

  *MaxDlyPtr = 0x3FF;

  *DlyBiasPtr = 4;
  MemNQuarterMemClk2NClkNb (NBPtr, DlyBiasPtr);   // 1 MEMCLK Margin

  *DlyBiasPtr += 1;  // add 1 NCLK
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function  sets the maximum round-trip latency in the system from the processor to the DRAM
 *   devices and back.
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]     MaxRcvEnDly - Maximum receiver enable delay value
 *
 */

VOID
MemNSetMaxLatencyNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT16 MaxRcvEnDly
  )
{
  UINT16 SubTotal;

  AGESA_TESTPOINT (TpProcMemRcvrCalcLatency, &(NBPtr->MemPtr->StdHeader));

  SubTotal = 0xC8;    // init value for MaxRdLat used in training


  if (MaxRcvEnDly != 0xFFFF) {
    // Get all sync components BKDG steps 1-5
    SubTotal = MemNTotalSyncComponentsNb (NBPtr);

    // Add the maximum (worst case) delay value of DqsRcvEnGrossDelay
    // that exists across all DIMMs and byte lanes.
    //
    SubTotal += MaxRcvEnDly >> 5;


    // Add 14.5 to the sub-total. 14.5 represents part of the processor
    // specific constant delay value in the DRAM clock domain.
    //
    SubTotal <<= 1;             // scale 1/2 MemClk to 1/4 MemClk
    SubTotal += 29;             // add 14.5 1/2 MemClk

    // Convert the sub-total (in 1/2 MEMCLKs) to northbridge clocks (NCLKs)
    // as follows (assuming DDR400 and assuming that no P-state or link speed
    // changes have occurred).
    //
    MemNQuarterMemClk2NClkNb (NBPtr, &SubTotal);

    // Add 2 NCLKs to the sub-total. 2 represents part of the processor
    // specific constant value in the northbridge clock domain.
    //
    SubTotal += 2;
  }

  NBPtr->DCTPtr->Timings.MaxRdLat = SubTotal;
  // Program the F2x[1, 0]78[MaxRdLatency] register with the total delay value
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMaxRdLat: %03x\n", SubTotal);
  MemNSetBitFieldNb (NBPtr, BFMaxLatency, SubTotal);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function sends the ZQCL command
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNSendZQCmdNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  // 1.Program MrsAddress[10]=1
  MemNSetBitFieldNb (NBPtr, BFMrsAddress, (UINT32)1 << 10);

  // 2.Set SendZQCmd=1
  MemNSetBitFieldNb (NBPtr, BFSendZQCmd, 1);

  // 3.Wait for SendZQCmd=0
  MemNPollBitFieldNb (NBPtr, BFSendZQCmd, 0, PCI_ACCESS_TIMEOUT, FALSE);

  // 4.Wait 512 MEMCLKs
  MemNWaitXMemClksNb (NBPtr, 512);
}


/*----------------------------------------------------------------------------
 *                              LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function is used to create the DRAM map
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 */

VOID
STATIC
MemNAfterStitchMemNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  if (NBPtr->MCTPtr->GangedMode) {
    NBPtr->MCTPtr->NodeMemSize = NBPtr->DCTPtr->Timings.DctMemSize;
    NBPtr->MCTPtr->NodeSysLimit = NBPtr->MCTPtr->NodeMemSize - 1;
    NBPtr->MCTPtr->DctData[1].Timings.CsPresent = NBPtr->DCTPtr->Timings.CsPresent;
    NBPtr->MCTPtr->DctData[1].Timings.CsEnabled = NBPtr->DCTPtr->Timings.CsEnabled;
    NBPtr->MCTPtr->DctData[1].Timings.DctMemSize = NBPtr->DCTPtr->Timings.DctMemSize;
  } else {
    // In unganged mode, add DCT0 and DCT1 to NodeMemSize
    NBPtr->MCTPtr->NodeMemSize += NBPtr->DCTPtr->Timings.DctMemSize;
    NBPtr->MCTPtr->NodeSysLimit = NBPtr->MCTPtr->NodeMemSize - 1;
  }
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *       This function Return the binary value of tfaw associated with
 *       the index k
 *
 *     @param[in]     k value
 *
 *     @return       F[k], in Binary MHz.
 */

UINT8
MemNGet1KTFawTkNb (
  IN       UINT8 k
  )
{
  CONST UINT8 Tab1KTfawTK[] = {0, 8, 10, 13, 14, 19};
  ASSERT (k <= 5);
  return Tab1KTfawTK[k];
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *       This function Return the binary value of the 2KTFaw associated with
 *       the index k
 *
 *     @param[in]     k value
 *
 *     @return       2KTFaw converted based on k.
 */

UINT8
MemNGet2KTFawTkNb (
  IN       UINT8 k
  )
{
  CONST UINT8 Tab2KTfawTK[] = {0, 10, 14, 17, 18, 24};
  ASSERT (k <= 5);
  return Tab2KTfawTK[k];
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function converts the sub-total (in 1/4 MEMCLKs) to northbridge clocks (NCLKs)
 *      (assuming DDR400 and assuming that no P-state or link speed
 *      changes have occurred).
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in,out]   *SubTotalPtr - pointer to Sub-Total
 */

VOID
STATIC
MemNQuarterMemClk2NClkNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN OUT   UINT16 *SubTotalPtr
  )
{
  UINT32 NBFreq;
  UINT32 MemFreq;

  // Multiply SubTotal by NB COF
  NBFreq = (MemNGetBitFieldNb (NBPtr, BFNbFid) + 4) * 200;
  // Divide SubTotal by 4 times current MemClk frequency
  MemFreq = NBPtr->DCTPtr->Timings.Speed * 4;
  *SubTotalPtr = (UINT16) (((NBFreq * (*SubTotalPtr)) + MemFreq - 1) / MemFreq);  // round up
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the total of sync components for Max Read Latency calculation
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return      Total in 1/2 MEMCLKs
 */

UINT16
MemNTotalSyncComponentsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT16 SubTotal;

  // Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs UINTs.
  SubTotal = (UINT16) MemNGetBitFieldNb (NBPtr, BFTcl) + 1;
  if ((MemNGetBitFieldNb (NBPtr, BFDdr3Mode)) != 0) {
    SubTotal += 3;
  }
  SubTotal *= 2;

  // If registered DIMMs are being used then add 1 MEMCLK to the sub-total.
  if ((MemNGetBitFieldNb (NBPtr, BFUnBuffDimm)) == 0) {
    SubTotal += 2;
  }

  // If (F2x[1, 0]9C_x04[AddrCmdSetup] and F2x[1, 0]9C_x04[CsOdtSetup] and F2x[1, 0]9C_x04[Cke-Setup] = 0) then K = K + 1
  // If (F2x[1, 0]9C_x04[AddrCmdSetup] or F2x[1, 0]9C_x04[CsOdtSetup] or F2x[1, 0]9C_x04[CkeSetup] = 1) then K = K + 2
  if ((MemNGetBitFieldNb (NBPtr, BFAddrTmgControl) & 0x0202020) == 0) {
    SubTotal += 1;
  } else {
    SubTotal += 2;
  }

  // If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs,
  // then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total.
  //
  SubTotal = SubTotal + (8 - (UINT16) MemNGetBitFieldNb (NBPtr, BFRdPtrInit));

  return SubTotal;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function swaps bits for OnDimmMirror support
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNSwapBitsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 ChipSel;
  UINT32 MRSReg;

  ChipSel = (UINT8) MemNGetBitFieldNb (NBPtr, BFMrsChipSel);
  if ((ChipSel & 1) != 0) {
    MRSReg = MemNGetBitFieldNb (NBPtr, BFDramInitRegReg);
    if ((NBPtr->DCTPtr->Timings.DimmMirrorPresent & (1 << (ChipSel >> 1))) != 0) {
      MRSReg = (MRSReg & 0xFFFCFE07) | ((MRSReg&0x100A8) << 1) | ((MRSReg&0x20150) >> 1);
      MemNSetBitFieldNb (NBPtr, BFDramInitRegReg, MRSReg);
    }
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function swaps bits for OnDimmMirror support for Unb
 *
 *     Dimm Mirroring Requires that, during MRS command cycles, the following
 *     bits are swapped by software
 *
 *             A3 -> A4         A7 -> A8
 *             A4 -> A3         BA0 -> BA1
 *             A5 -> A6         BA1 -> BA0
 *             A6 -> A5
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNSwapBitsUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 ChipSel;
  UINT32 MRSBank;
  UINT32 MRSAddr;

  ChipSel = (UINT8) MemNGetBitFieldNb (NBPtr, BFMrsChipSel);
  if ((ChipSel & 1) != 0) {
    if ((NBPtr->DCTPtr->Timings.DimmMirrorPresent & (1 << (ChipSel >> 1))) != 0) {
      MRSBank = MemNGetBitFieldNb (NBPtr, BFMrsBank);
      MRSAddr = MemNGetBitFieldNb (NBPtr, BFMrsAddress);

      IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d MR%d %05x swapped to ->",
                                                                    (ChipSel & 0x7),
                                                                    (MRSBank & 0x7),
                                                                    (MRSAddr & 0x3FFFF));
      //
      // Swap Mrs Bank bits 0 with 1
      MRSBank = (MRSBank & 0x0100) | ((MRSBank & 0x01) << 1) | ((MRSBank & 0x02) >> 1);
      //
      // Swap Mrs Address bits 3 with 4, 5 with 6, and 7 with 8
      MRSAddr = (MRSAddr & 0x03FE07) | ((MRSAddr&0x000A8) << 1) | ((MRSAddr&0x00150) >> 1);
      MemNSetBitFieldNb (NBPtr, BFMrsBank, MRSBank);
      MemNSetBitFieldNb (NBPtr, BFMrsAddress, MRSAddr);
    }
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   Programs Address/command timings, driver strengths, and tri-state fields.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNProgramPlatformSpecNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST UINT8           PinType[3]  = {PSO_CKE_TRI, PSO_ODT_TRI,   PSO_CS_TRI};
  CONST UINT8           TabSize[3]  = {          2,           4,            8};
  CONST BIT_FIELD_NAME  BitField[3] = {   BFCKETri,    BFODTTri, BFChipSelTri};
  UINT8  *TabPtr;
  UINT8  i;
  UINT8  k;
  UINT8  Value;
  //===================================================================
  // Tristate unused CKE, ODT and chip select to save power
  //===================================================================
  //
  TabPtr = NULL;
  for (k = 0; k < sizeof (PinType); k++) {
    if (NBPtr->IsSupported[CheckFindPSOverideWithSocket]) {
      TabPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PinType[k], NBPtr->MCTPtr->SocketId, MemNGetSocketRelativeChannelNb (NBPtr, NBPtr->Dct, 0));
    }
    if (NBPtr->IsSupported[CheckFindPSDct]) {
      TabPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PinType[k], NBPtr->MCTPtr->SocketId, NBPtr->Dct);
    }
    if (TabPtr == NULL) {
      switch (k) {
      case 0:
        TabPtr = NBPtr->ChannelPtr->CKETriMap;
        break;
      case 1:
        TabPtr = NBPtr->ChannelPtr->ODTTriMap;
        break;
      case 2:
        TabPtr = NBPtr->ChannelPtr->ChipSelTriMap;
        break;
      default:
        IDS_ERROR_TRAP;
      }
    }
    ASSERT (TabPtr != NULL);

    Value = 0;
    for (i = 0; i < TabSize[k]; i++) {
      if ((NBPtr->DCTPtr->Timings.CsPresent & TabPtr[i]) == 0) {
        Value |= (UINT8) (1 << i);
      }
    }

    if (k == PSO_CS_TRI) {
      NBPtr->FamilySpecificHook[BeforeSetCsTri] (NBPtr, &Value);
    }

    ASSERT (k < GET_SIZE_OF (BitField));
    MemNSetBitFieldNb (NBPtr, BitField[k], Value);
  }
  NBPtr->MemNBeforePlatformSpecNb (NBPtr);

  //===================================================================
  // Program Address/Command timings and driver strength
  //===================================================================
  //
  MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ADDRTMG, ALL_DIMMS);
  MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ODCCONTROL, ALL_DIMMS);

  MemNSetBitFieldNb (NBPtr, BFSlowAccessMode, (NBPtr->ChannelPtr->SlowMode) ? 1 : 0);
  MemNSetBitFieldNb (NBPtr, BFODCControl, NBPtr->ChannelPtr->DctOdcCtl);
  MemNSetBitFieldNb (NBPtr, BFAddrTmgControl, NBPtr->ChannelPtr->DctAddrTmg);
  NBPtr->FamilySpecificHook[SetDqsODT] (NBPtr, NBPtr);

  if (NBPtr->IsSupported[CheckODTControls]) {
    MemNSetBitFieldNb (NBPtr, BFPhyRODTCSLow, NBPtr->ChannelPtr->PhyRODTCSLow);
    MemNSetBitFieldNb (NBPtr, BFPhyRODTCSHigh, NBPtr->ChannelPtr->PhyRODTCSHigh);
    MemNSetBitFieldNb (NBPtr, BFPhyWODTCSLow, NBPtr->ChannelPtr->PhyWODTCSLow);
    MemNSetBitFieldNb (NBPtr, BFPhyWODTCSHigh, NBPtr->ChannelPtr->PhyWODTCSHigh);
  }
}
/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the Trdrd value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return      Trdrd value
 */

UINT8
MemNGetTrdrdNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  DCT_STRUCT *DCTPtr;
  INT8 Cgdd;

  DCTPtr = NBPtr->DCTPtr;

  // BIOS calculates Trdrd (in MEMCLKs) = CGDD / 2 + 3 clocks and programs F2x[1, 0]8C[Trdrd] with the
  // converted field value. BIOS rounds fractional values down.
  // The Critical Gross Delay Difference (CGDD) for Trdrd on any given byte lane is the largest F2x[1,
  // 0]9C_x[3:0][2B:10][DqsRcvEnGrossDelay] delay of any DIMM minus the F2x[1,
  // 0]9C_x[3:0][2B:10][DqsRcvEnGrossDelay] delay of any other DIMM.

  Cgdd = MemNGetOptimalCGDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly);
  DCTPtr->Timings.Trdrd = (Cgdd / 2) + 3;

  // Transfer clk to reg definition, 2T is 00b, etc.
  DCTPtr->Timings.Trdrd -= 2;
  if (DCTPtr->Timings.Trdrd > 8) {
    DCTPtr->Timings.Trdrd = 8;
  }

  return DCTPtr->Timings.Trdrd;
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the Twrwr value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return      Twrwr value
 */

UINT8
MemNGetTwrwrNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  DCT_STRUCT *DCTPtr;
  INT8 Cgdd;

  DCTPtr = NBPtr->DCTPtr;

  // Twrwr (in MEMCLKs) = CGDD / 2 + 3 clocks and programs F2x[1, 0]8C[Twrwr] with the
  // converted field value. BIOS rounds fractional values down.
  // On any given byte lane, the largest F2x[1, 0]9C_x[3:0][A, 7, 6, 0][2:1]:F2x[1, 0]9C_x[3:0][A, 7, 6,
  // 0]3[WrDatGrossDlyByte] delay of any DIMM minus the F2x[1, 0]9C_x[3:0][A, 7, 6, 0][2:1]:F2x[1,
  // 0]9C_x[3:0][A, 7, 6, 0]3[WrDatGrossDlyByte] delay of any other DIMM is equal to the Critical Gross
  // Delay Difference (CGDD) for Twrwr.

  Cgdd = MemNGetOptimalCGDDNb (NBPtr, AccessWrDatDly, AccessWrDatDly);
  DCTPtr->Timings.Twrwr = (Cgdd / 2) + 3;
  NBPtr->TechPtr->AdjustTwrwr (NBPtr->TechPtr);

  return DCTPtr->Timings.Twrwr;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the Twrrd value. BIOS calculates Twrrd (in MEMCLKs) = CGDD / 2 - LD + 3 clocks and programs
 * F2x[1, 0]8C[Twrrd] with the converted field value. BIOS rounds fractional
 * values down.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return  Value to be programmed to Twrrd field
 *              pDCT->Timings.Twrrd updated
 */

UINT8
MemNGetTwrrdNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  INT8 Cgdd;
  INT8 Ld;
  INT8 Twrrd;
  DCT_STRUCT *DCTPtr;

  DCTPtr = NBPtr->DCTPtr;

  //
  // For DDR3, BIOS calculates the latency difference (Ld) as equal to read CAS latency minus write CAS
  // latency, in MEMCLKs (see F2x[1, 0]88[Tcl] and F2x[1, 0]84[Tcwl]) which can be a negative or positive
  // value.
  // For DDR2, LD is always one clock (For DDR2, Tcwl is always Tcl minus 1).
  //
  Ld = NBPtr->TechPtr->GetLD (NBPtr->TechPtr);

  // On any given byte lane, the largest WrDatGrossDlyByte delay of any DIMM
  // minus the DqsRcvEnGrossDelay delay of any other DIMM is
  // equal to the Critical Gross Delay Difference (CGDD) for Twrrd.
  Cgdd = MemNGetOptimalCGDDNb (NBPtr, AccessWrDatDly, AccessRcvEnDly);
  Twrrd = (Cgdd / 2) - Ld + 3;
  DCTPtr->Timings.Twrrd = (UINT8) ((Twrrd >= 0) ? Twrrd : 0);
  NBPtr->TechPtr->AdjustTwrrd (NBPtr->TechPtr);

  return DCTPtr->Timings.Twrrd;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the TrwtTO value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return  pDCT->Timings.TrwtTO updated
 */

UINT8
MemNGetTrwtTONb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  INT8 Cgdd;
  INT8 Ld;
  INT8 TrwtTO;
  DCT_STRUCT *DCTPtr;

  DCTPtr = NBPtr->DCTPtr;
  //
  // For DDR3, BIOS calculates the latency difference (Ld) as equal to read CAS latency minus write CAS
  // latency, in MEMCLKs (see F2x[1, 0]88[Tcl] and F2x[1, 0]84[Tcwl]) which can be a negative or positive
  // value.
  // For DDR2, LD is always one clock (For DDR2, Tcwl is always Tcl minus 1).
  //
  Ld = NBPtr->TechPtr->GetLD (NBPtr->TechPtr);

  // On any byte lane, the largest DqsRcvEnGrossDelay delay of any DIMM minus
  // the WrDatGrossDlyByte delay of any other DIMM is equal to the Critical Gross
  // Delay Difference (CGDD) for TrwtTO.
  Cgdd = MemNGetOptimalCGDDNb (NBPtr, AccessRcvEnDly, AccessWrDatDly);
  TrwtTO = (Cgdd / 2) + Ld + 3;
  TrwtTO -= 2;
  DCTPtr->Timings.TrwtTO = (UINT8) ((TrwtTO > 1) ? TrwtTO : 1);

  return DCTPtr->Timings.TrwtTO;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the TrwtWB value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return      TrwtWB value
 */
UINT8
MemNGetTrwtWBNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  DCT_STRUCT *DCTPtr;

  DCTPtr = NBPtr->DCTPtr;

  // TrwtWB ensures read-to-write data-bus turnaround.
  // This value should be one more than the programmed TrwtTO.
  return DCTPtr->Timings.TrwtWB = DCTPtr->Timings.TrwtTO;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function converts MemClk frequency in MHz to MemClkFreq value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Speed   - MemClk frequency in MHz
 *
 *     @return      MemClkFreq value
 */
UINT8
MemNGetMemClkFreqIdNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT16 Speed
  )
{
  return (UINT8) ((Speed < DDR800_FREQUENCY) ? ((Speed / 66) - 3) : (Speed / 133));
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function enables swapping interleaved region feature.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]   Base   - Swap interleaved region base [47:27]
 *     @param[in]   Limit   - Swap interleaved region limit [47:27]
 *
 */
VOID
MemNEnableSwapIntlvRgnNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Base,
  IN       UINT32 Limit
  )
{
  UINT32 Size;
  UINT32 SizeOfAlign;

  // Swapped interleaving region must be below 16G
  if (Limit < (1 << (34 - 27))) {
    // Adjust Base and Size to meet :
    // 1. The size of the swapped region must be less than or equal to the alignment of F2x10C[IntLvRegionBase].
    // 2. Entire UMA region is swapped with interleaving region.
    Size = Limit - Base;
    SizeOfAlign = (UINT32) 1 << LibAmdBitScanForward (Base);
    while (SizeOfAlign <= Size) {
      // In case of SizeOfAlign <= Size, UmaBase -= 128MB, SizeOfIntlvrgn += 128MB.
      Base -= 1;
      Size += 1;
      SizeOfAlign = (UINT32) 1 << LibAmdBitScanForward (Base);
    }
    MemNSetBitFieldNb (NBPtr, BFIntLvRgnBaseAddr, Base);
    MemNSetBitFieldNb (NBPtr, BFIntLvRgnLmtAddr, (Limit - 1));
    MemNSetBitFieldNb (NBPtr, BFIntLvRgnSize, Size);
    MemNSetBitFieldNb (NBPtr, BFIntLvRgnSwapEn, 1);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function converts MemClk frequency in MHz to MemClkFreq value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Speed   - MemClk frequency in MHz
 *
 *     @return      MemClkFreq value
 */
UINT8
MemNGetMemClkFreqIdClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT16 Speed
  )
{
  return (UINT8) ((Speed > DDR400_FREQUENCY) ? ((Speed / 33) - 6) : ((Speed == DDR400_FREQUENCY) ? 2 : (Speed / 55)));
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function converts MemClk frequency in MHz to MemClkFreq value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Speed   - MemClk frequency in MHz
 *
 *     @return      MemClkFreq value
 */
UINT8
MemNGetMemClkFreqIdUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT16 Speed
  )
{
  return (UINT8) ((Speed > DDR400_FREQUENCY) ? ((Speed / 33) - 6) : ((Speed == DDR400_FREQUENCY) ? 2 : (Speed / 55)));
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function converts MemClkFreq Id value to MemClk frequency in MHz
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       FreqId   - FreqId from Register
 *
 *     @return          MemClk frequency in MHz
 */
UINT16
MemNGetMemClkFreqUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 FreqId
  )
{
  UINT16 MemClkFreq;
  if (FreqId > 2) {
    MemClkFreq = (FreqId == 14) ? 667 : (300 + ((FreqId - 3) * 33) + (FreqId - 3) / 3);
  } else if (FreqId == 2) {
    MemClkFreq = 200;
  } else {
    MemClkFreq = 50 + (50 * FreqId);
  }
  return MemClkFreq;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *  This function change MemClk frequency to the value that is specified by DCTPtr->Timings.Speed
 *  for client NB.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNChangeFrequencyUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  MEM_TECH_BLOCK *TechPtr;
  UINT8 Dct;
  UINT8 ChipSel;
  UINT32 Dummy;
  BOOLEAN FrequencyChangeSuccess;

  TechPtr = NBPtr->TechPtr;

  MemNBrdcstSetNb (NBPtr, BFDisDllShutdownSR, 1);

  //Program F2x[1,0]90[EnterSelfRefresh]=1.
  //Wait until the hardware resets F2x[1,0]90[EnterSelfRefresh]=0.
  MemNBrdcstSetNb (NBPtr, BFEnterSelfRef, 1);
  MemNPollBitFieldNb (NBPtr, BFEnterSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE);

  if (NBPtr->ChangeNbFrequency (NBPtr)) {
    // Reprogram Twr, Tcwl, and Tcl based on the new MEMCLK frequency.
    for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
      MemNSwitchDCTNb (NBPtr, Dct);
      if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
        TechPtr->AutoCycTiming (TechPtr);
        if (!MemNPlatformSpecUnb (NBPtr)) {
          IDS_ERROR_TRAP;
        }
      }
    }

    // 1. Program PllLockTime to Family-specific value
    MemNBrdcstSetNb (NBPtr, BFPllLockTime, NBPtr->FreqChangeParam->PllLockTimeDefault);

    // 2. Program D18F2x[1,0]94[MemClkFreqVal] = 0.
    MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 0);

    // 3. Program D18F2x[1,0]94[MemClkFreq] to the desired DRAM frequency.
    MemNBrdcstSetNb (NBPtr, BFMemClkFreq, NBPtr->GetMemClkFreqId (NBPtr, NBPtr->DCTPtr->Timings.Speed));

    // 4. Program D18F2x[1,0]F4_x30[DbeGskFifoNumerator] and D18F2x[1,0]F4_x31[DbeGskFifoDenominator].
    // 5. Program D18F2x[1,0]F4_x32[DataTxFifoSchedDlyNegSlot1, DataTxFifoSchedDlySlot1,
    // DataTxFifoSchedDlyNegSlot0, DataTxFifoSchedDlySlot0]. See 2.10.3.2.2.1 [DCT Transmit Fifo Schedule
    // Delay Programming].
    // 6. 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)
    NBPtr->ProgramNbPsDependentRegs (NBPtr);

    NBPtr->FamilySpecificHook[BeforeMemClkFreqVal] (NBPtr, NBPtr);
    IDS_OPTION_HOOK (IDS_BEFORE_MEM_FREQ_CHG, NBPtr, &(NBPtr->MemPtr->StdHeader));
    // 7. Program D18F2x[1,0]94[MemClkFreqVal] = 1.
    MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 1);
    MemNPollBitFieldNb (NBPtr, BFFreqChgInProg, 0, PCI_ACCESS_TIMEOUT, TRUE);
    NBPtr->FamilySpecificHook[AfterMemClkFreqVal] (NBPtr, &Dct);

    // 8. IF (D18F2x[1,0]9C_x0D0F_E00A[CsrPhySrPllPdMode]==0) THEN program
    // D18F2x[1,0]9C_x0D0F_E006[PllLockTime] = 0Fh.
    // (CsrPhySrPllPdMode is kept 0 before training)
    MemNBrdcstSetNb (NBPtr, BFPllLockTime, 0x000F);

    FrequencyChangeSuccess = TRUE;
  } else {
    // If NB frequency cannot be updated, use the current speed as the target speed
    for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
      MemNSwitchDCTNb (NBPtr, Dct);
      NBPtr->DCTPtr->Timings.Speed = NBPtr->TechPtr->PrevSpeed;
      NBPtr->DCTPtr->Timings.TargetSpeed = NBPtr->TechPtr->PrevSpeed;
    }
    FrequencyChangeSuccess = FALSE;
  }

  //Program F2x[1,0]90[ExitSelfRef]=1 for both DCTs.
  //Wait until the hardware resets F2x[1, 0]90[ExitSelfRef]=0.
  MemNBrdcstSetNb (NBPtr, BFExitSelfRef, 1);
  MemNPollBitFieldNb (NBPtr, BFExitSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE);
  MemNBrdcstSetNb (NBPtr, BFDisDllShutdownSR, 0);

  if (FrequencyChangeSuccess) {
    NBPtr->FamilySpecificHook[AfterMemClkFreqChg] (NBPtr, NULL);

    // Perform Phy Fence training and Phy comp init after frequency change
    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);

        // Phy fence programming
        AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader));
        NBPtr->PhyFenceTraining (NBPtr);

        // Phy compensation initialization
        AGESA_TESTPOINT (TPProcMemPhyCompensation, &(NBPtr->MemPtr->StdHeader));
        NBPtr->MemNInitPhyComp (NBPtr);
        MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_SLEWRATE, ALL_DIMMS);
      }
    }

    //======================================================================
    // Calculate and program DRAM Timings at new frequency
    //======================================================================
    //
    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) {
        for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) {
          if (MemNGetMCTSysAddrNb (NBPtr, ChipSel, &Dummy)) {
            // if chip select present
            if (!(TechPtr->TechnologySpecificHook[LrdimmSendAllMRCmds] (TechPtr, &ChipSel))) {
              TechPtr->SendAllMRCmds (TechPtr, ChipSel);
            }
          }
        }
        // Wait 512 clocks for DLL-relock
        MemNWaitXMemClksNb (NBPtr, 512);
      }
    }
  }
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *  This function calculates and programs NB P-state dependent registers
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNProgramNbPstateDependentRegistersUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 RdPtrInit;
  UINT8 Dct;

  RdPtrInit = (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) ? 6 : 5;
  MemNBrdcstSetNb (NBPtr, BFRdPtrInit, RdPtrInit);
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tRdPtr: %d\n", RdPtrInit);

  switch (RdPtrInit) {
  case 4:
    if (MemNGetBitFieldNb (NBPtr, BFNbPsSel) == 0) {
      MemNBrdcstSetNb (NBPtr, BFDataTxFifoWrDly, 2);
    } else {
      MemNBrdcstSetNb (NBPtr, BFDataTxFifoWrDly, 1);
    }
    break;
  case 5:
    MemNBrdcstSetNb (NBPtr, BFDataTxFifoWrDly, 1);
    break;
  case 6:
    MemNBrdcstSetNb (NBPtr, BFDataTxFifoWrDly, 0);
    break;
  default:
    ASSERT (FALSE);
  }

  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      // Set ProcOdtAdv
      if (NBPtr->DCTPtr->Timings.Speed <= DDR1333_FREQUENCY) {
        MemNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0);
      } else {
        MemNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0x4000);
      }
    }
  }

  NBPtr->FamilySpecificHook[OverrideDataTxFifoWrDly] (NBPtr, NBPtr);
  IDS_OPTION_HOOK (IDS_NBPS_REG_OVERRIDE, NBPtr, &NBPtr->MemPtr->StdHeader);
}

/* -----------------------------------------------------------------------------*/
CONST UINT8 PllDivTab[] = {0, 0, 0, 2, 3, 3, 2, 3};
CONST UINT8 PllMultTab[] = {0, 0, 0, 16, 32, 40, 32, 56};

/**
 *
 *  This function calculates and programs NB P-state dependent registers
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNProgramNbPstateDependentRegistersClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 i;
  UINT8 Dct;
  UINT8 NclkFid;
  UINT16 MemClkDid;
  UINT8 PllMult;
  UINT8 NclkDiv;
  UINT8 RdPtrInitMin;
  UINT8 RdPtrInit;
  UINT32 NclkPeriod;
  UINT32 MemClkPeriod;
  INT32 PartialSum2x;
  INT32 PartialSumSlotI2x;
  INT32 RdPtrInitRmdr2x;
  INT32 TDataProp;
  UINT8 NbPstate;
  UINT8 SlowMode;

  NclkFid = (UINT8) (MemNGetBitFieldNb (NBPtr, BFMainPllOpFreqId) + 0x10);  // NclkFid is in 100MHz

  MemClkDid = PllDivTab[NBPtr->DCTPtr->Timings.Speed / 133];
  NBPtr->FamilySpecificHook[OverridePllDiv] (NBPtr, &MemClkDid);
  PllMult = PllMultTab[NBPtr->DCTPtr->Timings.Speed / 133];
  NBPtr->FamilySpecificHook[OverridePllMult] (NBPtr, &PllMult);

  if (NBPtr->NbFreqChgState == 2) {
    MemNSetBitFieldNb (NBPtr, BFNbPsCsrAccSel, 1);
    MemNSetBitFieldNb (NBPtr, BFNbPsDbgEn, 1);
    NclkDiv = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbPs1NclkDiv);
    // Divisors less than 8 are undefined.  Maybe the CPU does not support NB P-states.
    if (NclkDiv < 8) {
      // Set a dummy divisor to prevent divide by zero exception below.
      NclkDiv = 8;
    }
    NbPstate = 1;
  } else {
    NclkDiv = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbPs0NclkDiv);
    NbPstate = 0;
  }
  NclkPeriod = (2500 * NclkDiv) / NclkFid;  // (1,000,000 * 0.25 * NclkDiv) / (NclkFid * 100MHz) = ps
  MemClkPeriod = 1000000 / NBPtr->DCTPtr->Timings.Speed;
  NBPtr->NBClkFreq = ((UINT32) NclkFid * 400) / NclkDiv;

  IDS_HDT_CONSOLE (MEM_FLOW, "\n\tNB P%d  Freq: %dMHz\n", NbPstate, NBPtr->NBClkFreq);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClk Freq: %dMHz\n", NBPtr->DCTPtr->Timings.Speed);
  // 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 = RdPtrInitMin = (NBPtr->DCTPtr->Timings.Speed >= DDR1333_FREQUENCY) ? NBPtr->FreqChangeParam->RdPtrInit667orHigher : NBPtr->FreqChangeParam->RdPtrInitLower667;
  MemNBrdcstSetNb (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].
  MemNBrdcstSetNb (NBPtr, BFDbeGskFifoNumerator, NclkFid * MemClkDid * 16);
  MemNBrdcstSetNb (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 -
  //   CmdSetup - PtrSeparation - 1. (Llano)
  //   PartialSum = ((5 * NclkPeriod) + MemClkPeriod) + 520ps)*MemClkFrequency - tCWL -
  //   CmdSetup - PtrSeparation - 1. (Ontario)
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    MemNSwitchDCTNb (NBPtr, Dct);
    if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
      PartialSum2x = NBPtr->FreqChangeParam->NclkPeriodMul2x * NclkPeriod;
      PartialSum2x += NBPtr->FreqChangeParam->MemClkPeriodMul2x * MemClkPeriod;
      PartialSum2x += 520 * 2;

      // PtrSeparation = ((16 + RdPtrInitMin - D18F2x[1,0]78[RdPtrInit]) MOD 16)/2 + RdPtrInitRmdr
      // If (D18F2x[1,0]94[MemClkFreq] >= 800 MHz)
      // then RdPtrInitRmdr = (((4.5 * MemClkPeriod) - 990ps) MOD MemClkPeriod)/MemClkPeriod
      // else RdPtrInitRmdr = (((4.5 * MemClkPeriod) - 1466ps) MOD MemClkPeriod)/MemClkPeriod
      TDataProp = (NBPtr->DCTPtr->Timings.Speed >= DDR1600_FREQUENCY) ?
                  NBPtr->FreqChangeParam->TDataProp800orHigher : NBPtr->FreqChangeParam->TDataPropLower800;
      RdPtrInitRmdr2x = ((NBPtr->FreqChangeParam->SyncTimeMul4x * MemClkPeriod) / 2) - 2 * (TDataProp + 520);
      RdPtrInitRmdr2x %= MemClkPeriod;
      PartialSum2x -= ((16 + RdPtrInitMin - RdPtrInit) % 16) * MemClkPeriod + RdPtrInitRmdr2x;

      // Convert PartialSum2x to PCLK
      PartialSum2x = (PartialSum2x + MemClkPeriod - 1) / MemClkPeriod;  // round-up here
      PartialSum2x -= 2 * (MemNGetBitFieldNb (NBPtr, BFTcwl) + 5);
      if ((MemNGetBitFieldNb (NBPtr, BFAddrTmgControl) & 0x0202020) == 0) {
        PartialSum2x -= 1;
      } else {
        PartialSum2x -= 2;
      }
      PartialSum2x -= 2;

      // If PartialSumSlotN is positive:
      //   DataTxFifoSchedDlySlotN=CEIL(PartialSumSlotN).
      //   DataTxFifoSchedDlyNegSlotN=0.
      // Else if PartialSumSlotN is negative:
      //   DataTxFifoSchedDlySlotN=ABS(CEIL(PartialSumSlotN*MemClkPeriod/NclkPeriod)).
      //   DataTxFifoSchedDlyNegSlotN=1.
      for (i = 0; i < 2; i++) {
        PartialSumSlotI2x = PartialSum2x;
        SlowMode = (UINT8) MemNGetBitFieldNb (NBPtr, BFSlowAccessMode);
        if ((i == 0) && (SlowMode == 0)) {
          PartialSumSlotI2x += 2;
        }
        if (NBPtr->IsSupported[SchedDlySlot1Extra] && (i == 1) && (SlowMode != 0)) {
          PartialSumSlotI2x -= 2;
        }
        if (PartialSumSlotI2x > 0) {
          MemNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlyNegSlot0 + i, 0);
          MemNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlySlot0 + i, (PartialSumSlotI2x + 1) / 2);
          IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDataTxFifoSchedDlySlot%d: %d\n", i, (PartialSumSlotI2x + 1) / 2);
        } else {
          MemNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlyNegSlot0 + i, 1);
          PartialSumSlotI2x = ((-PartialSumSlotI2x) * MemClkPeriod) / (2 * NclkPeriod);
          MemNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlySlot0 + i, PartialSumSlotI2x);
          IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDataTxFifoSchedDlySlot%d: -%d\n", i, PartialSumSlotI2x);
        }
      }

      // Set ProcOdtAdv
      if (NBPtr->DCTPtr->Timings.Speed <= DDR1333_FREQUENCY) {
        MemNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0);
      } else {
        MemNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0x4000);
      }
    }
  }

  MemFInitTableDrive (NBPtr, MTAfterNbPstateChange);
  if (NBPtr->NbFreqChgState == 2) {
    MemNSetBitFieldNb (NBPtr, BFNbPsDbgEn, 0);
    MemNSetBitFieldNb (NBPtr, BFNbPsCsrAccSel, 0);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets the total of sync components for Max Read Latency calculation
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return      Total in ps
 */

UINT32
MemNTotalSyncComponentsClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT32 P;
  UINT32 T;
  UINT8  RdPtrInitMin;
  UINT8  RdPtrInit;
  UINT32 AddrTmgCtl;
  UINT8  DbeGskMemClkAlignMode;
  UINT32 MemClkPeriod;

  // P = P + ((16 + RdPtrInitMin - D18F2x[1,0]78[RdPtrInit]) MOD 16)
  RdPtrInitMin = (NBPtr->DCTPtr->Timings.Speed >= DDR1333_FREQUENCY) ? NBPtr->FreqChangeParam->RdPtrInit667orHigher : NBPtr->FreqChangeParam->RdPtrInitLower667;
  RdPtrInit = (UINT8) MemNGetBitFieldNb (NBPtr, BFRdPtrInit);
  P = (16 + RdPtrInitMin - RdPtrInit) % 16;

  // IF (AddrCmdSetup != CkeSetup) THEN P = P + 1
  AddrTmgCtl = MemNGetBitFieldNb (NBPtr, BFAddrTmgControl);
  if (((AddrTmgCtl >> 16) & 0x20) != (AddrTmgCtl & 0x20)) {
    P += 1;
  }

  // IF (DbeGskMemClkAlignMode==01b || (DbeGskMemClkAlignMode==00b && !(AddrCmdSetup==CsOdtSetup==CkeSetup)))
  // THEN P = P + 1
  DbeGskMemClkAlignMode = (UINT8) MemNGetBitFieldNb (NBPtr, BFDbeGskMemClkAlignMode);
  if ((DbeGskMemClkAlignMode == 1) || ((DbeGskMemClkAlignMode == 0) &&
      !((((AddrTmgCtl >> 16) & 0x20) == (AddrTmgCtl & 0x20)) && (((AddrTmgCtl >> 8) & 0x20) == (AddrTmgCtl & 0x20))))) {
    P += 1;
  }

  // IF (SlowAccessMode==1) THEN P = P + 2
  if (MemNGetBitFieldNb (NBPtr, BFSlowAccessMode) == 1) {
    P += 2;
  }

  // P = P + 2
  P += 2;
  T = 0;

  // If (AddrCmdSetup==0 && CsOdtSetup==0 && CkeSetup==0)
  // then P = P + 1
  // else P = P + 2
  if ((AddrTmgCtl & 0x0202020) == 0) {
    P += 1;
  } else {
    P += 2;
  }

  // P = P + (2 * (D18F2x[1,0]88[Tcl] clocks - 1))
  P += 2 * (NBPtr->DCTPtr->Timings.CasL - 1);

  // If (DisCutThroughMode==0)
  // then P = P + 3
  // else P = P + 7
  if (MemNGetBitFieldNb (NBPtr, BFDisCutThroughMode) == 0) {
    P += 3;
  } else {
    P += 7;
  }

  MemClkPeriod = 1000000 / NBPtr->DCTPtr->Timings.Speed;
  return (((P * MemClkPeriod + 1) / 2) + T);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function sets up phy power saving for client NB
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNPhyPowerSavingClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  // 4. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]13[DllDisEarlyU] = 1b.
  // 5. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]13[DllDisEarlyL] = 1b.
  // 6. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]13[7:4] = 1010b.
  MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F13Bit0to7, 0xA3);
  // 7. Program D18F2x[1,0]9C_x0D0F_812F[7, 5, 0] = {1b, 1b, 1b} to disable unused PAR and A[17:16] pins.
  MemNSetBitFieldNb (NBPtr, BFAddrCmdTri, MemNGetBitFieldNb (NBPtr, BFAddrCmdTri) | 0xA1);
  // 8. Program D18F2x[1,0]9C_x0D0F_C000[LowPowerDrvStrengthEn] = 1.
  if (!NBPtr->FamilySpecificHook[DisLowPwrDrvStr] (NBPtr, NULL)) {
    MemNSetBitFieldNb (NBPtr, BFLowPowerDrvStrengthEn, 0x100);
  }
  // 9. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]10[EnRxPadStandby]= IF (D18F2x[1,0]94[MemClkFreq] <=
  //    800 MHz) THEN 1 ELSE 0 ENDIF.
  MemNSetBitFieldNb (NBPtr, BFEnRxPadStandby, (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) ? 0x1000 : 0);
  // 10. Program D18F2x[1,0]9C_x0000_000D as follows:
  //    TxMaxDurDllNoLock/RxMaxDurDllNoLock = 7h.
  MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 7);
  MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 7);
  //    TxCPUpdPeriod/RxCPUpdPeriod = 011b.
  MemNSetBitFieldNb (NBPtr, BFTxCPUpdPeriod, 3);
  MemNSetBitFieldNb (NBPtr, BFRxCPUpdPeriod, 3);
  //    TxDLLWakeupTime/RxDLLWakeupTime = 11b.
  MemNSetBitFieldNb (NBPtr, BFTxDLLWakeupTime, 3);
  MemNSetBitFieldNb (NBPtr, BFRxDLLWakeupTime, 3);

  IDS_OPTION_HOOK (IDS_PHY_DLL_STANDBY_CTRL, NBPtr, &NBPtr->MemPtr->StdHeader);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function overrides the ASR and SRT value in MRS command
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNSetASRSRTNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT32 MrsAddress;
  UINT8 Dimm;
  UINT8 *SpdBufferPtr;

  // Look for MR2
  if (NBPtr->GetBitField (NBPtr, BFMrsBank) == 2) {
    MrsAddress = NBPtr->GetBitField (NBPtr, BFMrsAddress);
    // Clear A6(ASR) and A7(SRT)
    MrsAddress &= (UINT32) ~0xC0;
    Dimm = (UINT8) (NBPtr->GetBitField (NBPtr, BFMrsChipSel) >> 1);
    // Make sure we access SPD of the second logical dimm of QR dimm correctly
    if ((Dimm >= 2) && ((NBPtr->ChannelPtr->DimmQrPresent & (UINT8) (1 << Dimm)) != 0)) {
      Dimm -= 2;
    }
    if (NBPtr->TechPtr->GetDimmSpdBuffer (NBPtr->TechPtr, &SpdBufferPtr, Dimm)) {
      // Bit 2 is ASR
      if (SpdBufferPtr[THERMAL_OPT] & 0x4) {
        // when ASR is 1, set SRT to 0
        MrsAddress |= 0x40;
      } else {
        // Set SRT based on bit on of thermal byte
        MrsAddress |= ((SpdBufferPtr[THERMAL_OPT] & 1) << 7);
      }
      NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress);
    }
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function changes NB frequency as below:
 *     NBP0-DDR800 -> NBP0-DDR1066 -> ... -> NBP0-DDRTarget -> NBP1-DDRTarget -> NBP0-DDRTarget
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

BOOLEAN
MemNChangeNbFrequencyNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  BOOLEAN Status;

  Status = FALSE;

  // State machine to change NB frequency and NB Pstate
  switch (NBPtr->NbFreqChgState) {
  case 0:
    // Starting up by not changing NB P state, but only updating NB frequency based on current MemClk frequency
    Status = NBPtr->ChangeNbFrequencyWrap (NBPtr, 0);
    if (NBPtr->DCTPtr->Timings.Speed == NBPtr->DCTPtr->Timings.TargetSpeed) {
      // When MemClk has been ramped up to its max, transition to next state, which changes NBPstate to P1
      NBPtr->NbFreqChgState = 1;
      IDS_OPTION_HOOK (IDS_NB_PSTATE_DIDVID, NBPtr, &(NBPtr->MemPtr->StdHeader));
    }
    break;

  case 1:
    // Clear ForceCasToSlot0 after MaxRdLatency training is completed for NB-P0
    MemNBrdcstSetNb (NBPtr, BFForceCasToSlot0, 0);

    // Next state would be to change NBPstate back to P0
    NBPtr->NbFreqChgState = 2;

    // Update NB freq dependent registers
    NBPtr->ProgramNbPsDependentRegs (NBPtr);

    // Change NB P-State to NBP1 for MaxRdLat training
    if (NBPtr->ChangeNbFrequencyWrap (NBPtr, 1)) {
      // Enable cut through mode for NB P1
      MemNBrdcstSetNb (NBPtr, BFDisCutThroughMode, 0);

      // Return TRUE to repeat MaxRdLat training
      Status = TRUE;

    } else {
      // If transition to NB-P1 fails, transition to exit state machine
      NBPtr->NbFreqChgState = 3;
    }
    break;

  case 2:
    // Clear ForceCasToSlot0 after MaxRdLatency training is completed for NB-P1
    MemNBrdcstSetNb (NBPtr, BFForceCasToSlot0, 0);

    // Change NB P-State back to NBP0
    Status = NBPtr->ChangeNbFrequencyWrap (NBPtr, 0);
    ASSERT (Status);

    // Return FALSE to get out of MaxRdLat training loop
    Status = FALSE;

    // Exit state machine
    NBPtr->NbFreqChgState = 3;
    break;

  default:
    break;
  }

  return Status;
}

/*-----------------------------------------------------------------------------
 *
 *
 *     This function programs registers before phy fence training for CNB
 *
 *     @param[in,out]  *NBPtr     - Pointer to the MEM_NB_BLOCK
 *     @param[in,out]  OptParam   - Optional parameter
 *
 *     @return    TRUE
 * ----------------------------------------------------------------------------
 */
BOOLEAN
MemNBeforePhyFenceTrainingClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN OUT   VOID *OptParam
  )
{
  IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClkAlign=0\n");
  MemNBrdcstSetNb (NBPtr, BFDbeGskMemClkAlignMode, 0);

  IDS_HDT_CONSOLE (MEM_FLOW, "\tEnDramInit = 1 for both DCTs\n");
  MemNBrdcstSetNb (NBPtr, BFEnDramInit, 1);

  return TRUE;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function changes NB frequency foras below:
 *     NBP0-DDR800 -> NBP0-DDR1066 -> ... -> NBP0-DDRTarget -> NBP1-DDRTarget -> NBP2-DDRTarget -> NBP3-DDRTarget -> NBP0-DDRTarget
 *
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

BOOLEAN
MemNChangeNbFrequencyUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  BOOLEAN Status;

  Status = FALSE;

  // State machine to change NB frequency and NB Pstate
  switch (NBPtr->NbFreqChgState) {
  case 0:
    // Starting up by not changing NB P state, but only updating NB frequency based on current MemClk frequency
    Status = NBPtr->ChangeNbFrequencyWrap (NBPtr, 0);
    if (NBPtr->DCTPtr->Timings.Speed == NBPtr->DCTPtr->Timings.TargetSpeed) {
      // When MemClk has been ramped up to its max, transition to next state, which changes NBPstate to P1
      NBPtr->NbFreqChgState = 1;
      IDS_OPTION_HOOK (IDS_NB_PSTATE_DIDVID, NBPtr, &(NBPtr->MemPtr->StdHeader));
    }
    break;

  case 1:
  case 2:
  case 3:
    // Change NB P-State to NBP1 for MaxRdLat training
    if (NBPtr->ChangeNbFrequencyWrap (NBPtr, NBPtr->NbFreqChgState)) {
      NBPtr->ProgramNbPsDependentRegs (NBPtr);

      // Next state is to try all NBPstates
      NBPtr->NbFreqChgState++;

      // Return TRUE to repeat MaxRdLat training
      Status = TRUE;
    } else {
      // If transition to any NBPs fails, transition to exit state machine
      NBPtr->NbFreqChgState = 4;
    }
    break;

  case 4:
    // Change NB P-State back to NBP0
    Status = NBPtr->ChangeNbFrequencyWrap (NBPtr, 0);
    ASSERT (Status);

    // Return FALSE to get out of MaxRdLat training loop
    Status = FALSE;

    // Exit state machine
    NBPtr->NbFreqChgState = 5;
    break;

  default:
    break;
  }

  return Status;
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets "Dram Term" value from data structure
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       ChipSel  - Targeted chipsel
 *
 *     @return       Dram Term value
 */
UINT8
MemNGetDramTermNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 ChipSel
  )
{
  UINT8 DramTerm;

  if ((NBPtr->ChannelPtr->DimmQrPresent & ((UINT16) (1 << (ChipSel >> 1)))) != 0) {
    DramTerm = NBPtr->PsPtr->QR_DramTerm;
  } else {
    DramTerm = NBPtr->PsPtr->DramTerm;
  }

  return DramTerm;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function gets "Dynamic Dram Term" value from data structure
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       ChipSel  - Targeted chipsel
 *
 *     @return       Dynamic Dram Term value
 */
UINT8
MemNGetDynDramTermNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 ChipSel
  )
{
  return (NBPtr->PsPtr->DynamicDramTerm);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function returns MR0[CL] value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return       MR0[CL] value
 */
UINT32
MemNGetMR0CLNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT8 Tcl;
  UINT32 Value32;

  Tcl = (UINT8) MemNGetBitFieldNb (NBPtr, BFTcl);
  Value32 = (UINT32) ((Tcl < 8) ? (Tcl << 4) : (((Tcl - 8) << 4) | 4));

  return Value32;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function returns MR0[WR] value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return       MR0[WR] value
 */
UINT32
MemNGetMR0WRNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT32 Value32;

  Value32 = MemNGetBitFieldNb (NBPtr, BFTwrDDR3) << 9;

  return Value32;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function returns MR2[CWL] value
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return       MR0[CWL] value
 */
UINT32
MemNGetMR2CWLNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT32 Value32;

  Value32 = MemNGetBitFieldNb (NBPtr, BFTcwl) << 3;

  return Value32;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *   This function sets Txp and Txpdll
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return       none
 */
VOID
MemNSetTxpNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  CONST UINT8 Txp[] = {0xFF, 0xFF, 3, 3, 4, 4, 5, 6, 7};
  CONST UINT8 Txpdll[] = {0xFF, 0xFF, 0xA, 0xA, 0xD, 0x10, 0x14, 0x17, 0x1A};
  UINT8 i;
  UINT8 TxpVal;
  UINT8 TxpdllVal;
  UINT16 Speed;

  Speed = NBPtr->DCTPtr->Timings.Speed;
  i = (UINT8) ((Speed < DDR800_FREQUENCY) ? ((Speed / 66) - 3) : (Speed / 133));
  ASSERT (i < sizeof (Txp));
  ASSERT (i < sizeof (Txpdll));

  TxpdllVal = Txpdll[i];

  if ((NBPtr->MCTPtr->Status[SbLrdimms] || NBPtr->MCTPtr->Status[SbRegistered]) &&
      ((NBPtr->DCTPtr->Timings.Speed == DDR667_FREQUENCY) || (NBPtr->DCTPtr->Timings.Speed == DDR800_FREQUENCY)) &&
      (NBPtr->RefPtr->DDR3Voltage == VOLT1_25)) {
    TxpVal = 4;
  } else {
    TxpVal = Txp[i];
  }

  if (TxpVal != 0xFF) {
    MemNSetBitFieldNb (NBPtr, BFTxp, TxpVal);
  }
  if (TxpdllVal != 0xFF) {
    NBPtr->FamilySpecificHook[AdjustTxpdll] (NBPtr, &TxpdllVal);
    MemNSetBitFieldNb (NBPtr, BFTxpdll, TxpdllVal);
  }
}

/*-----------------------------------------------------------------------------
 *
 *
 *     This function adjust value of Txpdll to encoded value.
 *
 *     @param[in,out]  *NBPtr     - Pointer to the MEM_NB_BLOCK
 *     @param[in,out]  OptParam   - Optional parameter
 *
 *     @return    TRUE
 * ----------------------------------------------------------------------------
 */
BOOLEAN
MemNAdjustTxpdllClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN OUT   VOID *OptParam
  )
{
  *(UINT8 *) OptParam -= 10;
  return TRUE;
}
