/* $NoKeywords:$ */ /** * @file * * PCIe early post initialization. * * * * @xrefitem bom "File Content Label" "Release Content" * @e project: AGESA * @e sub-project: GNB * @e \$Revision: 87701 $ @e \$Date: 2013-02-07 12:58:51 -0600 (Thu, 07 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 "amdlib.h" #include "Ids.h" #include "Gnb.h" #include "GnbPcie.h" #include "GnbUra.h" #include "GnbCommonLib.h" #include "GnbPcieConfig.h" #include "GnbPcieTrainingV2.h" #include "GnbPcieInitLibV1.h" #include "GnbPcieInitLibV4.h" #include "GnbPcieInitLibV5.h" #include "PcieLibKB.h" #include "PcieComplexDataKB.h" #include "GnbRegistersKB.h" #include "GnbRegisterAccKB.h" #include "OptionGnb.h" #include "GnbSmuInitLibV7.h" #include "Filecode.h" #define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIEEARLYINITKB_FILECODE /*---------------------------------------------------------------------------------------- * D E F I N I T I O N S A N D M A C R O S *---------------------------------------------------------------------------------------- */ extern GNB_BUILD_OPTIONS GnbBuildOptions; extern BUILD_OPT_CFG UserOptions; extern CONST PCIE_HOST_REGISTER_TABLE_HEADER ROMDATA PcieInitEarlyTableKB; extern CONST PCIE_HOST_REGISTER_TABLE_HEADER ROMDATA CoreInitTableKB; extern CONST PCIE_PORT_REGISTER_TABLE_HEADER ROMDATA PortInitEarlyTableKB; /*---------------------------------------------------------------------------------------- * 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 *---------------------------------------------------------------------------------------- */ AGESA_STATUS PcieEarlyInterfaceKB ( IN AMD_CONFIG_PARAMS *StdHeader ); /*----------------------------------------------------------------------------------------*/ /** * Set port device/function mapping * * * * @param[in] Descriptor Silicon descriptor * @param[in] Buffer Pointer to buffer * @param[in] Pcie Pointer to global PCIe configuration */ STATIC AGESA_STATUS PciePortMapInitCallbackKB ( IN PCIe_DESCRIPTOR_HEADER *Descriptor, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PcieSetPortPciAddressMapKB ((PCIe_SILICON_CONFIG *) Descriptor); return AGESA_SUCCESS; } /*----------------------------------------------------------------------------------------*/ /** * Static init for various registers. * * * * @param[in] Pcie Pointer to global PCIe configuration */ VOID STATIC PcieEarlyStaticInitKB ( IN PCIe_PLATFORM_CONFIG *Pcie ) { UINTN Index; for (Index = 0; Index < PcieInitEarlyTableKB.Length; Index++) { GnbLibPciIndirectRMW ( MAKE_SBDFO (0,0,0,0, D0F0xE0_ADDRESS), PcieInitEarlyTableKB.Table[Index].Reg, AccessS3SaveWidth32, (UINT32)~PcieInitEarlyTableKB.Table[Index].Mask, PcieInitEarlyTableKB.Table[Index].Data, GnbLibGetHeader (Pcie) ); } } /*----------------------------------------------------------------------------------------*/ /** * Init core registers. * * * @param[in] Wrapper Pointer to wrapper configuration descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID STATIC PcieEarlyCoreInitKB ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT8 CoreId; UINTN Index; if (PcieLibIsPcieWrapper (Wrapper)) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyCoreInitKB Enter\n"); for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { for (Index = 0; Index < CoreInitTableKB.Length; Index++) { UINT32 Value; Value = PcieRegisterRead ( Wrapper, CORE_SPACE (CoreId, CoreInitTableKB.Table[Index].Reg), Pcie ); Value &= (~CoreInitTableKB.Table[Index].Mask); Value |= CoreInitTableKB.Table[Index].Data; PcieRegisterWrite ( Wrapper, CORE_SPACE (CoreId, CoreInitTableKB.Table[Index].Reg), Value, FALSE, Pcie ); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyCoreInitKB Exit\n"); } } /*----------------------------------------------------------------------------------------*/ /** * Set Pcie Phy Isolation * * * @param[in] Wrapper Pointer to wrapper configuration descriptor * @param[in] Pcie Pointer to PCIe configuration data area */ VOID STATIC PciePhyIsolationKB ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT32 ActiveLaneBitmap; UINT32 PhyRxIsoDis; D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; UINT32 D0F0xE4_WRAP_8021; UINT32 D0F0xE4_WRAP_8022; UINT32 D0F0xE4_WRAP_8025; UINT32 D0F0xE4_WRAP_8026; IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyIsolationKB Enter\n"); // Apply lane mux D0F0xE4_WRAP_8021 = 0x07060504; D0F0xE4_WRAP_8022 = 0x03020100; D0F0xE4_WRAP_8025 = 0x07060504; D0F0xE4_WRAP_8026 = 0x03020100; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS), D0F0xE4_WRAP_8021, FALSE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8022_ADDRESS), D0F0xE4_WRAP_8022, FALSE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), D0F0xE4_WRAP_8025, FALSE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8026_ADDRESS), D0F0xE4_WRAP_8026, FALSE, Pcie ); PhyRxIsoDis = GnbBuildOptions.CfgPciePhyIsolationEnable ? 0 : 3; ActiveLaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, Wrapper); if ((ActiveLaneBitmap & 0xF0) != 0) { PhyRxIsoDis = 3; } IDS_OPTION_HOOK (IDS_GNB_PCIE_PHY_ISOLATION, &PhyRxIsoDis, GnbLibGetHeader (Pcie)); D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), Pcie ); D0F0xE4_WRAP_8013.Field.PhyRxIsoDis = PhyRxIsoDis; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), D0F0xE4_WRAP_8013.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, " ActiveLaneBitmap = 0x%x, PhyRxIsoDis = %d\n", ActiveLaneBitmap, PhyRxIsoDis); IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyIsolationKB Exit\n"); } UINT8 LaneMuxSelectorArrayKB[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; /*----------------------------------------------------------------------------------------*/ /** * Locate mux array index * * * * @param[in, out] LaneMuxSelectorArrayPtr Pointer to mux selector array * @param[in] LaneMuxValue The value that match to array * @retval Index Index successfully mapped */ STATIC UINT8 PcieTopologyLocateMuxIndexKB ( IN OUT UINT8 *LaneMuxSelectorArrayPtr, IN UINT8 LaneMuxValue ) { UINT8 Index; for (Index = 0; Index < sizeof (LaneMuxSelectorArrayKB); Index++ ) { if (LaneMuxSelectorArrayPtr [Index] == LaneMuxValue) { return Index; } } return 0; } /*----------------------------------------------------------------------------------------*/ /** * Apply lane mux * * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ STATIC VOID PcieTopologyApplyLaneMuxKB ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT32 Index; UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayKB)]; UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayKB)]; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxKB Enter\n"); if (PcieLibIsPcieWrapper (Wrapper)) { LibAmdMemCopy ( &TxLaneMuxSelectorArray[0], &LaneMuxSelectorArrayKB[0], sizeof (LaneMuxSelectorArrayKB), GnbLibGetHeader (Pcie) ); LibAmdMemCopy ( &RxLaneMuxSelectorArray[0], &LaneMuxSelectorArrayKB[0], sizeof (LaneMuxSelectorArrayKB), GnbLibGetHeader (Pcie) ); EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { UINT32 CoreLaneBitmap; UINT32 PifLaneBitmap; UINT8 CurrentCoreLane; UINT8 CurrentPifLane; CoreLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_CORE_ALLOC, 0, EngineList); PifLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, EngineList); while (CoreLaneBitmap != 0) { CurrentCoreLane = LibAmdBitScanForward (CoreLaneBitmap); CurrentPifLane = LibAmdBitScanForward (PifLaneBitmap); if (TxLaneMuxSelectorArray[CurrentPifLane] != CurrentCoreLane) { TxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexKB (TxLaneMuxSelectorArray, CurrentCoreLane)] = TxLaneMuxSelectorArray[CurrentPifLane]; TxLaneMuxSelectorArray[CurrentPifLane] = CurrentCoreLane; } if (RxLaneMuxSelectorArray[CurrentCoreLane] != CurrentPifLane) { RxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexKB (RxLaneMuxSelectorArray, CurrentPifLane)] = RxLaneMuxSelectorArray[CurrentCoreLane]; RxLaneMuxSelectorArray[CurrentCoreLane] = CurrentPifLane; } CoreLaneBitmap &= (~ (1 << CurrentCoreLane)); PifLaneBitmap &= (~ (1 << CurrentPifLane)); } } EngineList = PcieLibGetNextDescriptor (EngineList); } for (Index = 0; Index < 2; ++Index) { PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS + Index), ((UINT32 *) TxLaneMuxSelectorArray) [Index], FALSE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS + Index), ((UINT32 *) RxLaneMuxSelectorArray) [Index], FALSE, Pcie ); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxKB Exit\n"); } /*----------------------------------------------------------------------------------------*/ /** * Execute/clean up reconfiguration * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ STATIC VOID PcieTopologyExecuteReconfigKB ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; PCIe_SILICON_CONFIG *Silicon; DEV_OBJECT DevObject; if (PcieLibIsPcieWrapper (Wrapper)) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigKB Enter\n"); D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), Pcie ); D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; D0F0xE4_WRAP_8062.Field.ResetPeriod = 0x2; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), D0F0xE4_WRAP_8062.Value, FALSE, Pcie ); Silicon = PcieConfigGetParentSilicon (Wrapper); GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0xB8_ADDRESS, 0x3f81c, AccessWidth32, (UINT32) ~0xff00, Wrapper->WrapId << 8, GnbLibGetHeader (Pcie) ); DevObject.StdHeader = GnbLibGetHeader (Pcie); DevObject.GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); DevObject.DevPciAddress.AddressValue = Silicon->Address.AddressValue; GnbSmuServiceRequestV7 ( &DevObject, 25, //SMC_MSG_RECONFIGURE, 0, 0 ); D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x1; D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x0; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), D0F0xE4_WRAP_8062.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigKB Exit\n"); } } /*----------------------------------------------------------------------------------------*/ /** * Apply Misc settings for given wrapper * * * * @param[in] Wrapper Pointer to Wrapper config descriptor * @param[in] Pcie Pointer to PICe configuration data area */ STATIC VOID PcieMiscInitKB ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0xE4_WRAP_8011_STRUCT D0F0xE4_WRAP_8011; GnbRegistersKB4915_STRUCT GnbRegistersKB4915; GnbRegistersKB4940_STRUCT GnbRegistersKB4940; GnbRegistersKB4965_STRUCT GnbRegistersKB4965; GnbRegistersKB4990_STRUCT GnbRegistersKB4990; GnbRegistersKB5015_STRUCT GnbRegistersKB5015; IDS_HDT_CONSOLE (GNB_TRACE, "PcieMiscInitKB Enter\n"); D0F0xE4_WRAP_8011.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), Pcie ); D0F0xE4_WRAP_8011.Field.Bitfield_23_23 = 0; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), D0F0xE4_WRAP_8011.Value, TRUE, Pcie ); GnbRegistersKB4915.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x805), Pcie ); GnbRegistersKB4940.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x905), Pcie ); GnbRegistersKB4965.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x0A05), Pcie ); GnbRegistersKB4990.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x0B05), Pcie ); GnbRegistersKB5015.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x0C05), Pcie ); GnbRegistersKB4915.Field.bit_31_24 = 0x40; GnbRegistersKB4940.Field.bit_31_24 = 0x40; GnbRegistersKB4965.Field.bit_31_24 = 0x40; GnbRegistersKB4990.Field.bit_31_24 = 0x40; GnbRegistersKB5015.Field.bit_31_24 = 0x40; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x805), GnbRegistersKB4915.Value, TRUE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x905), GnbRegistersKB4940.Value, TRUE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x0A05), GnbRegistersKB4965.Value, TRUE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x0B05), GnbRegistersKB4990.Value, TRUE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x0C05), GnbRegistersKB5015.Value, TRUE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieMiscInitKB Exit\n"); } /*----------------------------------------------------------------------------------------*/ /** * Switch to PCIe Native Gen1 PLL. * * * @param[in] Pcie Pointer to global PCIe configuration */ AGESA_STATUS STATIC PcieNativeGen1PLLSwitchKB ( IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIE_LINK_SPEED_CAP GlobalSpeedCap; UINT32 ParamValue; IDS_HDT_CONSOLE (GNB_TRACE, "PcieNativeGen1PLLSwitchKB Enter\n"); GlobalSpeedCap = PcieUtilGlobalGenCapability ( PCIE_PORT_GEN_CAP_MAX | PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS | PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS, Pcie ); ParamValue = 0; if (GlobalSpeedCap == PcieGen1) { GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), TYPE_SMU_MSG, 87, &ParamValue, 0, GnbLibGetHeader (Pcie)); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieNativeGen1PLLSwitchKB Exit\n"); return AGESA_SUCCESS; } /*----------------------------------------------------------------------------------------*/ /** * Per wrapper Pcie Init prior training. * * * @param[in] Wrapper Pointer to wrapper configuration descriptor * @param[in] Buffer Pointer buffer * @param[in] Pcie Pointer to global PCIe configuration */ AGESA_STATUS STATIC PcieEarlyInitCallbackKB ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { AGESA_STATUS Status; BOOLEAN CoreConfigChanged; BOOLEAN PllConfigChanged; IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitCallbackKB Enter\n"); CoreConfigChanged = FALSE; PllConfigChanged = FALSE; IDS_OPTION_HOOK (IDS_BEFORE_RECONFIGURATION, Pcie, GnbLibGetHeader (Pcie)); PcieTopologyPrepareForReconfig (Wrapper, Pcie); Status = PcieTopologySetCoreConfig (Wrapper, &CoreConfigChanged, Pcie); ASSERT (Status == AGESA_SUCCESS); PciePhyIsolationKB (Wrapper, Pcie); PcieTopologyApplyLaneMuxKB (Wrapper, Pcie); PciePifSetRxDetectPowerMode (Wrapper, Pcie); PciePifSetLs2ExitTimeV5 (Wrapper, Pcie); PciePifApplyGanging (Wrapper, Pcie); PcieTopologySelectMasterPllKB (Wrapper, &PllConfigChanged, Pcie); PcieMiscInitKB (Wrapper, Pcie); PcieTopologyExecuteReconfigKB (Wrapper, Pcie); PcieTopologyCleanUpReconfig (Wrapper, Pcie); PcieTopologySetLinkReversalV4 (Wrapper, Pcie); PciePifPllConfigureKB (Wrapper, Pcie); PcieTopologyLaneControlV5 ( DisableLanes, PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_CORE_ALLOC, Wrapper), Wrapper, Pcie ); PciePollPifForCompeletion (Wrapper, Pcie); PcieEarlyCoreInitKB (Wrapper, Pcie); PcieSetSsidV4 (UserOptions.CfgGnbPcieSSID, Wrapper, Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitCallbackKB Exit [%x]\n", Status); return Status; } /*----------------------------------------------------------------------------------------*/ /** * Pcie Init * * * * @param[in] Pcie Pointer to global PCIe configuration * @retval AGESA_SUCCESS Topology successfully mapped * @retval AGESA_ERROR Topology can not be mapped */ AGESA_STATUS STATIC PcieEarlyInitKB ( IN PCIe_PLATFORM_CONFIG *Pcie ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; BOOLEAN NativeGen1PLL; IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitKB Enter\n"); AgesaStatus = AGESA_SUCCESS; NativeGen1PLL = GnbBuildOptions.CfgNativeGen1PLL; Status = PcieConfigRunProcForAllDescriptors (DESCRIPTOR_SILICON, 0, DESCRIPTOR_TERMINATE_TOPOLOGY, PciePortMapInitCallbackKB, NULL, Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); IDS_OPTION_HOOK (IDS_GNB_PMM_NATIVEGEN1PLL, &NativeGen1PLL, GnbLibGetHeader (Pcie)); if (NativeGen1PLL == TRUE) { Status = PcieNativeGen1PLLSwitchKB (Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); } Status = PcieConfigRunProcForAllWrappers (DESCRIPTOR_ALL_WRAPPERS, PcieEarlyInitCallbackKB, NULL, Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); PcieEarlyStaticInitKB (Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitKB Exit [%x]\n", AgesaStatus); return AgesaStatus; } /*----------------------------------------------------------------------------------------*/ /** * Set misc slot capability * * * * @param[in] Engine Pointer to engine config descriptor * @param[in] Pcie Pointer to global PCIe configuration * */ VOID STATIC PcieLinkSetSlotCapKB ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT32 IntPin; PCIe_WRAPPER_CONFIG *Wrapper; GnbLibPciRMW ( Engine->Type.Port.Address.AddressValue | DxF0x58_ADDRESS, AccessWidth32, 0xffffffff, 1 << DxF0x58_SlotImplemented_OFFSET, GnbLibGetHeader (Pcie) ); if (Engine->Type.Port.Address.Address.Function < 5) { IntPin = Engine->Type.Port.Address.Address.Function; } else { IntPin = Engine->Type.Port.Address.Address.Function - 4; } GnbLibPciRMW ( Engine->Type.Port.Address.AddressValue | DxF0x3C_ADDRESS, AccessWidth32, 0xffffffff, IntPin << DxF0x3C_IntPin_OFFSET, GnbLibGetHeader (Pcie) ); // Set MaxPayload straps for port if (Engine->EngineData.StartLane == Engine->EngineData.EndLane) { IDS_HDT_CONSOLE (GNB_TRACE, "Set MaxPayload strap for StartLane = %d and EndLane = %d\n", Engine->EngineData.StartLane, Engine->EngineData.EndLane); Wrapper = PcieConfigGetParentWrapper (Engine); PcieRegisterRMW ( Wrapper, WRAP_SPACE (Wrapper->WrapId, 0x804 + (Engine->Type.Port.PortId) * 0x100), 0xe, MAX_PAYLOAD_256 << 1, FALSE, Pcie ); } } /*----------------------------------------------------------------------------------------*/ /** * Callback to init various features on all active ports * * * * * @param[in] Engine Pointer to engine config descriptor * @param[in, out] Buffer Not used * @param[in] Pcie Pointer to global PCIe configuration * */ VOID STATIC PcieEarlyPortInitCallbackKB ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackKB Enter\n"); ASSERT (Engine->EngineData.EngineType == PciePortEngine); PciePortProgramRegisterTable (PortInitEarlyTableKB.Table, PortInitEarlyTableKB.Length, Engine, FALSE, Pcie); PcieSetLinkSpeedCapV4 (PcieGen1, Engine, Pcie); PcieSetLinkWidthCap (Engine, Pcie); PcieCompletionTimeout (Engine, Pcie); PcieLinkSetSlotCapKB (Engine, Pcie); PcieLinkInitHotplugV5 (Engine, Pcie); PciePhyChannelCharacteristicV5 (Engine, Pcie); if (Engine->Type.Port.PortData.PortPresent == PortDisabled || (Engine->Type.Port.PortData.EndpointStatus == EndpointNotPresent && Engine->Type.Port.PortData.LinkHotplug != HotplugEnhanced && Engine->Type.Port.PortData.LinkHotplug != HotplugServer)) { ASSERT (!PcieConfigIsSbPcieEngine (Engine)); // // Pass endpoint status in scratch // PciePortRegisterRMW ( Engine, 0x1, 0x1, 0x1, FALSE, Pcie ); PcieTrainingSetPortState (Engine, LinkStateDeviceNotPresent, FALSE, Pcie); } if (PcieConfigIsSbPcieEngine (Engine)) { PcieTrainingSetPortState (Engine, LinkStateTrainingSuccess, FALSE, Pcie); } if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { PcieTrainingSetPortState (Engine, LinkStateTrainingCompleted, FALSE, Pcie); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackKB Exit\n"); } /*----------------------------------------------------------------------------------------*/ /** * Callback to init various features on all active ports * * * * * @param[in] Engine Pointer to engine config descriptor * @param[in, out] Buffer Not used * @param[in] Pcie Pointer to global PCIe configuration * */ VOID STATIC DdiEarlyPortInitCallbackKB ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT32 GMMx6464; UINT32 GMMx5C6C; UINT32 GMMx5C90; IDS_HDT_CONSOLE (GNB_TRACE, "DdiEarlyPortInitCallbackKB Enter\n"); if ((Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDP) || (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDpToLvds) || (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvds) || (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvdsSwInit)) { IDS_HDT_CONSOLE (GNB_TRACE, "Found eDP/LVDS Connector\n"); GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x6464, &GMMx6464, 0, GnbLibGetHeader (Pcie)); GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c90, &GMMx5C90, 0, GnbLibGetHeader (Pcie)); GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c6c, &GMMx5C6C, 0, GnbLibGetHeader (Pcie)); GMMx6464 |= 1; GMMx6464 |= 1 << 4; GMMx6464 |= 1 << 25; GMMx5C90 &= ~0x3f00; GMMx5C90 |= 1 << 8; GMMx5C6C &= ~0x1800; GMMx5C6C |= 1 << 13; GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x6464, &GMMx6464, 0, GnbLibGetHeader (Pcie)); GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c90, &GMMx5C90, 0, GnbLibGetHeader (Pcie)); GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c6c, &GMMx5C6C, 0, GnbLibGetHeader (Pcie)); } IDS_HDT_CONSOLE (GNB_TRACE, "DdiEarlyPortInitCallbackKB Exit\n"); } /*----------------------------------------------------------------------------------------*/ /** * Master procedure to init various features on all active ports * * * @param[in] Pcie Pointer to global PCIe configuration * @retval AGESA_STATUS * */ AGESA_STATUS STATIC PcieEarlyPortInitKB ( IN PCIe_PLATFORM_CONFIG *Pcie ) { AGESA_STATUS Status; Status = AGESA_SUCCESS; // Leave all device in Presence Detect Presence state for distributed training will be completed at PciePortPostEarlyInit if (Pcie->TrainingAlgorithm == PcieTrainingDistributed) { Pcie->TrainingExitState = LinkStateResetExit; } PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, PcieEarlyPortInitCallbackKB, NULL, Pcie ); PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, DdiEarlyPortInitCallbackKB, NULL, Pcie ); return Status; } /*----------------------------------------------------------------------------------------*/ /** * PCIe Early Post Init * * * * @param[in] StdHeader Standard configuration header * @retval AGESA_STATUS */ AGESA_STATUS PcieEarlyInterfaceKB ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; PCIe_PLATFORM_CONFIG *Pcie; AgesaStatus = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInterfaceKB Enter\n"); Status = PcieLocateConfigurationData (StdHeader, &Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_SUCCESS) { PciePortsVisibilityControlV5 (UnhidePorts, Pcie); Status = PcieEarlyInitKB (Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); ASSERT (Status == AGESA_SUCCESS); Status = PcieEarlyPortInitKB (Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); ASSERT (Status == AGESA_SUCCESS); Status = PcieTraining (Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); ASSERT (Status == AGESA_SUCCESS); IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_PCIE_PHY_CONFIG, Pcie, StdHeader); PciePortsVisibilityControlV5 (HidePorts, Pcie); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInterfaceKB Exit [0x%x]\n", AgesaStatus); return AgesaStatus; }