diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuCommonF12Utilities.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuCommonF12Utilities.c | 572 |
1 files changed, 0 insertions, 572 deletions
diff --git a/src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuCommonF12Utilities.c b/src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuCommonF12Utilities.c deleted file mode 100644 index 59fb1d94f4..0000000000 --- a/src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuCommonF12Utilities.c +++ /dev/null @@ -1,572 +0,0 @@ -/* $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; -} |