diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c new file mode 100644 index 0000000000..0fb763b33a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c @@ -0,0 +1,463 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87263 $ @e \$Date: 2013-01-31 09:18:06 -0600 (Thu, 31 Jan 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 "amdlib.h" +#include "heapManager.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbNbInitLibV1.h" +#include "OptionGnb.h" +#include "PcieAlibV2.h" +#include "GnbF1Table.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_MODULES_GNBPCIEALIBV2_PCIEALIBV2_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern F_ALIB_GET *AlibGetBaseTableV2; +extern F_ALIB_UPDATE *AlibDispatchTableV2[]; +extern GNB_BUILD_OPTIONS ROMDATA GnbBuildOptions; + + +/*---------------------------------------------------------------------------------------- + * 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 +PcieAlibUpdateGnbData ( + IN OUT VOID *SsdtBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PcieAlibUpdatePciePortDataCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieAlibBuildAcpiTableV2 ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **AlibSsdtPtr + ); + +AGESA_STATUS +PcieAlibUpdateVoltageData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieAlibUpdatePcieData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Create ACPI ALIB SSDT table + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PcieAlibV2Feature ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_LATE_PARAMS *LateParamsPtr; + LateParamsPtr = (AMD_LATE_PARAMS*) StdHeader; + return PcieAlibBuildAcpiTableV2 (StdHeader, &LateParamsPtr->AcpiAlib); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build ALIB ACPI table + * + * + * + * @param[in] StdHeader Standard Configuration Header + * @param[in,out] AlibSsdtPtr Pointer to pointer to ALIB SSDT table + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +PcieAlibBuildAcpiTableV2 ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **AlibSsdtPtr + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + UINTN Index; + VOID *AlibSsdtBuffer; + VOID *AlibSsdtTable; + UINTN AlibSsdtlength; + UINT32 AmlObjName; + VOID *AmlObjPtr; + + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTableV2 Enter\n"); + AgesaStatus = AGESA_SUCCESS; + AlibSsdtTable = AlibGetBaseTableV2 (StdHeader); + AlibSsdtlength = ((ACPI_TABLE_HEADER*) AlibSsdtTable)->TableLength; + if (*AlibSsdtPtr == NULL) { + AlibSsdtBuffer = GnbAllocateHeapBuffer ( + AMD_ACPI_ALIB_BUFFER_HANDLE, + AlibSsdtlength, + StdHeader + ); + ASSERT (AlibSsdtBuffer != NULL); + if (AlibSsdtBuffer == NULL) { + return AGESA_ERROR; + } + *AlibSsdtPtr = AlibSsdtBuffer; + } else { + AlibSsdtBuffer = *AlibSsdtPtr; + } + // Check length of port data + ASSERT (sizeof (_ALIB_PORT_DATA) <= 20); + // Check length of global data + ASSERT (sizeof (_ALIB_GLOBAL_DATA) <= 32); + // Copy template to buffer + LibAmdMemCopy (AlibSsdtBuffer, AlibSsdtTable, AlibSsdtlength, StdHeader); + // Update table OEM fields. + LibAmdMemCopy ( + (VOID *) &((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->OemId, + (VOID *) &GnbBuildOptions.OemIdString, + sizeof (GnbBuildOptions.OemIdString), + StdHeader); + LibAmdMemCopy ( + (VOID *) &((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->OemTableId, + (VOID *) &GnbBuildOptions.OemTableIdString, + sizeof (GnbBuildOptions.OemTableIdString), + StdHeader); + // + // Update register base base + // + PcieAlibUpdateGnbData (AlibSsdtBuffer, StdHeader); + // + // Update transfer block + // + AmlObjName = STRING_TO_UINT32 ('A', 'D', 'A', 'T'); + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + if (AmlObjPtr != NULL) { + AmlObjPtr = (UINT8 *) AmlObjPtr + 10; + } + // Dispatch function from table + Index = 0; + while (AlibDispatchTableV2[Index] != NULL) { + Status = AlibDispatchTableV2[Index] (AmlObjPtr, StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + Index++; + } + if (AgesaStatus != AGESA_SUCCESS) { + //Shrink table length to size of the header + ((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->TableLength = sizeof (ACPI_TABLE_HEADER); + } + ChecksumAcpiTable ((ACPI_TABLE_HEADER*) AlibSsdtBuffer, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTableV2 Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update MMIO info + * + * + * + * + * @param[in] SsdtBuffer Pointer to SSDT table + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +PcieAlibUpdateGnbData ( + IN OUT VOID *SsdtBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 LocalMsrRegister; + UINT32 AmlObjName; + VOID *AmlObjPtr; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateGnbData Enter\n"); + // + // Locate Base address variable + // + AmlObjName = STRING_TO_UINT32 ('A', 'G', 'R', 'B'); + AmlObjPtr = GnbLibFind ( + SsdtBuffer, + ((ACPI_TABLE_HEADER*) SsdtBuffer)->TableLength, + (UINT8*) &AmlObjName, + sizeof (AmlObjName) + ); + /// @todo + // ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr == NULL) { + return AGESA_ERROR; + } + // + // Update PCIe MMIO base + // + LibAmdMsrRead (MSR_MMIO_Cfg_Base, &LocalMsrRegister, StdHeader); + if ((LocalMsrRegister & BIT0) != 0 && (LocalMsrRegister & 0xFFFFFFFF00000000) == 0) { + *(UINT32*)((UINT8*) AmlObjPtr + 5) = (UINT32) (LocalMsrRegister & 0xFFFFF00000); + } else { + ASSERT (FALSE); + return AGESA_ERROR; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateGnbData Exit\n"); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update MMIO info + * + * + * + * + * @param[in] DataBuffer Pointer to data buffer + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +PcieAlibUpdateVoltageData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PP_F1_ARRAY_V2 *PpF1Array; + AGESA_STATUS Status; + ALIB_DATA *AlibData; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateVoltageData Enter\n"); + Status = AGESA_SUCCESS; + ASSERT (DataBuffer != NULL); + AlibData = (ALIB_DATA *) DataBuffer; + // + // Locate F1 table + // + PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array != NULL) { + // + // Update GEN1 Vid + // + AlibData->Data.Data.PcieVidGen1 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[0]; + // + // Update GEN2 Vid + // + AlibData->Data.Data.PcieVidGen2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[PpF1Array->PcieGen2Vid]; + // + // Update DPM Mask + // + AlibData->Data.Data.DpmMask = (PpF1Array->PP_FUSE_ARRAY_V2_fld37 + 1); + IDS_HDT_CONSOLE (GNB_TRACE, " DpmMask = %02x\n", AlibData->Data.Data.DpmMask); + // + // Update Boost data + // + AlibData->Data.Data.NumBoostStates = (PpF1Array->PP_FUSE_ARRAY_V2_fld36); + IDS_HDT_CONSOLE (GNB_TRACE, " NumBoost = %02x\n", AlibData->Data.Data.NumBoostStates); + } else { + Status = AGESA_ERROR; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateVoltageData Exit\n"); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Update PCIe info + * + * + * + * + * @param[in] DataBuffer Ponter to data buffer + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +PcieAlibUpdatePcieData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_PLATFORM_CONFIG *Pcie; + AMD_LATE_PARAMS *LateParamsPtr; + AGESA_STATUS Status; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdatePcieData Enter\n"); + ASSERT (DataBuffer != NULL); + Status = AGESA_SUCCESS; + // + // Locate PCIe platform config + // + if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { + // + // Update policy data + // + ((ALIB_DATA *) DataBuffer)->Data.Data.PsppPolicy = Pcie->PsppPolicy; + // + // Update data for each port + // + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_PCIE_ENGINE, + PcieAlibUpdatePciePortDataCallback, + DataBuffer, + Pcie + ); + } else { + ASSERT (FALSE); + Status = AGESA_FATAL; + } + + LateParamsPtr = (AMD_LATE_PARAMS *) StdHeader; + ((ALIB_DATA *) DataBuffer)->Data.Data.DockedTdpHeadroom = + LateParamsPtr->GnbLateConfiguration.DockedTdpHeadroom; + IDS_HDT_CONSOLE (GNB_TRACE, " DockedTdpHeadroom = %02x\n", + LateParamsPtr->GnbLateConfiguration.DockedTdpHeadroom); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdatePcieData Exit\n"); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to update PCIe port data + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieAlibUpdatePciePortDataCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + _ALIB_PORT_DATA *PortData; + + PortData = &((ALIB_DATA *) Buffer)->PortData[Engine->Type.Port.PcieBridgeId].PortData; + + if (PcieConfigIsEngineAllocated (Engine) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS))) { + // + // Various speed capability + // + PortData->PciePortMaxSpeed = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_MAX, Engine); + PortData->PciePortCurSpeed = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); + PortData->PciePortDcSpeed = PcieGen1; + PortData->PciePortAcSpeed = PortData->PciePortMaxSpeed; + if (Pcie->PsppPolicy == PsppBalanceLow) { + PortData->PciePortAcSpeed = PcieGen1; + } + if (PcieConfigIsSbPcieEngine (Engine)) { + PortData->PcieSbPort = 0x1; + PortData->PciePortAcSpeed = PortData->PciePortMaxSpeed; + } + if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode != 0) { + PortData->PcieLinkSafeMode = 0x1; + PortData->PcieLocalOverrideSpeed = Engine->Type.Port.PortData.MiscControls.LinkSafeMode; + } + // + // various port capability + // + PortData->StartPhyLane = (UINT8) Engine->EngineData.StartLane; + PortData->EndPhyLane = (UINT8) Engine->EngineData.EndLane; + PortData->StartCoreLane = (UINT8) Engine->Type.Port.StartCoreLane; + PortData->EndCoreLane = (UINT8) Engine->Type.Port.EndCoreLane; + PortData->PortId = Engine->Type.Port.PortId; + PortData->LinkHotplug = Engine->Type.Port.PortData.LinkHotplug; + PortData->PciDev = (UINT8) Engine->Type.Port.Address.Address.Device; + PortData->PciFun = (UINT8) Engine->Type.Port.Address.Address.Function; + } else { + PortData->PciePortMaxSpeed = PcieGen1; + PortData->PciePortCurSpeed = PcieGen1; + PortData->PciePortDcSpeed = PcieGen1; + PortData->PciePortAcSpeed = PcieGen1; + PortData->PcieLocalOverrideSpeed = PcieGen1; + } +} + |