/* $NoKeywords:$ */
/**
 * @file
 *
 * AMD Family_12 specific utility functions.
 *
 * Provides numerous utility functions specific to family 12h.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:      AGESA
 * @e sub-project:  CPU/FAMILY/0x12
 * @e \$Revision: 49553 $   @e \$Date: 2011-03-25 08:55:17 +0800 (Fri, 25 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.
 ******************************************************************************
 */

/*----------------------------------------------------------------------------------------
 *                             M O D U L E S    U S E D
 *----------------------------------------------------------------------------------------
 */
#include "AGESA.h"
#include "amdlib.h"
#include "Ids.h"
#include "cpuRegisters.h"
#include "cpuServices.h"
#include "cpuFamilyTranslation.h"
#include "cpuCommonF12Utilities.h"
#include "cpuF12PowerMgmt.h"
#include "OptionFamily12hEarlySample.h"
#include "NbSmuLib.h"
#include "GnbRegistersLN.h"
#include "F12PackageType.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_CPU_FAMILY_0X12_CPUCOMMONF12UTILITIES_FILECODE

/*----------------------------------------------------------------------------------------
 *                   D E F I N I T I O N S    A N D    M A C R O S
 *----------------------------------------------------------------------------------------
 */
extern F12_ES_CORE_SUPPORT F12EarlySampleCoreSupport;
#define F12_DDR1333_ENCODED_MEMCLK (0xE)

/*----------------------------------------------------------------------------------------
 *                  T Y P E D E F S     A N D     S T R U C T U R E S
 *----------------------------------------------------------------------------------------
 */
CONST UINT16 ROMDATA F12MaxNbFreqAtMinVidFreqTable[] =
{
  25,         // 00000b
  50,         // 00001b
  100,        // 00010b
  150,        // 00011b
  167,        // 00100b
  183,        // 00101b
  200,        // 00110b
  217,        // 00111b
  233,        // 01000b
  250,        // 01001b
  267,        // 01010b
  283,        // 01011b
  300,        // 01100b
  317,        // 01101b
  333,        // 01110b
  350,        // 01111b
  366,        // 10000b
  383,        // 10001b
  400,        // 10010b
  417,        // 10011b
  433,        // 10100b
  450,        // 10101b
  467,        // 10110b
  483,        // 10111b
  500,        // 11000b
  517,        // 11001b
  533,        // 11010b
  550,        // 11011b
  563,        // 11100b
  575,        // 11101b
  588,        // 11110b
  600         // 11111b
};

/*----------------------------------------------------------------------------------------
 *           P R O T O T Y P E S     O F     L O C A L     F U N C T I O N S
 *----------------------------------------------------------------------------------------
 */
UINT32
STATIC
RoundedDivision (
  IN       UINT32 Dividend,
  IN       UINT32 Divisor
  );

UINT32
F12GetApCoreNumber (
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  );

CORE_ID_POSITION
F12CpuAmdCoreIdPositionInInitialApicId (
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  );

/*----------------------------------------------------------------------------------------
 *                          E X P O R T E D    F U N C T I O N S
 *----------------------------------------------------------------------------------------
 */

/*---------------------------------------------------------------------------------------*/
/**
 *  Set warm reset status and count
 *
 *  @CpuServiceMethod{::F_CPU_SET_WARM_RESET_FLAG}.
 *
 *  This function will use bit9, and bit 10 of register F0x6C as a warm reset status and count.
 *
 *  @param[in]  FamilySpecificServices   The current Family Specific Services.
 *  @param[in]  StdHeader                Handle of Header for calling lib functions and services.
 *  @param[in]  Request                  Indicate warm reset status
 *
 */
VOID
F12SetAgesaWarmResetFlag (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS *StdHeader,
  IN       WARM_RESET_REQUEST *Request
  )
{
  PCI_ADDR  PciAddress;
  UINT32    PciData;

  PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_0, HT_INIT_CTRL);
  LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);

  // bit[5] - indicate a warm reset is or is not required
  PciData &= ~(HT_INIT_BIOS_RST_DET_0);
  PciData = PciData | (Request->RequestBit << 5);

  // bit[10,9] - indicate warm reset status and count
  PciData &= ~(HT_INIT_BIOS_RST_DET_1 | HT_INIT_BIOS_RST_DET_2);
  PciData |= Request->StateBits << 9;

  LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader);
}

/*---------------------------------------------------------------------------------------*/
/**
 *  Get warm reset status and count
 *
 *  @CpuServiceMethod{::F_CPU_GET_WARM_RESET_FLAG}.
 *
 *  This function will bit9, and bit 10 of register F0x6C as a warm reset status and count.
 *
 *  @param[in]   FamilySpecificServices   The current Family Specific Services.
 *  @param[in]   StdHeader                Config handle for library and services
 *  @param[out]  Request                  Indicate warm reset status
 *
 */
VOID
F12GetAgesaWarmResetFlag (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS *StdHeader,
     OUT   WARM_RESET_REQUEST *Request
  )
{
  PCI_ADDR  PciAddress;
  UINT32    PciData;

  PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_0, HT_INIT_CTRL);
  LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);

  // bit[5] - indicate a warm reset is or is not required
  Request->RequestBit = (UINT8) ((PciData & HT_INIT_BIOS_RST_DET_0) >> 5);
  // bit[10,9] - indicate warm reset status and count
  Request->StateBits = (UINT8) ((PciData & (HT_INIT_BIOS_RST_DET_1 | HT_INIT_BIOS_RST_DET_2)) >> 9);
}

/*---------------------------------------------------------------------------------------*/
/**
 *  Use the Mailbox Register to get the Ap Mailbox info for the current core.
 *
 *  @CpuServiceMethod{::F_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE}.
 *
 *  Access the mailbox register used with this NB family.  This is valid until the
 *  point that some init code initializes the mailbox register for its normal use.
 *
 *  @param[in]     FamilySpecificServices  The current Family Specific Services.
 *  @param[out]    ApMailboxInfo           The AP Mailbox info
 *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
 *
 */
VOID
F12GetApMailboxFromHardware (
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
     OUT   AP_MAILBOXES           *ApMailboxInfo,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  // For Family 12h, we will return socket 0, node 0, module 0, module type 0, and 0 for
  // the system degree
  ApMailboxInfo->ApMailInfo.Info = (UINT32) 0x00000000;
  ApMailboxInfo->ApMailExtInfo.Info = (UINT32) 0x00000000;
}


/*---------------------------------------------------------------------------------------*/
/**
 *  Get this AP's system core number from hardware.
 *
 *  @CpuServiceMethod{::F_CPU_GET_AP_CORE_NUMBER}.
 *
 *  Returns the system core number.  For family 12h, this is simply the
 *  initial APIC ID.
 *
 *  @param[in]     FamilySpecificServices  The current Family Specific Services.
 *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
 *
 *  @return        The AP's unique core number
 */
UINT32
F12GetApCoreNumber (
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  CPUID_DATA Cpuid;

  LibAmdCpuidRead (0x1, &Cpuid, StdHeader);
  return ((Cpuid.EBX_Reg >> 24) & 0xFF);
}


/*---------------------------------------------------------------------------------------*/
/**
 * Return a number zero or one, based on the Core ID position in the initial APIC Id.
 *
 * @CpuServiceMethod{::F_CORE_ID_POSITION_IN_INITIAL_APIC_ID}.
 *
 * @param[in]     FamilySpecificServices  The current Family Specific Services.
 * @param[in]     StdHeader               Handle of Header for calling lib functions and services.
 *
 * @retval        CoreIdPositionZero      Core Id is not low
 * @retval        CoreIdPositionOne       Core Id is low
 */
CORE_ID_POSITION
F12CpuAmdCoreIdPositionInInitialApicId (
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  return (CoreIdPositionOne);
}

/*---------------------------------------------------------------------------------------*/
/**
 * Sets up a valid set of NB P-states based on the value of MEMCLK, transitions
 * to the desired NB P-state, and returns the current NB frequency in megahertz.
 *
 * @param[in]     TargetMemclk            The target MEMCLK in megahertz, or zero to
 *                                        indicate NB P-state change only.
 * @param[in]     TargetMemclkEncoded     The target MEMCLK's register encoding.
 * @param[in]     TargetNbPstate          The NB P-state to exit in.
 * @param[out]    CurrentNbFreq           Current NB operating frequency in megahertz.
 * @param[in]     StdHeader               Handle of Header for calling lib functions and services.
 *
 * @retval        TRUE                    Transition to TargetNbPstate was successful.
 * @retval        FALSE                   Transition to TargetNbPstate was unsuccessful.
 */
BOOLEAN
F12NbPstateInit (
  IN       UINT32             TargetMemclk,
  IN       UINT32             TargetMemclkEncoded,
  IN       UINT32             TargetNbPstate,
     OUT   UINT32             *CurrentNbFreq,
  IN       AMD_CONFIG_PARAMS  *StdHeader
  )
{
  UINT32                EncodedNbPs1Vid;
  UINT32                EncodedNbPs0NclkDiv;
  UINT32                EncodedNbPs1NclkDiv;
  UINT32                NbP0Cof;
  UINT32                NbP1Cof;
  UINT32                NbPstateNumerator;
  UINT32                TargetNumerator;
  UINT32                TargetDenominator;
  UINT32                PkgType;
  BOOLEAN               ReturnStatus;
  BOOLEAN               WaitForTransition;
  BOOLEAN               EnableAltVddNb;
  PCI_ADDR              PciAddress;
  D18F3xD4_STRUCT       Cptc0;
  D18F3xDC_STRUCT       Cptc2;
  D18F6x90_STRUCT       NbPsCfgLow;
  D18F6x98_STRUCT       NbPsCtrlSts;
  FCRxFE00_6000_STRUCT  FCRxFE00_6000;
  FCRxFE00_6002_STRUCT  FCRxFE00_6002;
  FCRxFE00_7006_STRUCT  FCRxFE00_7006;
  FCRxFE00_7009_STRUCT  FCRxFE00_7009;
  FCRxFE00_705F_STRUCT  FCRxFE00_705F;

  // F12 only supports NB P0 and NB P1
  ASSERT (TargetNbPstate < 2);

  WaitForTransition = FALSE;
  ReturnStatus = TRUE;
  EnableAltVddNb = FALSE;

  // Get D18F3xD4[MainPllOpFreqId] frequency
  PciAddress.AddressValue = CPTC0_PCI_ADDR;
  LibAmdPciRead (AccessWidth32, PciAddress, &Cptc0.Value, StdHeader);

  // Calculate the numerator to be used for NB P-state calculations
  NbPstateNumerator = (UINT32) (4 * ((Cptc0.Field.MainPllOpFreqId + 0x10) * 100));

  if (TargetMemclk != 0) {
    // Determine the appropriate numerator / denominator of the target memclk
    switch (TargetMemclk) {
    case DDR800_FREQUENCY:
      TargetNumerator = 400;
      TargetDenominator = 1;
      break;
    case DDR1066_FREQUENCY:
      TargetNumerator = 1600;
      TargetDenominator = 3;
      break;
    case DDR1333_FREQUENCY:
      TargetNumerator = 2000;
      TargetDenominator = 3;
      break;
    case DDR1600_FREQUENCY:
      TargetNumerator = 800;
      TargetDenominator = 1;
      break;
    case DDR1866_FREQUENCY:
      TargetNumerator = 2800;
      TargetDenominator = 3;
      break;
    default:
      // An invalid memclk has been passed in.
      ASSERT (FALSE);
      TargetNumerator = TargetMemclk;
      TargetDenominator = 1;
      break;
    }

    FCRxFE00_6000.Value = NbSmuReadEfuse (FCRxFE00_6000_ADDRESS, StdHeader);
    FCRxFE00_6002.Value = NbSmuReadEfuse (FCRxFE00_6002_ADDRESS, StdHeader);
    FCRxFE00_7006.Value = NbSmuReadEfuse (FCRxFE00_7006_ADDRESS, StdHeader);
    FCRxFE00_7009.Value = NbSmuReadEfuse (FCRxFE00_7009_ADDRESS, StdHeader);

    F12EarlySampleCoreSupport.F12NbPstateInitHook (&FCRxFE00_6000,
                                                   &FCRxFE00_6002,
                                                   &FCRxFE00_7006,
                                                   &FCRxFE00_7009,
                                                   NbPstateNumerator,
                                                   StdHeader);

    // Determine NB P0 settings
    if ((TargetNumerator * FCRxFE00_7009.Field.NbPs0NclkDiv) < (NbPstateNumerator * TargetDenominator)) {
      // Program D18F3xDC[NbPs0NclkDiv] to the minimum divisor where
      // (target memclk frequency >= (D18F3xD4[MainPllOpFreqId] freq) / divisor)
      EncodedNbPs0NclkDiv = ((NbPstateNumerator * TargetDenominator) / TargetNumerator);
      if (((NbPstateNumerator * TargetDenominator) % TargetNumerator) != 0) {
        EncodedNbPs0NclkDiv++;
      }
      // Ensure that the encoded divisor is even to give 50% duty cycle
      EncodedNbPs0NclkDiv = ((EncodedNbPs0NclkDiv + 1) & 0xFFFFFFFE);

      ASSERT (EncodedNbPs0NclkDiv >= 8);
      ASSERT (EncodedNbPs0NclkDiv <= 0x3F);
    } else {
      EncodedNbPs0NclkDiv = FCRxFE00_7009.Field.NbPs0NclkDiv;
    }

    // Check to see if the DIMMs are too fast for the CPU (NB P0 COF < (Memclk / 2))
    if ((TargetNumerator * EncodedNbPs0NclkDiv) > (NbPstateNumerator * TargetDenominator * 2)) {
      // Indicate the error to the memory code so the DIMMs can be derated.
      ReturnStatus = FALSE;
    }

    // Apply the appropriate P0 frequency
    PciAddress.AddressValue = CPTC2_PCI_ADDR;
    LibAmdPciRead (AccessWidth32, PciAddress, &Cptc2.Value, StdHeader);
    if (Cptc2.Field.NbPs0NclkDiv != EncodedNbPs0NclkDiv) {
      WaitForTransition = TRUE;
      Cptc2.Field.NbPs0NclkDiv = EncodedNbPs0NclkDiv;
      LibAmdPciWrite (AccessWidth32, PciAddress, &Cptc2.Value, StdHeader);
    }
    NbP0Cof = RoundedDivision (NbPstateNumerator, EncodedNbPs0NclkDiv);

    // Determine NB P1 settings if necessary
    PciAddress.AddressValue = NB_PSTATE_CFG_LOW_PCI_ADDR;
    LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCfgLow.Value, StdHeader);
    if (NbPsCfgLow.Field.NbPsCap == 1) {
      if ((TargetNumerator * FCRxFE00_7006.Field.NbPs1NclkDiv) > (NbPstateNumerator * TargetDenominator * 2)) {
        // Program D18F6x90[NbPs1NclkDiv] to the maximum divisor where
        // (target memclk frequency / 2 <= (D18F3xD4[MainPllOpFreqId] freq) / divisor)
        EncodedNbPs1NclkDiv = ((NbPstateNumerator * TargetDenominator * 2) / TargetNumerator);

        // Ensure that the encoded divisor is even to give 50% duty cycle
        EncodedNbPs1NclkDiv &= 0xFFFFFFFE;
        ASSERT (EncodedNbPs1NclkDiv >= 8);
        ASSERT (EncodedNbPs1NclkDiv <= 0x3F);

        // Calculate the new effective P1 frequency to determine the voltage
        NbP1Cof = RoundedDivision (NbPstateNumerator, EncodedNbPs1NclkDiv);

        if (NbP1Cof <= F12MaxNbFreqAtMinVidFreqTable[FCRxFE00_7006.Field.MaxNbFreqAtMinVid]) {
          // Program D18F6x90[NbPs1Vid] = FCRxFE00_6002[NbPs1VidAddl]
          EncodedNbPs1Vid = FCRxFE00_6002.Field.NbPs1VidAddl;
        } else {
          // Program D18F6x90[NbPs1Vid] = FCRxFE00_6002[NbPs1VidHigh]
          EncodedNbPs1Vid = FCRxFE00_6002.Field.NbPs1VidHigh;
        }
      } else {
        // Fused frequency and voltage are legal
        EncodedNbPs1Vid = FCRxFE00_6000.Field.NbPs1Vid;
        EncodedNbPs1NclkDiv = FCRxFE00_7006.Field.NbPs1NclkDiv;
        NbP1Cof = RoundedDivision (NbPstateNumerator, EncodedNbPs1NclkDiv);
      }

      if (NbP0Cof < NbP1Cof) {
        // NB P1 frequency is faster than NB P0.  Fix it up by slowing
        // P1 to match P0.
        EncodedNbPs1NclkDiv  = EncodedNbPs0NclkDiv;
        NbP1Cof = NbP0Cof;
      }

      // Program the new NB P1 settings
      NbPsCfgLow.Field.NbPs1NclkDiv = EncodedNbPs1NclkDiv;
      NbPsCfgLow.Field.NbPs1Vid = EncodedNbPs1Vid;
      LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCfgLow.Value, StdHeader);
    } else {
      // NB P-states are not enabled
      NbP1Cof = 0;
    }
    *CurrentNbFreq = NbP0Cof;
    if (WaitForTransition) {
      // Ensure that the frequency has settled before returning to memory code.
      PciAddress.AddressValue = CPTC2_PCI_ADDR;
      do {
        LibAmdPciRead (AccessWidth32, PciAddress, &Cptc2.Value, StdHeader);
      } while (Cptc2.Field.NclkFreqDone != 1);
    }
  } else {
    // Get NB P0 COF
    PciAddress.AddressValue = CPTC2_PCI_ADDR;
    LibAmdPciRead (AccessWidth32, PciAddress, &Cptc2.Value, StdHeader);
    NbP0Cof = RoundedDivision (NbPstateNumerator, Cptc2.Field.NbPs0NclkDiv);

    // Read NB P-state status
    PciAddress.AddressValue = NB_PSTATE_CTRL_STS_PCI_ADDR;
    LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlSts.Value, StdHeader);

    FCRxFE00_705F.Value = NbSmuReadEfuse (FCRxFE00_705F_ADDRESS, StdHeader);
    if (FCRxFE00_705F.Field.GnbIdleAdjustVid != 0) {
      PkgType = LibAmdGetPackageType (StdHeader);
      if ((PkgType == PACKAGE_TYPE_FP1) || ((PkgType == PACKAGE_TYPE_FS1) && (TargetMemclkEncoded <= F12_DDR1333_ENCODED_MEMCLK))) {
        EnableAltVddNb = TRUE;
      }
    }

    // Read low config register
    PciAddress.AddressValue = NB_PSTATE_CFG_LOW_PCI_ADDR;
    LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCfgLow.Value, StdHeader);
    if (TargetNbPstate == 1) {
      // If target is P1, the CPU MUST be in P0, otherwise the P1 settings
      // cannot be realized.  This is a programming error.
      ASSERT (NbPsCtrlSts.Field.NbPs1Act == 0);

      if (NbPsCfgLow.Field.NbPsCap == 1) {
        // The part is capable of NB P-states.  Transition to P1.
        if (EnableAltVddNb) {
          NbPsCfgLow.Field.NbPs1Vid += FCRxFE00_705F.Field.GnbIdleAdjustVid;
          LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCfgLow.Value, StdHeader);
        }

        NbPsCfgLow.Field.NbPsForceSel = 1;
        LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCfgLow.Value, StdHeader);

        WaitForTransition = TRUE;
        *CurrentNbFreq = RoundedDivision (NbPstateNumerator, NbPsCfgLow.Field.NbPs1NclkDiv);
      } else {
        // No NB P-states.  Return FALSE, and set current frequency to P0.
        *CurrentNbFreq = NbP0Cof;
        ReturnStatus = FALSE;
      }
    } else {
      // Target P0
      *CurrentNbFreq = NbP0Cof;
      if (NbPsCtrlSts.Field.NbPs1Act != 0) {
        // Request transition to P0
        if (EnableAltVddNb) {
          NbPsCfgLow.Field.NbPs1Vid -= FCRxFE00_705F.Field.GnbIdleAdjustVid;
        }
        NbPsCfgLow.Field.NbPsForceSel = 0;
        LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCfgLow.Value, StdHeader);
        WaitForTransition = TRUE;
      }
    }
    if (WaitForTransition) {
      // Ensure that the frequency has settled before returning to memory code.
      PciAddress.AddressValue = NB_PSTATE_CTRL_STS_PCI_ADDR;
      do {
        LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlSts.Value, StdHeader);
      } while (NbPsCtrlSts.Field.NbPs1Act != TargetNbPstate);
    }
  }

  return ReturnStatus;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Performs integer division, and rounds the quotient up if the remainder is greater
 * than or equal to 50% of the divisor.
 *
 * @param[in]     Dividend                The target MEMCLK in megahertz.
 * @param[in]     Divisor                 The target MEMCLK's register encoding.
 *
 * @return        The rounded quotient
 */
UINT32
STATIC
RoundedDivision (
  IN       UINT32 Dividend,
  IN       UINT32 Divisor
  )
{
  UINT32 Quotient;

  ASSERT (Divisor != 0);

  Quotient = Dividend / Divisor;
  if (((Dividend % Divisor) * 2) >= Divisor) {
    Quotient++;
  }
  return Quotient;
}
