/* $NoKeywords:$ */ /** * @file * * GNB function to create/locate PCIe configuration data area * * Contain code that create/locate and rebase configuration data area. * * @xrefitem bom "File Content Label" "Release Content" * @e project: AGESA * @e sub-project: GNB * @e \$Revision: 39898 $ @e \$Date: 2010-10-15 17:08:45 -0400 (Fri, 15 Oct 2010) $ * */ /* ***************************************************************************** * * 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 "Ids.h" #include "amdlib.h" #include "heapManager.h" #include "Gnb.h" #include "GnbPcie.h" #include "GnbPcieFamServices.h" #include GNB_MODULE_DEFINITIONS (GnbCommonLib) #include GNB_MODULE_DEFINITIONS (GnbPcieConfig) #include "PcieMapTopology.h" #include "PcieInputParser.h" #include "Filecode.h" #define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIECONFIGDATA_FILECODE /*---------------------------------------------------------------------------------------- * D E F I N I T I O N S A N D M A C R O S *---------------------------------------------------------------------------------------- */ #define REBASE_PTR( Ptr, OldBase, NewBase) *(UINTN *)Ptr = (*(UINTN *)Ptr + (UINTN) NewBase - (UINTN) OldBase); extern BUILD_OPT_CFG UserOptions; /*---------------------------------------------------------------------------------------- * 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 *---------------------------------------------------------------------------------------- */ VOID PcieConfigDebugDump ( IN PCIe_PLATFORM_CONFIG *Pcie ); /*----------------------------------------------------------------------------------------*/ /** * Create internal PCIe configuration data * * * * @param[in] StdHeader Standard configuration header * @retval AGESA_SUCCESS Configuration data successfully allocated. * @retval AGESA_FATAL Configuration data allocation failed. */ AGESA_STATUS PcieConfigurationInit ( IN AMD_CONFIG_PARAMS *StdHeader ) { AMD_EARLY_PARAMS *EarlyParamsPtr; PCIe_COMPLEX_DESCRIPTOR *ComplexList; PCIe_PLATFORM_CONFIG *Pcie; AGESA_STATUS AgesaStatus; AGESA_STATUS Status; PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor; UINTN ComplexesDataLength; UINTN ComplexIndex; UINTN NumberOfComplexes; VOID *Buffer; UINTN Index; UINT32 NumberOfSockets; UINT32 SocketId; IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Enter\n"); EarlyParamsPtr = (AMD_EARLY_PARAMS *) StdHeader; ComplexList = EarlyParamsPtr->GnbConfig.PcieComplexList; AgesaStatus = AGESA_SUCCESS; ComplexesDataLength = 0; NumberOfSockets = GnbGetNumberOfSockets (StdHeader); for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) { if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) { UINTN CurrentComplexesDataLength; Status = PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength); ASSERT (Status == AGESA_SUCCESS); ComplexesDataLength += CurrentComplexesDataLength; } } NumberOfComplexes = PcieInputParserGetNumberOfComplexes (ComplexList); Pcie = GnbAllocateHeapBuffer (AMD_PCIE_COMPLEX_DATA_HANDLE, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader); if (Pcie == NULL) { IDS_ERROR_TRAP; return AGESA_FATAL; } LibAmdMemFill (Pcie, 0x00, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader); Pcie->StdHeader = (PVOID) StdHeader; Pcie->This = (UINTN) (Pcie); Buffer = (UINT8 *) (Pcie) + sizeof (PCIe_PLATFORM_CONFIG); ComplexIndex = 0; for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) { if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) { UINTN CurrentComplexesDataLength; if (ComplexIndex > MAX_NUMBER_OF_COMPLEXES) { IDS_ERROR_TRAP; return AGESA_FATAL; } Pcie->ComplexList[ComplexIndex].SiliconList = (PPCIe_SILICON_CONFIG) Buffer; PcieFmBuildComplexConfiguration (Buffer, StdHeader); for (Index = 0; Index < NumberOfComplexes; Index++) { ComplexDescriptor = PcieInputParserGetComplexDescriptor (ComplexList, Index); if (ComplexDescriptor->SocketId == SocketId) { Status = PcieMapTopologyOnComplex (ComplexDescriptor, &Pcie->ComplexList[Index], Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); } } PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength); Buffer = (VOID *) ((UINT8 *)Buffer + CurrentComplexesDataLength); ComplexIndex++; } } Pcie->ComplexList[ComplexIndex - 1].Flags |= DESCRIPTOR_TERMINATE_LIST; Pcie->LinkReceiverDetectionPooling = PCIE_LINK_RECEIVER_DETECTION_POOLING; Pcie->LinkL0Pooling = PCIE_LINK_L0_POOLING; Pcie->LinkGpioResetAssertionTime = PCIE_LINK_GPIO_RESET_ASSERT_TIME; Pcie->LinkResetToTrainingTime = PCIE_LINK_RESET_TO_TRAINING_TIME; Pcie->GfxCardWorkaround = GfxWorkaroundEnable; if ((UserOptions.CfgAmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { Pcie->GfxCardWorkaround = GfxWorkaroundDisable; } Pcie->PsppPolicy = EarlyParamsPtr->GnbConfig.PsppPolicy; IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_PCIE_PLATFORM_CONFIG, Pcie, StdHeader); GNB_DEBUG_CODE ( PcieConfigDebugDump (Pcie); ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Exit [0x%x]\n", AgesaStatus); return AgesaStatus; } /*----------------------------------------------------------------------------------------*/ /** * Locate global PCIe configuration data * * * * @param[in] StdHeader Standard configuration header * @param[out] Pcie Pointer to global PCIe configuration * @retval AGESA_SUCCESS Configuration data successfully located * @retval AGESA_FATAL Configuration can not be located. */ AGESA_STATUS PcieLocateConfigurationData ( IN AMD_CONFIG_PARAMS *StdHeader, OUT PCIe_PLATFORM_CONFIG **Pcie ) { PCIe_COMPLEX_CONFIG *Complex; *Pcie = GnbLocateHeapBuffer (AMD_PCIE_COMPLEX_DATA_HANDLE, StdHeader); if (*Pcie == NULL) { IDS_ERROR_TRAP; return AGESA_FATAL; } if ((UINTN) (*Pcie) != (UINTN) (*Pcie)->This) { Complex = &(*Pcie)->ComplexList[0]; while (Complex != NULL) { PCIe_SILICON_CONFIG *SiliconList; REBASE_PTR (&Complex->SiliconList, (UINTN) (*Pcie)->This, (UINTN)*Pcie); SiliconList = PcieComplexGetSiliconList (Complex); PcieRebaseConfigurationData (SiliconList, (UINTN) (*Pcie)->This, (UINTN)*Pcie); Complex = PcieLibGetNextDescriptor (Complex); } (*Pcie)->This = (UINTN)(*Pcie); } (*Pcie)->StdHeader = (PVOID) StdHeader; return AGESA_SUCCESS; } /*----------------------------------------------------------------------------------------*/ /** * Rebase all pointers in Complex Configuration Data * * * * @param[in] SiliconList Pointer to first silicon descriptor of the complex * @param[in] OldBase Old base address of the configuration data * @param[in] NewBase New base address of the configuration data */ VOID PcieRebaseConfigurationData ( IN PCIe_SILICON_CONFIG *SiliconList, IN UINTN OldBase, IN UINTN NewBase ) { while (SiliconList != NULL) { PCIe_WRAPPER_CONFIG *WrapperList; REBASE_PTR (&SiliconList->WrapperList, OldBase, NewBase); REBASE_PTR (&SiliconList->FmSilicon, OldBase, NewBase); WrapperList = PcieSiliconGetWrapperList (SiliconList); while (WrapperList != NULL) { PCIe_ENGINE_CONFIG *EngineList; REBASE_PTR (&WrapperList->EngineList, OldBase, NewBase); REBASE_PTR (&WrapperList->FmWrapper, OldBase, NewBase); REBASE_PTR (&WrapperList->Silicon, OldBase, NewBase); EngineList = PcieWrapperGetEngineList (WrapperList); while (EngineList != NULL) { REBASE_PTR (&EngineList->Wrapper, OldBase, NewBase); EngineList = PcieLibGetNextDescriptor (EngineList); } WrapperList = PcieLibGetNextDescriptor (WrapperList); } SiliconList = PcieLibGetNextDescriptor (SiliconList); } } /*----------------------------------------------------------------------------------------*/ /** * Helper function to dump configuration to debug out * * * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieConfigDebugDump ( IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; PCIe_SILICON_CONFIG *SiliconList; PCIe_WRAPPER_CONFIG *WrapperList; PCIe_COMPLEX_CONFIG *ComplexList; ComplexList = &Pcie->ComplexList[0]; IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config Start----------------->\n"); IDS_HDT_CONSOLE (PCIE_MISC, " PSPP Policy - %s\n", (Pcie->PsppPolicy == PsppPowerSaving) ? "Power Saving" : (Pcie->PsppPolicy == PsppBalanceHigh) ? "Balance-High" : ( (Pcie->PsppPolicy == PsppBalanceLow) ? "Balance-Low" : ( (Pcie->PsppPolicy == PsppPerformance) ? "Performance" : ( (Pcie->PsppPolicy == PsppDisabled) ? "Disabled" : "Unknown"))) ); IDS_HDT_CONSOLE (PCIE_MISC, " GFX Workaround - %s\n", (Pcie->GfxCardWorkaround == 0) ? "Disabled" : "Enabled" ); IDS_HDT_CONSOLE (PCIE_MISC, " LinkL0Pooling - %dus\n", Pcie->LinkL0Pooling ); IDS_HDT_CONSOLE (PCIE_MISC, " LinkGpioResetAssertionTime - %dus\n", Pcie->LinkGpioResetAssertionTime ); IDS_HDT_CONSOLE (PCIE_MISC, " LinkReceiverDetectionPooling - %dus\n", Pcie->LinkReceiverDetectionPooling ); SiliconList = PcieComplexGetSiliconList (ComplexList); while (SiliconList != NULL) { WrapperList = PcieSiliconGetWrapperList (SiliconList); while (WrapperList != NULL) { IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config -------->\n", PcieFmDebugGetWrapperNameString (WrapperList) ); IDS_HDT_CONSOLE (PCIE_MISC, " PowerOffUnusedLanes - %x\n PowerOffUnusedPlls - %x\n ClkGating - %x\n" " LclkGating - %x\n TxclkGatingPllPowerDown - %x\n PllOffInL1 - %x\n", WrapperList->Features.PowerOffUnusedLanes, WrapperList->Features.PowerOffUnusedPlls, WrapperList->Features.ClkGating, WrapperList->Features.LclkGating, WrapperList->Features.TxclkGatingPllPowerDown, WrapperList->Features.PllOffInL1 ); IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config End----->\n", PcieFmDebugGetWrapperNameString (WrapperList) ); EngineList = PcieWrapperGetEngineList (WrapperList); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { IDS_HDT_CONSOLE (PCIE_MISC, " Engine Type - %s\n Start Phy Lane - %d\n End Phy Lane - %d\n", ((EngineList->EngineData.EngineType == PciePortEngine) ? "PCIe Port" : "DDI Link"), EngineList->EngineData.StartLane, EngineList->EngineData.EndLane ); if (PcieLibIsPcieEngine (EngineList)) { IDS_HDT_CONSOLE (PCIE_MISC, " PCIe port configuration:\n"); IDS_HDT_CONSOLE (PCIE_MISC, " Port Training - %s\n", (EngineList->Type.Port.PortData.PortPresent == PortDisabled) ? "Disable" : "Enabled" ); IDS_HDT_CONSOLE (PCIE_MISC, " Start Core Lane - %d\n", EngineList->Type.Port.StartCoreLane); IDS_HDT_CONSOLE (PCIE_MISC, " End Core Lane - %d\n", EngineList->Type.Port.EndCoreLane); IDS_HDT_CONSOLE (PCIE_MISC, " PCI Address - %d:%d:%d\n", EngineList->Type.Port.Address.Address.Bus, EngineList->Type.Port.Address.Address.Device, EngineList->Type.Port.Address.Address.Function ); IDS_HDT_CONSOLE (PCIE_MISC, " Native PCI Dev Number - %d\n", EngineList->Type.Port.NativeDevNumber); IDS_HDT_CONSOLE (PCIE_MISC, " Native PCI Func Number - %d\n", EngineList->Type.Port.NativeFunNumber); IDS_HDT_CONSOLE (PCIE_MISC, " Hotplug - %s\n", (EngineList->Type.Port.PortData.LinkHotplug == 0) ? "Disabled" : ( (EngineList->Type.Port.PortData.LinkHotplug == 1) ? "Basic" : ( (EngineList->Type.Port.PortData.LinkHotplug == 2) ? "Server" : ( (EngineList->Type.Port.PortData.LinkHotplug == 2) ? "Enhanced" : "Unknown"))) ); IDS_HDT_CONSOLE (PCIE_MISC, " ASPM - %s\n", (EngineList->Type.Port.PortData.LinkAspm == 0) ? "Disabled" : ( (EngineList->Type.Port.PortData.LinkAspm == 1) ? "L0s" : ( (EngineList->Type.Port.PortData.LinkAspm == 2) ? "L1" : ( (EngineList->Type.Port.PortData.LinkAspm == 3) ? "L0s & L1" : "Unknown"))) ); IDS_HDT_CONSOLE (PCIE_MISC, " Speed - %d\n", EngineList->Type.Port.PortData.LinkSpeedCapability ); } else { IDS_HDT_CONSOLE (PCIE_MISC, " DDI configuration:\n"); IDS_HDT_CONSOLE (PCIE_MISC, " Connector - %s\n", (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDP) ? "DP" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDP) ? "eDP" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeSingleLinkDVI) ? "Single Link DVI" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDualLinkDVI) ? "Dual Link DVI" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeHDMI) ? "HDMI" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeTravisDpToVga) ? "Travis DP-to-VGA" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeTravisDpToLvds) ? "Travis DP-to-LVDS" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeLvds) ? "LVDS" : ( (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeNutmegDpToVga) ? "Hudson-2 Nutmeg DP-to-VGA" : "Unknown")))))))) ); IDS_HDT_CONSOLE (PCIE_MISC, " Aux - Aux%d\n", EngineList->Type.Ddi.DdiData.AuxIndex + 1); IDS_HDT_CONSOLE (PCIE_MISC, " Hdp - Hdp%d\n", EngineList->Type.Ddi.DdiData.HdpIndex + 1); } } EngineList = PcieLibGetNextDescriptor (EngineList); } WrapperList = PcieLibGetNextDescriptor (WrapperList); } SiliconList = PcieLibGetNextDescriptor (SiliconList); } IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config End------------------>\n"); }