diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c new file mode 100644 index 0000000000..61b07250a6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c @@ -0,0 +1,463 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * KB specific PCIe services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87645 $ @e \$Date: 2013-02-06 13:08:17 -0600 (Wed, 06 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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 "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV5.h" +#include "GnbPcieConfig.h" +#include "GnbPcieTrainingV2.h" +#include "GnbNbInitLibV4.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "PcieComplexDataKB.h" +#include "PcieLibKB.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbF1Table.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIELIBKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +PCIE_LINK_SPEED_CAP +PcieGetLinkSpeedCapKB ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +GnbTimeStampKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +PcieMaxPayloadKB ( + IN PCIe_ENGINE_CONFIG *Engine + ); +/*----------------------------------------------------------------------------------------*/ +/** + * PLL powerdown + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllConfigureKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllConfigureKB Enter\n"); + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x0; + + if (Wrapper->Features.PowerOffUnusedPlls != 0) { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + } else { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateL0; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateL0; + } + + if (Wrapper->Features.PllOffInL1 != 0) { + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateLS2; + } else { + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateL0; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateL0; + } + + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + 1), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllConfigureKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down unused lanes and plls + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePwrPowerDownUnusedLanesKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 UnusedLanes; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanesKB Enter\n"); + if (Wrapper->Features.PowerOffUnusedLanes != 0) { + UnusedLanes = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE, Wrapper); + PcieTopologyLaneControlV5 ( + DisableLanes, + UnusedLanes, + Wrapper, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanesKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Request boot up voltage + * + * + * + * @param[in] LinkCap Global GEN capability + * @param[in] Pcie Pointer to PCIe configuration data area + */ +VOID +PcieSetVoltageKB ( + IN PCIE_LINK_SPEED_CAP LinkCap, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 TargetVid; + UINT8 MinVidIndex; + UINT8 PP_FUSE_ARRAY_V2_fld32[5]; + UINT8 Index; + PP_F1_ARRAY_V2 *PpF1Array; + UINT32 Millivolt; + UINT32 D0F0xBC_xC0104007; + UINT32 D0F0xBC_xC0104008; + UINT32 D0F0xBC_xC010407C; + UINT32 D0F0xBC_xC0107064; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetVoltageKB Enter\n"); + PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Pcie)); + if (PpF1Array == NULL) { + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0104007, &D0F0xBC_xC0104007, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0104008, &D0F0xBC_xC0104008, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC010407C, &D0F0xBC_xC010407C, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0107064, &D0F0xBC_xC0107064, 0, GnbLibGetHeader (Pcie)); + PP_FUSE_ARRAY_V2_fld32[0] = (UINT8) ((D0F0xBC_xC0104007 >> 5) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[1] = (UINT8) ((D0F0xBC_xC0104008 >> 5) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[2] = (UINT8) ((D0F0xBC_xC0104008 >> 13) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[3] = (UINT8) ((D0F0xBC_xC0104008 >> 21) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[4] = (UINT8) ((D0F0xBC_xC010407C >> 20) & 0xFF); + Index = (UINT8) ((D0F0xBC_xC0107064 >> 11) & 7); + } else { + PP_FUSE_ARRAY_V2_fld32[0] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[0]; + PP_FUSE_ARRAY_V2_fld32[1] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[1]; + PP_FUSE_ARRAY_V2_fld32[2] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[2]; + PP_FUSE_ARRAY_V2_fld32[3] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[3]; + PP_FUSE_ARRAY_V2_fld32[4] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[4]; + Index = PpF1Array->PcieGen2Vid; + } + if (LinkCap > PcieGen1) { + ASSERT (PP_FUSE_ARRAY_V2_fld32[Index] != 0); + TargetVid = PP_FUSE_ARRAY_V2_fld32[Index]; + } else { + + MinVidIndex = 0; + for (Index = 0; Index < 5; Index++) { + if (PP_FUSE_ARRAY_V2_fld32[Index] > PP_FUSE_ARRAY_V2_fld32[MinVidIndex]) { + MinVidIndex = (UINT8) Index; + } + } + ASSERT (PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0); + TargetVid = PP_FUSE_ARRAY_V2_fld32[MinVidIndex]; + } + + IDS_HDT_CONSOLE (PCIE_MISC, " Set Voltage for Gen %d, Vid code %d\n", LinkCap, TargetVid); + Millivolt = GnbTranslateVidCodeToMillivoltV5 (TargetVid, GnbLibGetHeader (Pcie)) * 4 / 100; + GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), TYPE_SMU_MSG, SMC_MSG_VDDNB_REQUEST, &Millivolt, 0, GnbLibGetHeader (Pcie)); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetVoltageKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL power up latency + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + * @retval Pll wake up latency in us + */ +UINT8 +PciePifGetPllPowerUpLatencyKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + return 35; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get max link speed capability supported by this port + * + * + * + * @param[in] Flags See Flags PCIE_PORT_GEN_CAP_BOOT / PCIE_PORT_GEN_CAP_MAX + * @param[in] Engine Pointer to engine config descriptor + * @retval PcieGen1/PcieGen2 Max supported link gen capability + */ +PCIE_LINK_SPEED_CAP +PcieGetLinkSpeedCapKB ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + PCIE_LINK_SPEED_CAP LinkSpeedCapability; + PCIe_WRAPPER_CONFIG *Wrapper; + PCIe_PLATFORM_CONFIG *Pcie; + + Wrapper = PcieConfigGetParentWrapper (Engine); + Pcie = PcieConfigGetPlatform (Wrapper); + + LinkSpeedCapability = PcieGen2; + + if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGenMaxSupported) { + Engine->Type.Port.PortData.LinkSpeedCapability = (UINT8) LinkSpeedCapability; + } + if (Pcie->PsppPolicy == PsppPowerSaving) { + LinkSpeedCapability = PcieGen1; + } + if (Engine->Type.Port.PortData.LinkSpeedCapability < LinkSpeedCapability) { + LinkSpeedCapability = Engine->Type.Port.PortData.LinkSpeedCapability; + } + if ((Flags & PCIE_PORT_GEN_CAP_BOOT) != 0) { + + if (( Pcie->PsppPolicy == PsppBalanceLow || + Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) + && !PcieConfigIsSbPcieEngine (Engine)) { + + LinkSpeedCapability = PcieGen1; + } + } + return LinkSpeedCapability; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Family specific time stamp function + * + * + * @param[in] StdHeader Standard configuration header + * @retval Count + */ +UINT32 +GnbTimeStampKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TimeStamp; + + TimeStamp = 0; + + GnbLibPciIndirectRead ( + MAKE_SBDFO (0, 0, 0, 0, 0xE0), + 0x13080F0, + AccessWidth32, + &TimeStamp, + StdHeader + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbTsKb: %08x\n", TimeStamp); + return TimeStamp; + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Limit MaxPayload to 256 for x1 ports + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @retval MaxPayload MaxPayloadSupport + */ +UINT8 +PcieMaxPayloadKB ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT8 MaxPayload; + + MaxPayload = MAX_PAYLOAD_512; + if (Engine->EngineData.StartLane == Engine->EngineData.EndLane) { + MaxPayload = MAX_PAYLOAD_256; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMaxPayloadKB Exit with MaxPayload = %d for StartLane = %d and EndLane = %d\n", MaxPayload, Engine->EngineData.StartLane, Engine->EngineData.EndLane); + return MaxPayload; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Select master PLL + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[out] ConfigChanged Pointer to boolean indicator that configuration was changed + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieTopologySelectMasterPllKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT16 MasterLane; + UINT16 MasterHotplugLane; + UINT16 EngineMasterLane; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013_BASE; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); + MasterLane = 0xFFFF; + MasterHotplugLane = 0xFFFF; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieConfigIsEngineAllocated (EngineList) && EngineList->Type.Port.PortData.PortPresent != PortDisabled && PcieConfigIsPcieEngine (EngineList)) { + EngineMasterLane = PcieConfigGetPcieEngineMasterLane (EngineList); + if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + MasterHotplugLane = (EngineMasterLane < MasterHotplugLane) ? EngineMasterLane : MasterHotplugLane; + } else { + MasterLane = (EngineMasterLane < MasterLane) ? EngineMasterLane : MasterLane; + if (PcieConfigIsSbPcieEngine (EngineList)) { + break; + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + + if (MasterLane == 0xffff) { + if (MasterHotplugLane != 0xffff) { + MasterLane = MasterHotplugLane; + } else { + MasterLane = 0x0; + } + } + + D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8013_BASE.Value = D0F0xE4_WRAP_8013.Value; + + if (MasterLane <= 3 ) { + Wrapper->MasterPll = GNB_PCIE_MASTERPLL_A; + } else { + Wrapper->MasterPll = GNB_PCIE_MASTERPLL_B; + } + + IDS_OPTION_HOOK (IDS_GNB_PCIE_MASTERPLL_SELECTION, &(Wrapper->MasterPll), GnbLibGetHeader (Pcie)); + + if (Wrapper->MasterPll == GNB_PCIE_MASTERPLL_A) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + } else { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; + } + + if (ConfigChanged != NULL) { + *ConfigChanged = (D0F0xE4_WRAP_8013.Value == D0F0xE4_WRAP_8013_BASE.Value) ? FALSE : TRUE; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + D0F0xE4_WRAP_8013.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Exit\n"); +} + |