summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15Utilities.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15Utilities.c')
-rw-r--r--src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15Utilities.c1176
1 files changed, 0 insertions, 1176 deletions
diff --git a/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15Utilities.c b/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15Utilities.c
deleted file mode 100644
index a8d04a1c9c..0000000000
--- a/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15Utilities.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-/* $NoKeywords:$ */
-/**
- * @file
- *
- * AMD Family_15 specific utility functions.
- *
- * Provides numerous utility functions specific to family 15h.
- *
- * @xrefitem bom "File Content Label" "Release Content"
- * @e project: AGESA
- * @e sub-project: CPU/Family/0x15
- *
- */
-/*
- ******************************************************************************
- *
- * Copyright (c) 2008 - 2012, 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 "cpuFamilyTranslation.h"
-#include "cpuPstateTables.h"
-#include "cpuF15PowerMgmt.h"
-#include "cpuApicUtilities.h"
-#include "cpuServices.h"
-#include "GeneralServices.h"
-#include "cpuF15Utilities.h"
-#include "cpuEarlyInit.h"
-#include "cpuPostInit.h"
-#include "cpuFeatures.h"
-#include "OptionMultiSocket.h"
-#include "Filecode.h"
-CODE_GROUP (G2_PEI)
-RDATA_GROUP (G2_PEI)
-#define FILECODE PROC_CPU_FAMILY_0X15_CPUF15UTILITIES_FILECODE
-
-/*----------------------------------------------------------------------------------------
- * D E F I N I T I O N S A N D M A C R O S
- *----------------------------------------------------------------------------------------
- */
-
-extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
-extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
-
-// HT Phy registers used in code.
-#define HT_PHY_FUSE_PROC_DLL_PROCESS_COMP_RD_SL0 0x4011
-#define HT_PHY_FUSE_PROC_DLL_PROCESS_COMP_RD_SL1 0x4411
-#define HT_PHY_LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_RD 0x400F
-#define HT_PHY_LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_SL0 0x520F
-#define HT_PHY_LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_SL1 0x530F
-
-/*----------------------------------------------------------------------------------------
- * T Y P E D E F S A N D S T R U C T U R E S
- *----------------------------------------------------------------------------------------
- */
-
-/**
- * HT PHY DLL Process Compensation Lookup Table.
- *
- * If the hardware provides compensation values, the value is provided by accessing the bitfield
- * [HiBit:LoBit]. Otherwise, a default value will be used.
- *
- */
-typedef struct {
- UINT32 DefaultComp; ///< The default compensation value if not provided by hardware.
- UINT8 CtlIndexLoBit; ///< The low bit position of the compensation value.
- UINT8 CtlIndexHiBit; ///< The high bit position of the compensation value.
-} HT_PHY_DLL_COMP_LOOKUP_TABLE;
-
-/**
- * Process Compensation Fuses for HT PHY, Link Phy Receiver Process Fuse Control Register.
- */
-typedef struct {
- UINT32 :11;
- UINT32 DllProcessComp10:2; ///< [12:11] DLL Process Comp bits [1:0], this phy's adjustment.
- UINT32 DllProcessComp2:1; ///< [13] DLL Process Comp bit 2, Increment or Decrement.
- UINT32 : (31 - 13);
-} LINK_PHY_RECEIVER_PROCESS_FUSE_CONTROL_FIELDS;
-
-/// Access register as fields or uint32 value.
-typedef union {
- UINT32 Value; ///< 32 bit value for register access
- LINK_PHY_RECEIVER_PROCESS_FUSE_CONTROL_FIELDS Fields; ///< The register bit fields
-} LINK_PHY_RECEIVER_PROCESS_FUSE_CONTROL;
-
-/**
- * Link Phy Receiver Process DLL Control Register.
- */
-typedef struct {
- UINT32 DllProcessFreqCtlIndex2:4; ///< [3:0] The DLL Compensation override.
- UINT32 : (12 - 4);
- UINT32 DllProcessFreqCtlOverride:1; ///< [12] Enable DLL Compensation overriding.
- UINT32 : (31 - 12);
-} LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_FIELDS;
-
-/// Access register as fields or uint32 value.
-typedef union {
- UINT32 Value; ///< 32 bit value for register access
- LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_FIELDS Fields; ///< The register bit fields
-} LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL;
-
-/**
- * Provide the HT PHY DLL compensation value for each HT Link frequency.
- *
- * The HT Frequency enum is not contiguous, there are skipped values. Rather than complicate
- * index calculations, add Invalid entries here marked with an invalid compensation value (invalid
- * because real compensation values are 0 .. 15).
- */
-CONST STATIC HT_PHY_DLL_COMP_LOOKUP_TABLE ROMDATA HtPhyDllCompLookupTable[] = {
- {0xAul, 0, 3}, // HT_FREQUENCY_1200M
- {0xAul, 0, 3}, // HT_FREQUENCY_1400M
- {0x7ul, 4, 7}, // HT_FREQUENCY_1600M
- {0x7ul, 4, 7}, // HT_FREQUENCY_1800M
- {0x5ul, 8, 11}, // HT_FREQUENCY_2000M
- {0x5ul, 8, 11}, // HT_FREQUENCY_2200M
- {0x4ul, 12, 15}, // HT_FREQUENCY_2400M
- {0x3ul, 16, 19}, // HT_FREQUENCY_2600M
- {0xFFFFFFFFul, 0, 0}, // Invalid
- {0xFFFFFFFFul, 0, 0}, // Invalid
- {0x3ul, 20, 23}, // HT_FREQUENCY_2800M
- {0x2ul, 24, 27}, // HT_FREQUENCY_3000M
- {0x2ul, 28, 31} // HT_FREQUENCY_3200M
-};
-
-/*----------------------------------------------------------------------------------------
- * 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
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * E X P O R T E D F U N C T I O N S
- *----------------------------------------------------------------------------------------
- */
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Disables the desired P-state.
- *
- * @CpuServiceMethod{::F_CPU_DISABLE_PSTATE}.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in] StateNumber The P-State to disable.
- * @param[in] StdHeader Header for library and services
- *
- * @retval AGESA_SUCCESS Always succeeds.
- */
-AGESA_STATUS
-F15DisablePstate (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN UINT8 StateNumber,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT64 LocalMsrRegister;
-
- ASSERT (StateNumber < NM_PS_REG);
- LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader);
- ((F15_PSTATE_MSR *) &LocalMsrRegister)->PsEnable = 0;
- LibAmdMsrWrite (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader);
- return (AGESA_SUCCESS);
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Transitions the executing core to the desired P-state.
- *
- * @CpuServiceMethod{::F_CPU_TRANSITION_PSTATE}.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in] StateNumber The new P-State to make effective.
- * @param[in] WaitForTransition True if the caller wants the transition completed upon return.
- * @param[in] StdHeader Header for library and services
- *
- * @retval AGESA_SUCCESS Always Succeeds
- */
-AGESA_STATUS
-F15TransitionPstate (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN UINT8 StateNumber,
- IN BOOLEAN WaitForTransition,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT64 LocalMsrRegister;
-
- LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader);
- ASSERT (((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal >= StateNumber);
- LibAmdMsrRead (MSR_PSTATE_CTL, &LocalMsrRegister, StdHeader);
- ((PSTATE_CTRL_MSR *) &LocalMsrRegister)->PstateCmd = (UINT64) StateNumber;
- LibAmdMsrWrite (MSR_PSTATE_CTL, &LocalMsrRegister, StdHeader);
- if (WaitForTransition) {
- do {
- LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader);
- } while (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate != (UINT64) StateNumber);
- }
- return (AGESA_SUCCESS);
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Determines the rate at which the executing core's time stamp counter is
- * incrementing.
- *
- * @CpuServiceMethod{::F_CPU_GET_TSC_RATE}.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[out] FrequencyInMHz TSC actual frequency.
- * @param[in] StdHeader Header for library and services.
- *
- * @return The most severe status of all called services
- */
-AGESA_STATUS
-F15GetTscRate (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- OUT UINT32 *FrequencyInMHz,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT8 NumBoostStates;
- UINT32 LocalPciRegister;
- UINT64 LocalMsrRegister;
- PCI_ADDR PciAddress;
- PSTATE_CPU_FAMILY_SERVICES *FamilyServices;
-
- LibAmdMsrRead (0xC0010015, &LocalMsrRegister, StdHeader);
- if ((LocalMsrRegister & 0x01000000) != 0) {
- FamilyServices = NULL;
- GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
- ASSERT (FamilyServices != NULL);
- OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
- PciAddress.Address.Function = FUNC_4;
- PciAddress.Address.Register = CPB_CTRL_REG;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- NumBoostStates = (UINT8) ((F15_CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates;
- return (FamilyServices->GetPstateFrequency (FamilyServices, NumBoostStates, FrequencyInMHz, StdHeader));
- } else {
- return (FamilySpecificServices->GetCurrentNbFrequency (FamilySpecificServices, FrequencyInMHz, StdHeader));
- }
-}
-
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Initially launches the desired core to run from the reset vector.
- *
- * @CpuServiceMethod{::F_CPU_AP_INITIAL_LAUNCH}.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in] SocketNum The Processor on which the core is to be launched
- * @param[in] ModuleNum The Module in that processor containing that core
- * @param[in] CoreNum The Core to launch
- * @param[in] PrimaryCoreNum The id of the module's primary core.
- * @param[in] StdHeader Header for library and services
- *
- * @retval TRUE The core was launched
- * @retval FALSE The core was previously launched
- */
-BOOLEAN
-F15LaunchApCore (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN UINT32 SocketNum,
- IN UINT32 ModuleNum,
- IN UINT32 CoreNum,
- IN UINT32 PrimaryCoreNum,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 NodeRelativeCoreNum;
- UINT32 LocalPciRegister;
- PCI_ADDR PciAddress;
- BOOLEAN LaunchFlag;
- AGESA_STATUS Ignored;
-
- // Code Start
- LaunchFlag = FALSE;
- NodeRelativeCoreNum = CoreNum - PrimaryCoreNum;
- GetPciAddress (StdHeader, SocketNum, ModuleNum, &PciAddress, &Ignored);
- PciAddress.Address.Function = FUNC_0;
-
- switch (NodeRelativeCoreNum) {
- case 0:
- PciAddress.Address.Register = HT_INIT_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & HT_INIT_CTRL_REQ_DIS) != 0) {
- LocalPciRegister &= ~HT_INIT_CTRL_REQ_DIS;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 1:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE1_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE1_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 2:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
-
- if ((LocalPciRegister & CORE_CTRL_CORE2_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE2_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister,
- StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 3:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE3_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE3_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 4:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE4_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE4_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 5:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE5_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE5_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 6:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE6_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE6_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 7:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE7_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE7_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 8:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE8_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE8_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- case 9:
- PciAddress.Address.Register = CORE_CTRL;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((LocalPciRegister & CORE_CTRL_CORE9_EN) == 0) {
- LocalPciRegister |= CORE_CTRL_CORE9_EN;
- LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- LaunchFlag = TRUE;
- } else {
- LaunchFlag = FALSE;
- }
- break;
-
- default:
- break;
- }
-
- return (LaunchFlag);
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Provide the features of the next HT link.
- *
- * @CpuServiceMethod{::F_GET_NEXT_HT_LINK_FEATURES}.
- *
- * This method is different than the HT Phy Features method, because for the phy registers
- * sublink 1 matches and should be programmed if the link is ganged but for PCI config
- * registers sublink 1 is reserved if the link is ganged.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in,out] Link Initially zero, each call returns the link number;
- * caller passes it back unmodified each call.
- * @param[in,out] LinkBase Initially the PCI bus, device, function=0, offset=0;
- * Each call returns the HT Host Capability function and offset;
- * Caller may use it to access registers, but must @b not modify it;
- * Each new call passes the previous value as input.
- * @param[out] HtHostFeats The link's features.
- * @param[in] StdHeader Standard Head Pointer
- *
- * @retval TRUE Valid link and features found.
- * @retval FALSE No more links.
- */
-BOOLEAN
-F15GetNextHtLinkFeatures (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN OUT UINTN *Link,
- IN OUT PCI_ADDR *LinkBase,
- OUT HT_HOST_FEATS *HtHostFeats,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- PCI_ADDR PciAddress;
- UINT32 RegValue;
- UINT32 ExtendedFreq;
- UINTN LinkOffset;
- BOOLEAN Result;
-
- ASSERT (FamilySpecificServices != NULL);
-
- // No features present unless link is good and connected.
- HtHostFeats->HtHostValue = 0;
-
- Result = TRUE;
-
- // Find next link.
- if (LinkBase->Address.Register == 0) {
- // Beginning iteration now.
- LinkBase->Address.Register = HT_CAPABILITIES_POINTER;
- LibAmdPciReadBits (*LinkBase, 7, 0, &RegValue, StdHeader);
- } else {
- // Get next link offset.
- LibAmdPciReadBits (*LinkBase, 15, 8, &RegValue, StdHeader);
- }
- if (RegValue == 0) {
- // Are we at the end? Check if we can move to another function.
- if (LinkBase->Address.Function == 0) {
- LinkBase->Address.Function = 4;
- LinkBase->Address.Register = HT_CAPABILITIES_POINTER;
- LibAmdPciReadBits (*LinkBase, 7, 0, &RegValue, StdHeader);
- }
- }
-
- if (RegValue != 0) {
- // Not at end, process the found link.
- LinkBase->Address.Register = RegValue;
- // Compute link number
- *Link = (((LinkBase->Address.Function == 4) ? 4 : 0) + ((LinkBase->Address.Register - 0x80) >> 5));
-
- // Handle pending link power off, check End of Chain, Xmit Off.
- PciAddress = *LinkBase;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_CONTROL_REG_OFFSET;
- LibAmdPciReadBits (PciAddress, 7, 6, &RegValue, StdHeader);
- if (RegValue == 0) {
- // Check coherency (HTHOST_LINK_TYPE_REG = 0x18)
- PciAddress = *LinkBase;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_TYPE_REG_OFFSET;
- LibAmdPciReadBits (PciAddress, 4, 0, &RegValue, StdHeader);
- if (RegValue == 3) {
- HtHostFeats->HtHostFeatures.Coherent = 1;
- } else if (RegValue == 7) {
- HtHostFeats->HtHostFeatures.NonCoherent = 1;
- }
- }
-
- // If link was not connected, don't check other attributes, make sure
- // to return zero, no match.
- if ((HtHostFeats->HtHostFeatures.Coherent == 1) || (HtHostFeats->HtHostFeatures.NonCoherent == 1)) {
- // Check gen3
- PciAddress = *LinkBase;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_EXTENDED_FREQ;
- LibAmdPciRead (AccessWidth32, PciAddress, &ExtendedFreq, StdHeader);
- PciAddress = *LinkBase;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_FREQ_OFFSET;
- LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader);
- RegValue = (((ExtendedFreq & 0x1) << 4) | ((RegValue & 0x00000F00) >> 8));
- if (RegValue > 6) {
- HtHostFeats->HtHostFeatures.Ht3 = 1;
- } else {
- HtHostFeats->HtHostFeatures.Ht1 = 1;
- }
- // Check ganged. Must check the bit for sublink 0.
- LinkOffset = (*Link > 3) ? ((*Link - 4) * 4) : (*Link * 4);
- PciAddress = *LinkBase;
- PciAddress.Address.Function = 0;
- PciAddress.Address.Register = ((UINT32)LinkOffset + 0x170);
- LibAmdPciReadBits (PciAddress, 0, 0, &RegValue, StdHeader);
- if (RegValue == 0) {
- HtHostFeats->HtHostFeatures.UnGanged = 1;
- } else {
- if (*Link < 4) {
- HtHostFeats->HtHostFeatures.Ganged = 1;
- } else {
- // If this is a sublink 1 but it will be ganged, clear all features.
- HtHostFeats->HtHostValue = 0;
- }
- }
- }
- } else {
- // end of links.
- Result = FALSE;
- }
- return Result;
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Checks to see if the HT phy register table entry should be applied
- *
- * @CpuServiceMethod{::F_NEXT_LINK_HAS_HTFPY_FEATS}.
- *
- * Find the next link which matches, if any.
- * This method will match for sublink 1 if the link is ganged and sublink 0 matches.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in,out] HtHostCapability Initially the PCI bus, device, function=0, offset=0;
- * Each call returns the HT Host Capability function and offset;
- * Caller may use it to access registers, but must @b not modify it;
- * Each new call passes the previous value as input.
- * @param[in,out] Link Initially zero, each call returns the link number; caller passes it back unmodified each call.
- * @param[in] HtPhyLinkType Link type field from a register table entry to compare against
- * @param[out] MatchedSublink1 TRUE: It is actually just sublink 1 that matches, FALSE: any other condition.
- * @param[out] Frequency0 The frequency of sublink0 (200 MHz if not connected).
- * @param[out] Frequency1 The frequency of sublink1 (200 MHz if not connected).
- * @param[in] StdHeader Standard Head Pointer
- *
- * @retval TRUE Link matches
- * @retval FALSE No more links
- *
- */
-BOOLEAN
-F15NextLinkHasHtPhyFeats (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN OUT PCI_ADDR *HtHostCapability,
- IN OUT UINT32 *Link,
- IN HT_PHY_LINK_FEATS *HtPhyLinkType,
- OUT BOOLEAN *MatchedSublink1,
- OUT HT_FREQUENCIES *Frequency0,
- OUT HT_FREQUENCIES *Frequency1,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 RegValue;
- UINT32 ExtendedFreq;
- UINT32 InternalLinks;
- UINT32 Width;
- PCI_ADDR PciAddress;
- PCI_ADDR SubLink1Address;
- HT_PHY_LINK_FEATS LinkType;
- BOOLEAN IsReallyCheckingBoth;
- BOOLEAN IsFound;
- BOOLEAN Result;
-
- ASSERT (*Link < 4);
- ASSERT (HtPhyLinkType != NULL);
- // error checks: No unknown link type bits set and not a "match none"
- ASSERT ((HtPhyLinkType->HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL | HTPHY_LINKTYPE_SL0_AND | HTPHY_LINKTYPE_SL1_AND)) == 0);
- ASSERT (HtPhyLinkType->HtPhyLinkValue != 0);
-
- Result = FALSE;
- IsFound = FALSE;
- while (!IsFound) {
- *Frequency0 = 0;
- *Frequency1 = 0;
- IsReallyCheckingBoth = FALSE;
- *MatchedSublink1 = FALSE;
- LinkType.HtPhyLinkValue = 0;
-
- // Find next link.
- PciAddress = *HtHostCapability;
- if (PciAddress.Address.Register == 0) {
- // Beginning iteration now.
- PciAddress.Address.Register = HT_CAPABILITIES_POINTER;
- LibAmdPciReadBits (PciAddress, 7, 0, &RegValue, StdHeader);
- } else {
- // Get next link offset.
- LibAmdPciReadBits (PciAddress, 15, 8, &RegValue, StdHeader);
- }
- if (RegValue != 0) {
- HtHostCapability->Address.Register = RegValue;
- // Compute link number of this sublink pair (so we don't need to account for function).
- *Link = ((HtHostCapability->Address.Register - 0x80) >> 5);
-
- // Set the link indicators. This assumes each sublink set is contiguous, that is, links 3, 2, 1, 0 and 7, 6, 5, 4.
- LinkType.HtPhyLinkValue |= (HTPHY_LINKTYPE_SL0_LINK0 << *Link);
- LinkType.HtPhyLinkValue |= (HTPHY_LINKTYPE_SL1_LINK4 << *Link);
-
- // Read IntLnkRoute from the Link Initialization Status register.
- PciAddress = *HtHostCapability;
- PciAddress.Address.Function = 0;
- PciAddress.Address.Register = 0x1A0;
- LibAmdPciReadBits (PciAddress, 23, 16, &InternalLinks, StdHeader);
-
- // if ganged, don't read sublink 1, but use sublink 0 to check.
- SubLink1Address = *HtHostCapability;
-
- // Check ganged. Since we got called for sublink 0, sublink 1 is implemented also,
- // but only access it if it is also unganged.
- PciAddress = *HtHostCapability;
- PciAddress.Address.Function = 0;
- PciAddress.Address.Register = ((*Link * 4) + 0x170);
- LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader);
- RegValue = (RegValue & 0x01);
- if (RegValue == 0) {
- // Then really read sublink1, rather than using sublink0
- SubLink1Address.Address.Function = 4;
- IsReallyCheckingBoth = TRUE;
- }
-
- // Checks for Sublink 0
-
- // Handle pending link power off, check End of Chain, Xmit Off.
- PciAddress = *HtHostCapability;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_CONTROL_REG_OFFSET;
- LibAmdPciReadBits (PciAddress, 7, 6, &RegValue, StdHeader);
- if (RegValue == 0) {
- // Check coherency (HTHOST_LINK_TYPE_REG = 0x18)
- PciAddress = *HtHostCapability;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_TYPE_REG_OFFSET;
- LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader);
- if ((RegValue & 0x1F) == 3) {
- LinkType.HtPhyLinkFeatures.HtPhySL0Coh = 1;
- } else if ((RegValue & 0x1F) == 7) {
- LinkType.HtPhyLinkFeatures.HtPhySL0NonCoh = 1;
- }
- }
-
- // If link was not connected, don't check other attributes, make sure
- // to return zero, no match. (Phy may be powered off.)
- if ((LinkType.HtPhyLinkFeatures.HtPhySL0Coh) || (LinkType.HtPhyLinkFeatures.HtPhySL0NonCoh)) {
- // Check gen3
- PciAddress = *HtHostCapability;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_EXTENDED_FREQ;
- LibAmdPciRead (AccessWidth32, PciAddress, &ExtendedFreq, StdHeader);
- PciAddress = *HtHostCapability;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_FREQ_OFFSET;
- LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader);
- RegValue = (((ExtendedFreq & 0x1) << 4) | ((RegValue & 0x00000F00) >> 8));
- *Frequency0 = RegValue;
- if (RegValue > 6) {
- LinkType.HtPhyLinkFeatures.HtPhySL0Ht3 = 1;
- } else {
- LinkType.HtPhyLinkFeatures.HtPhySL0Ht1 = 1;
- }
- // Check internal / external
- if ((InternalLinks & (1 << *Link)) == 0) {
- // External
- LinkType.HtPhyLinkFeatures.HtPhySL0External = 1;
- } else {
- // Internal
- LinkType.HtPhyLinkFeatures.HtPhySL0Internal = 1;
- }
- } else {
- LinkType.HtPhyLinkValue &= ~(HTPHY_LINKTYPE_SL0_ALL);
- }
-
- // Checks for Sublink 1
- // Handle pending link power off, check End of Chain, Xmit Off.
- // Also, if the links are ganged but the width is not 16 bits, treat it is an inactive lane.
- PciAddress = SubLink1Address;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_CONTROL_REG_OFFSET;
- LibAmdPciReadBits (PciAddress, 7, 6, &RegValue, StdHeader);
- LibAmdPciReadBits (PciAddress, 31, 24, &Width, StdHeader);
- if ((RegValue == 0) && (IsReallyCheckingBoth || (Width == 0x11))) {
- // Check coherency (HTHOST_LINK_TYPE_REG = 0x18)
- PciAddress = SubLink1Address;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_TYPE_REG_OFFSET;
- LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader);
- if ((RegValue & 0x1F) == 3) {
- LinkType.HtPhyLinkFeatures.HtPhySL1Coh = 1;
- } else if ((RegValue & 0x1F) == 7) {
- LinkType.HtPhyLinkFeatures.HtPhySL1NonCoh = 1;
- }
- }
-
- if ((LinkType.HtPhyLinkFeatures.HtPhySL1Coh) || (LinkType.HtPhyLinkFeatures.HtPhySL1NonCoh)) {
- // Check gen3
- PciAddress = SubLink1Address;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_EXTENDED_FREQ;
- LibAmdPciRead (AccessWidth32, PciAddress, &ExtendedFreq, StdHeader);
- PciAddress = SubLink1Address;
- PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_FREQ_OFFSET;
- LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader);
- RegValue = (((ExtendedFreq & 0x1) << 4) | ((RegValue & 0x00000F00) >> 8));
- *Frequency1 = RegValue;
- if (RegValue > 6) {
- LinkType.HtPhyLinkFeatures.HtPhySL1Ht3 = 1;
- } else {
- LinkType.HtPhyLinkFeatures.HtPhySL1Ht1 = 1;
- }
- // Check internal / external. Note that we do really check sublink 1 regardless of ganging.
- if ((InternalLinks & (1 << (*Link + 4))) == 0) {
- // External
- LinkType.HtPhyLinkFeatures.HtPhySL1External = 1;
- } else {
- // Internal
- LinkType.HtPhyLinkFeatures.HtPhySL1Internal = 1;
- }
- } else {
- LinkType.HtPhyLinkValue &= ~(HTPHY_LINKTYPE_SL1_ALL);
- }
-
- // Determine if the link matches the entry criteria.
- // For Deemphasis checking, indicate whether it was actually sublink 1 that matched.
- // If the link is ganged or only sublink 0 matched, or the link features didn't match, this is false.
- if (((HtPhyLinkType->HtPhyLinkValue & HTPHY_LINKTYPE_SL0_AND) == 0) &&
- ((HtPhyLinkType->HtPhyLinkValue & HTPHY_LINKTYPE_SL1_AND) == 0)) {
- // Match if any feature matches (OR)
- Result = (BOOLEAN) ((LinkType.HtPhyLinkValue & HtPhyLinkType->HtPhyLinkValue) != 0);
- } else {
- // Match if all features match (AND)
- Result = (BOOLEAN) ((HtPhyLinkType->HtPhyLinkValue & ~(HTPHY_LINKTYPE_SL0_AND | HTPHY_LINKTYPE_SL1_AND)) ==
- (LinkType.HtPhyLinkValue & HtPhyLinkType->HtPhyLinkValue));
- }
- if (Result) {
- if (IsReallyCheckingBoth &&
- (((LinkType.HtPhyLinkValue & HtPhyLinkType->HtPhyLinkValue) & (HTPHY_LINKTYPE_SL1_ALL)) != 0)) {
- *MatchedSublink1 = TRUE;
- }
- IsFound = TRUE;
- } else {
- // Go to next link
- }
- } else {
- // No more links
- IsFound = TRUE;
- }
- }
- return Result;
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Applies an HT Phy read-modify-write based on an HT Phy register table entry.
- *
- * @CpuServiceMethod{::F_SET_HT_PHY_REGISTER}.
- *
- * This function performs the necessary sequence of PCI reads, writes, and waits
- * necessary to program an HT Phy register.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in] HtPhyEntry HT Phy register table entry to apply
- * @param[in] CapabilitySet The link's HT Host base address.
- * @param[in] Link Zero based, node, link number (not package link).
- * @param[in] StdHeader Config handle for library and services
- *
- */
-VOID
-F15SetHtPhyRegister (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN HT_PHY_TYPE_ENTRY_DATA *HtPhyEntry,
- IN PCI_ADDR CapabilitySet,
- IN UINT32 Link,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 Temp;
- UINT32 PhyReg;
- PCI_ADDR PhyBase;
-
- // Determine the PCI config address of the HT Phy portal
- PhyBase = CapabilitySet;
- PhyBase.Address.Function = FUNC_4;
- PhyBase.Address.Register = ((Link << 3) + REG_HT4_PHY_OFFSET_BASE_4X180);
-
- LibAmdPciRead (AccessWidth32, PhyBase, &PhyReg, StdHeader);
-
- // Handle direct map registers if needed
- PhyReg &= ~(HTPHY_DIRECT_OFFSET_MASK);
- if ((HtPhyEntry->Address > 0x3FF) || ((HtPhyEntry->Address >= 0xE) && (HtPhyEntry->Address <= 0x11))) {
- PhyReg |= HTPHY_DIRECT_MAP;
- }
-
- PhyReg |= (HtPhyEntry->Address);
- // Ask the portal to read the HT Phy Register contents
- LibAmdPciWrite (AccessWidth32, PhyBase, &PhyReg, StdHeader);
- do
- {
- LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader);
- } while (!(Temp & HTPHY_IS_COMPLETE_MASK));
-
- // Get the current register contents and do the update requested by the table
- PhyBase.AddressValue += 4;
- LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader);
- Temp &= ~(HtPhyEntry->Mask);
- Temp |= (HtPhyEntry->Data);
- LibAmdPciWrite (AccessWidth32, PhyBase, &Temp, StdHeader);
-
- PhyBase.AddressValue -= 4;
- // Ask the portal to write our updated value to the HT Phy
- PhyReg |= HTPHY_WRITE_CMD;
- LibAmdPciWrite (AccessWidth32, PhyBase, &PhyReg, StdHeader);
- do
- {
- LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader);
- } while (!(Temp & HTPHY_IS_COMPLETE_MASK));
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Applies an HT Phy write to a specified Phy register.
- *
- * @CpuServiceMethod{::F_SET_HT_PHY_REGISTER}.
- *
- * The caller is responsible for performing any read and modify steps.
- * This function performs the necessary sequence of PCI reads, writes, and waits
- * necessary to program an HT Phy register.
- *
- * @param[in] CapabilitySet The link's HT Host base address.
- * @param[in] Link Zero based, node, link number (not package link).
- * @param[in] Address The HT Phy register address
- * @param[in] Data The data to write to the register
- * @param[in] StdHeader Config handle for library and services
- *
- */
-VOID
-STATIC
-F15WriteOnlyHtPhyRegister (
- IN PCI_ADDR CapabilitySet,
- IN UINT32 Link,
- IN UINT32 Address,
- IN UINT32 Data,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 Temp;
- UINT32 PhyReg;
- PCI_ADDR PhyBase;
-
- // Determine the PCI config address of the HT Phy portal
- PhyBase = CapabilitySet;
- PhyBase.Address.Function = FUNC_4;
- PhyBase.Address.Register = ((Link << 3) + REG_HT4_PHY_OFFSET_BASE_4X180);
-
- LibAmdPciRead (AccessWidth32, PhyBase, &PhyReg, StdHeader);
-
- // Handle direct map registers if needed
- PhyReg &= ~(HTPHY_DIRECT_OFFSET_MASK);
- if ((Address > 0x3FF) || ((Address >= 0xE) && (Address <= 0x11))) {
- PhyReg |= HTPHY_DIRECT_MAP;
- }
-
- PhyReg |= (Address);
-
- // Get the current register contents and do the update requested by the table
- PhyBase.AddressValue += 4;
- LibAmdPciWrite (AccessWidth32, PhyBase, &Data, StdHeader);
-
- PhyBase.AddressValue -= 4;
- // Ask the portal to write our updated value to the HT Phy
- PhyReg |= HTPHY_WRITE_CMD;
- LibAmdPciWrite (AccessWidth32, PhyBase, &PhyReg, StdHeader);
- do
- {
- LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader);
- } while (!(Temp & HTPHY_IS_COMPLETE_MASK));
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Get the value of an HT PHY register.
- *
- * Reading HT Phy registers is not generally useful, because they return the effective value,
- * not the currently written value. So be warned, this function is dangerous if used to read
- * a register that will be udpated subsequently elsewhere.
- *
- * This routine is useful for reading hardware status from the HT Phy that can be used to set
- * other phy registers.
- *
- * @param[in] CapabilitySet The link's HT Host base address.
- * @param[in] Link Zero based, node link number (not package link).
- * @param[in] Address The HT Phy register address to read
- * @param[in] StdHeader Config handle for library and services
- *
- * @return The register content (in most cases, the effective content not the pending content)
- *
- */
-UINT32
-STATIC
-F15GetHtPhyRegister (
- IN PCI_ADDR CapabilitySet,
- IN UINT32 Link,
- IN UINT32 Address,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 Temp;
- UINT32 PhyReg;
- PCI_ADDR PhyBase;
-
- // Determine the PCI config address of the HT Phy portal
- PhyBase = CapabilitySet;
- PhyBase.Address.Function = FUNC_4;
- PhyBase.Address.Register = ((Link << 3) + REG_HT4_PHY_OFFSET_BASE_4X180);
-
- LibAmdPciRead (AccessWidth32, PhyBase, &PhyReg, StdHeader);
-
- // Handle direct map registers if needed
- PhyReg &= ~(HTPHY_DIRECT_OFFSET_MASK);
- if ((Address > 0x3FF) || ((Address >= 0xE) && (Address <= 0x11))) {
- PhyReg |= HTPHY_DIRECT_MAP;
- }
-
- PhyReg |= Address;
- // Ask the portal to read the HT Phy Register contents
- LibAmdPciWrite (AccessWidth32, PhyBase, &PhyReg, StdHeader);
- do
- {
- LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader);
- } while (!(Temp & HTPHY_IS_COMPLETE_MASK));
-
- // Get the current register contents
- PhyBase.AddressValue += 4;
- LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader);
-
- return Temp;
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * A Family Specific Workaround method, to override HT DLL Compensation.
- *
- * \@TableTypeFamSpecificInstances.
- *
- * The Link Product Information register can be fused to contain an HT PHY DLL Compensation Override table.
- * Based on link frequency, a compensation override can be selected from the value.
- * To accomodate individual link differences in the package, each link can also have a DLL process compensation
- * value set. This value can apply an adjustment to the compensation value.
- *
- * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched.
- * @param[in] StdHeader Config params for library, services.
- */
-VOID
-F15HtPhyOverrideDllCompensation (
- IN UINT32 Data,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 ProductLinkInfo;
- UINT32 Link;
- CPU_LOGICAL_ID CpuFamilyRevision;
- PCI_ADDR StartingCapabilitySet;
- PCI_ADDR CapabilitySet;
- PCI_ADDR PciAddress;
- CPU_SPECIFIC_SERVICES *FamilySpecificServices;
- BOOLEAN MatchedSublink1;
- HT_FREQUENCIES Freq0;
- HT_FREQUENCIES Freq1;
- UINTN Sublink;
- HT_PHY_LINK_FEATS DesiredLinkFeats;
- BOOLEAN IsEarlyRevProcessor;
- BOOLEAN IsHardwareReportingComp;
- UINTN LinkFrequency;
- UINT32 Compensation;
- UINT32 Adjustment;
- BOOLEAN IsIncrementAdjust;
- LINK_PHY_RECEIVER_PROCESS_FUSE_CONTROL LinkPhyReceiverProcessFuseControl;
- LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL LinkPhyReceiverProcessDllControl;
-
- OptionMultiSocketConfiguration.GetCurrPciAddr (&StartingCapabilitySet, StdHeader);
- GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
- GetCpuServicesFromLogicalId (&CpuFamilyRevision, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
-
- // Check if the hardware reported any compensation values.
- IsEarlyRevProcessor = (BOOLEAN) ((Data == 0) ? TRUE : FALSE);
- PciAddress = StartingCapabilitySet;
- PciAddress.Address.Function = FUNC_5;
- PciAddress.Address.Register = 0x190;
- LibAmdPciRead (AccessWidth32, PciAddress, &ProductLinkInfo, StdHeader);
- IsHardwareReportingComp = (BOOLEAN) (ProductLinkInfo != 0);
-
- if (!IsEarlyRevProcessor || IsHardwareReportingComp) {
- // Process all the sublink 0's and then all the sublink 1's that are at HT3 frequency.
- for (Sublink = 0; Sublink < 2; Sublink++) {
- CapabilitySet = StartingCapabilitySet;
- Link = 0;
- DesiredLinkFeats.HtPhyLinkValue = ((Sublink == 0) ? HTPHY_LINKTYPE_SL0_HT3 : HTPHY_LINKTYPE_SL0_HT3);
- while (FamilySpecificServices->NextLinkHasHtPhyFeats (
- FamilySpecificServices,
- &CapabilitySet,
- &Link,
- &DesiredLinkFeats,
- &MatchedSublink1,
- &Freq0,
- &Freq1,
- StdHeader)) {
-
- // Look up compensation value. Remember that we matched links which are at HT3 frequency, so Freq[1,0]
- // should safely be greater than or equal to 1.2 GHz.
- if (Sublink == 0) {
- LinkFrequency = Freq0 - HT_FREQUENCY_1200M;
- } else {
- LinkFrequency = (MatchedSublink1 ? Freq1 : Freq0) - HT_FREQUENCY_1200M;
- }
- // This assert would catch frequencies higher than we know how to support, or any table overrun bug.
- ASSERT (LinkFrequency < (sizeof (HtPhyDllCompLookupTable) / sizeof (HT_PHY_DLL_COMP_LOOKUP_TABLE)));
- // Since there are invalid entries in the table, for frequency enum skipped values, ensure we did not
- // pick one of those entries. This should be impossible from real hardware.
- ASSERT (HtPhyDllCompLookupTable[LinkFrequency].DefaultComp != 0xFFFFFFFFul);
-
- if (IsHardwareReportingComp) {
- LibAmdPciReadBits (
- PciAddress,
- HtPhyDllCompLookupTable[LinkFrequency].CtlIndexHiBit,
- HtPhyDllCompLookupTable[LinkFrequency].CtlIndexLoBit,
- &Compensation,
- StdHeader);
- } else {
- Compensation = HtPhyDllCompLookupTable[LinkFrequency].DefaultComp;
- }
-
- // Apply any per PHY adjustment
- LinkPhyReceiverProcessFuseControl.Value = F15GetHtPhyRegister (
- CapabilitySet,
- Link,
- ((Sublink == 0) ? HT_PHY_FUSE_PROC_DLL_PROCESS_COMP_RD_SL0 : HT_PHY_FUSE_PROC_DLL_PROCESS_COMP_RD_SL1),
- StdHeader);
- Adjustment = LinkPhyReceiverProcessFuseControl.Fields.DllProcessComp10;
- IsIncrementAdjust = (BOOLEAN) ((LinkPhyReceiverProcessFuseControl.Fields.DllProcessComp2 == 0) ? TRUE : FALSE);
- if (IsIncrementAdjust) {
- Compensation = (((Compensation + Adjustment) > 0x000F) ? 0x000F : (Compensation + Adjustment));
- } else {
- // decrement adjustment
- Compensation = ((Compensation < Adjustment) ? 0 : (Compensation - Adjustment));
- }
-
- // Update the DLL Compensation
- LinkPhyReceiverProcessDllControl.Value = F15GetHtPhyRegister (
- CapabilitySet,
- Link,
- HT_PHY_LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_RD,
- StdHeader);
- LinkPhyReceiverProcessDllControl.Fields.DllProcessFreqCtlOverride = 1;
- LinkPhyReceiverProcessDllControl.Fields.DllProcessFreqCtlIndex2 = Compensation;
- F15WriteOnlyHtPhyRegister (
- CapabilitySet,
- Link,
- ((Sublink == 0) ? HT_PHY_LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_SL0 : HT_PHY_LINK_PHY_RECEIVER_PROCESS_DLL_CONTROL_SL1),
- LinkPhyReceiverProcessDllControl.Value,
- StdHeader);
- }
- }
- }
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Returns whether or not BIOS is responsible for configuring the NB COFVID.
- *
- * @CpuServiceMethod{::F_CPU_IS_NBCOF_INIT_NEEDED}.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in] PciAddress The northbridge to query by pci base address.
- * @param[out] NbVidUpdateAll Do all NbVids need to be updated
- * @param[in] StdHeader Header for library and services
- *
- * @retval TRUE Perform northbridge frequency and voltage config.
- * @retval FALSE Do not configure them.
- */
-BOOLEAN
-F15CommonGetNbCofVidUpdate (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN PCI_ADDR *PciAddress,
- OUT BOOLEAN *NbVidUpdateAll,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- *NbVidUpdateAll = FALSE;
- return FALSE;
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Is the Northbridge PState feature enabled?
- *
- * @CpuServiceMethod{::F_IS_NB_PSTATE_ENABLED}.
- *
- * @param[in] FamilySpecificServices The current Family Specific Services.
- * @param[in] PlatformConfig Platform profile/build option config structure.
- * @param[in] StdHeader Handle of Header for calling lib functions and services.
- *
- * @retval TRUE The NB PState feature is enabled.
- * @retval FALSE The NB PState feature is not enabled.
- */
-BOOLEAN
-F15IsNbPstateEnabled (
- IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
- IN PLATFORM_CONFIGURATION *PlatformConfig,
- IN AMD_CONFIG_PARAMS *StdHeader
- )
-{
- UINT32 LocalPciRegister;
- PCI_ADDR PciAddress;
- BOOLEAN PowerMode;
- BOOLEAN SkipHwCfg;
-
- SkipHwCfg = FALSE;
-
- IDS_OPTION_HOOK (IDS_NBPSDIS_OVERRIDE, &SkipHwCfg, StdHeader);
-
- // Defaults to Power Optimized Mode
- PowerMode = TRUE;
-
- // If system is optimized for performance, disable NB P-States
- if (PlatformConfig->PlatformProfile.PlatformPowerPolicy == Performance) {
- PowerMode = FALSE;
- }
-
- PciAddress.AddressValue = F15_NB_PSTATE_CTRL_PCI_ADDR;
- LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
- if ((((((F15_NB_PSTATE_CTRL_REGISTER *) &LocalPciRegister)->NbPstateMaxVal != 0) &&
- (!IsNonCoherentHt1 (StdHeader))) || SkipHwCfg) && (PowerMode)) {
- return TRUE;
- }
- return FALSE;
-}