diff options
author | efdesign98 <efdesign98@gmail.com> | 2011-06-16 16:35:54 -0700 |
---|---|---|
committer | Marc Jones <marcj303@gmail.com> | 2011-06-21 22:37:51 +0200 |
commit | b0969d65e675f7c7a3004fc3f6fc154f22e73d44 (patch) | |
tree | 7e11f186e900ce6fc77603515b85c2a4154c6849 /src/vendorcode/amd/agesa/f12/Proc/GNB/Modules | |
parent | d1cb0eecd130cb4259ce9fedb32ebcd9ada0d4b7 (diff) |
Add AMD Family 12 cpu Agesa code
This is the addition of the AMD Family 12 cpu code.
Change-Id: I3febc81e192b4e86bbd3e8d6e1da62a28598fa8c
Signed-off-by: Frank Vibrans<frank.vibrans@amd.com>
Signed-off-by: efdesign98 <efdesign98@gmail.com>
Reviewed-on: http://review.coreboot.org/40
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Proc/GNB/Modules')
93 files changed, 20675 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCableSafe/GnbCableSafe.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCableSafe/GnbCableSafe.c new file mode 100755 index 0000000000..249768bc58 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCableSafe/GnbCableSafe.c @@ -0,0 +1,249 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Cable safe module + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "OptionGnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbGfxInitLibV1.h" +#include "GnbRegistersLN.h" +#include "cpuFamilyTranslation.h" +#include "NbSmuLib.h" +#include "GnbCableSafeDefs.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCABLESAFE_GNBCABLESAFE_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; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +UINT8 HdpIndexTranslationTable [] = { + 3, 2, 1, 0, 7, 6 +}; + +UINT8 AuxIndexTranslationTable [] = { + 5, 4, 11, 10, 9, 8 +}; + +UINT8 AuxDataTranslationTable [] = { + 0x10, 0x20, 0x40, 0x01, 0x02, 0x04 +}; + +/*---------------------------------------------------------------------------------------- + * 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 +GnbCableSafeEntry ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +GnbCableSafeGetConnectorInfoArrayCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +GnbCableSafeIsSupported ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Cable Safe module entry + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbCableSafeEntry ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_ENGINE_CONFIG *DdiEngineList [MaxHdp]; + UINT8 HdpIndex; + UINT8 CurrentIndex; + GNB_CABLE_SAFE_DATA CableSafeData; + BOOLEAN ForceCableSafeOff; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbCableSafeEntry Enter\n"); + Status = AGESA_SUCCESS; + ForceCableSafeOff = GnbBuildOptions.CfgForceCableSafeOff; + IDS_OPTION_HOOK (IDS_GNB_FORCE_CABLESAFE, &ForceCableSafeOff, StdHeader); + if (GnbCableSafeIsSupported (StdHeader)) { + if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { + for (HdpIndex = 0; HdpIndex < MaxHdp; HdpIndex++) { + DdiEngineList[HdpIndex] = NULL; + } + LibAmdMemFill (&CableSafeData, 0, sizeof (CableSafeData), StdHeader); + if (!ForceCableSafeOff) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE, + GnbCableSafeGetConnectorInfoArrayCallback, + DdiEngineList, + Pcie + ); + CurrentIndex = 0; + for (HdpIndex = 0; HdpIndex < MaxHdp; HdpIndex++) { + if (DdiEngineList [HdpIndex] != NULL) { + CableSafeData.Data[HdpIndexTranslationTable[CurrentIndex]] = HdpIndex + 1; + CableSafeData.Data[AuxIndexTranslationTable[CurrentIndex]] = AuxDataTranslationTable [(DdiEngineList [HdpIndex])->Type.Ddi.DdiData.AuxIndex]; + IDS_HDT_CONSOLE (NB_MISC, " Index [%d] HDP 0x%02x AUX 0x%02x\n", CurrentIndex, HdpIndex, (DdiEngineList [HdpIndex])->Type.Ddi.DdiData.AuxIndex); + CurrentIndex++; + } + } + } else { + GMMx6124_STRUCT GMMx6124; + GMMx6124.Value = 0x3F; + NbSmuSrbmRegisterWrite (SMU_GMM_TO_FCR (GMMx6124_ADDRESS), &GMMx6124.Value, TRUE, GnbLibGetHeader (Pcie)); + GnbLibPciRMW ( + MAKE_SBDFO (0, 0, 0x18, 6, D18F6x80_ADDRESS), + AccessWidth32, + 0xffffffff, + (7 << D18F6x80_CableSafeDisAux_3_1_OFFSET) | (7 << D18F6x80_CableSafeDisAux_6_4_OFFSET), + GnbLibGetHeader (Pcie) + ); + } + CableSafeData.Config.Enable = 0x1; + CableSafeData.Config.DebounceFilter = 0; + CableSafeData.Config.SoftPeriod = 0x4; + CableSafeData.Config.Unit = 0x1; + CableSafeData.Config.Period = 0xf424; + NbSmuRcuRegisterWrite ( + SMUx0B_x85D0_ADDRESS, + (UINT32*) &CableSafeData, + sizeof (CableSafeData) / sizeof (UINT32), + TRUE, + StdHeader + ); + NbSmuServiceRequest (0x05, TRUE, StdHeader); + } else { + Status = AGESA_ERROR; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbCableSafeEntry Exit [Status = 0x%04x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init max port Gen capability + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +GnbCableSafeGetConnectorInfoArrayCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG **EngineList; + EngineList = (PCIe_ENGINE_CONFIG**) Buffer; + EngineList [Engine->Type.Ddi.DdiData.HdpIndex] = Engine; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if feature supported + * + * Module requre for LN B0 and above + * + * + * @param[in] StdHeader Standard configuration header + * @retval TRUE Cable safe needs to be enabled + */ + +BOOLEAN +GnbCableSafeIsSupported ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN Result; + CPU_LOGICAL_ID LogicalId; + SMU_FIRMWARE_REV FirmwareRev; + Result = FALSE; + if (GfxLibIsControllerPresent (StdHeader)) { + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + FirmwareRev = NbSmuFirmwareRevision (StdHeader); + if (SMI_FIRMWARE_REVISION (FirmwareRev) >= 0x010904 && LogicalId.Revision > AMD_F12_LN_A1) { + Result = TRUE; + } + } + return Result; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCableSafe/GnbCableSafeDefs.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCableSafe/GnbCableSafeDefs.h new file mode 100755 index 0000000000..dce430a29e --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCableSafe/GnbCableSafeDefs.h @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Cable safe module + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBCABLESAFEDEFS_H_ +#define _GNBCABLESAFEDEFS_H_ + +#pragma pack (push, 1) + +/// Cable safe data package +typedef struct { + struct { + UINT32 Enable :1; ///< Enable cable safe + UINT32 DebounceFilter :3; ///< Debounce filter + UINT32 SoftPeriod :4; ///< Soft period + UINT32 Unit :4; ///< Unit + UINT32 Reserved :4; ///< Reserved + UINT32 Period :16; ///< Period + } Config; ///< Configuration package + UINT8 Data [12]; ///< HDP/AUX info array +} GNB_CABLE_SAFE_DATA; + +#pragma pack (pop) +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h new file mode 100755 index 0000000000..d71a64e8aa --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h @@ -0,0 +1,58 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49526 $ @e \$Date: 2011-03-25 00:52:37 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ +#ifndef _GNBCOMMONLIB_H_ +#define _GNBCOMMONLIB_H_ + +#include "GnbLib.h" +#include "GnbLibCpuAcc.h" +#include "GnbLibHeap.h" +#include "GnbLibIoAcc.h" +#include "GnbLibMemAcc.h" +#include "GnbLibPci.h" +#include "GnbLibPciAcc.h" +#include "GnbLibStall.h" +#include "GnbTable.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLib.c new file mode 100755 index 0000000000..27ed1b823e --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLib.c @@ -0,0 +1,609 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49047 $ @e \$Date: 2011-03-16 15:27:08 +0800 (Wed, 16 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "cpuFamilyTranslation.h" +#include "cpuServices.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbLibIoAcc.h" +#include "GnbLibPciAcc.h" +#include "GnbLibMemAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_SERVICE *ServiceTable; + +/*---------------------------------------------------------------------------------------- + * 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 +GnbLibPciIndirectReadField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + OUT UINT32 *Value, + IN VOID *Config + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read GNB indirect registers + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] Width Width + * @param[out] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *Config + ) +{ + UINT32 IndexOffset; + IndexOffset = LibAmdAccessWidth (Width); + GnbLibPciWrite (Address, Width, &IndirectAddress, Config); + GnbLibPciRead (Address + IndexOffset, Width, Value, Config); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Read GNB indirect registers field + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[out] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectReadField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + OUT UINT32 *Value, + IN VOID *Config + ) +{ + UINT32 Mask; + GnbLibPciIndirectRead (Address, IndirectAddress, AccessWidth32, Value, Config); + Mask = (1 << FieldWidth) - 1; + *Value = (*Value >> FieldOffset) & Mask; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write GNB indirect registers + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] Width Width + * @param[in] Value Pointer to value + * @param[in] Config Pointer to standard header + */ + +VOID +GnbLibPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *Config + ) +{ + UINT32 IndexOffset; + IndexOffset = LibAmdAccessWidth (Width); + GnbLibPciWrite (Address, Width, &IndirectAddress, Config); + GnbLibPciWrite (Address + IndexOffset, Width, Value, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write GNB indirect registers field + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Value Pointer to value + * @param[in] S3Save Save for S3 (TRUE/FALSE) + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectWriteField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN VOID *Config + ) +{ + UINT32 Data; + UINT32 Mask; + GnbLibPciIndirectRead (Address, IndirectAddress, AccessWidth32, &Data, Config); + Mask = (1 << FieldWidth) - 1; + Data &= (~(Mask << FieldOffset)); + Data |= ((Value & Mask) << FieldOffset); + GnbLibPciIndirectWrite (Address, IndirectAddress, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Data, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write GNB indirect registers field + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] Width Width + * @param[in] Mask And Mask + * @param[in] Value Or Value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectRMW ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibPciIndirectRead ( + Address, + IndirectAddress, + (Width >= AccessS3SaveWidth8) ? (Width - (AccessS3SaveWidth8 - AccessWidth8)) : Width, + &Data, + Config + ); + Data = (Data & Mask) | Value; + GnbLibPciIndirectWrite (Address, IndirectAddress, Width, &Data, Config); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCI registers + * + * + * + * @param[in] Address PCI address + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Value OR Value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciRMW ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibPciRead (Address, Width, &Data, Config); + Data = (Data & Mask) | Value; + GnbLibPciWrite (Address, Width, &Data, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write I/O registers + * + * + * + * @param[in] Address I/O Port + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Value OR Mask + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibIoRMW ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibIoRead (Address, Width, &Data, Config); + Data = (Data & Mask) | Value; + GnbLibIoWrite (Address, Width, &Data, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Indirect IO block read + * + * + * + * @param[in] IndexPort Index Port + * @param[in] DataPort Data Port + * @param[in] Width Access width + * @param[in] IndexAddress Index Address + * @param[in] Count Count + * @param[in] Buffer Buffer + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibIndirectIoBlockRead ( + IN UINT16 IndexPort, + IN UINT16 DataPort, + IN ACCESS_WIDTH Width, + IN UINT32 IndexAddress, + IN UINT32 Count, + IN VOID *Buffer, + IN VOID *Config + ) +{ + UINT32 Index; + for (Index = IndexAddress; Index < (IndexAddress + Count); Index++) { + GnbLibIoWrite (IndexPort, Width, &Index, Config); + GnbLibIoRead (DataPort, Width, Buffer, Config); + Buffer = (VOID *) ((UINT8 *) Buffer + LibAmdAccessWidth (Width)); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get IOAPIC ID + * + * + * + * @param[in] IoApicBaseAddress IO APIC base address + * @param[in] Config Pointer to standard header + */ +UINT8 +GnbLiGetIoapicId ( + IN UINT64 IoApicBaseAddress, + IN VOID *Config + ) +{ + UINT32 Value; + Value = 0x0; + GnbLibMemWrite (IoApicBaseAddress, AccessWidth32, &Value, Config); + GnbLibMemRead (IoApicBaseAddress + 0x10, AccessWidth32, &Value, Config); + return (UINT8) (Value >> 24); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write MMIO registers + * + * + * + * @param[in] Address Physical address + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Value OR Value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibMemRMW ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibMemRead (Address, Width, &Data, Config); + Data = (Data & Mask) | Value; + GnbLibMemWrite (Address, Width, &Data, Config); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of sockets + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval Total number of socket on platform + */ + +UINT32 +GnbGetNumberOfSockets ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return GetPlatformNumberOfSockets (); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of Silicons on the socket + * + * + * + * @param[in] SiliconId Socket ID + * @param[in] StdHeader Standard configuration header + * @retval Number of silicons/modules in device in socket + */ + +UINT32 +GnbGetNumberOfSiliconsOnSocket ( + IN UINT32 SiliconId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return 1; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCI Address + * + * + * + * @param[in] SocketId Socket ID + * @param[in] SiliconId Silicon device Id + * @param[in] StdHeader Standard configuration header + * @retval PCI address of GNB for a given socket/silicon. + */ + +PCI_ADDR +GnbGetPciAddress ( + IN UINT32 SocketId, + IN UINT32 SiliconId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR Gnb; + Gnb.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + return Gnb; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if anything plugged in socket + * + * + * + * @param[in] SocketId Socket ID + * @param[in] StdHeader Standard configuration header + * @retval TRUE CPU present in socket. + */ + +BOOLEAN +GnbIsDevicePresentInSocket ( + IN UINT32 SocketId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return IsProcessorPresent (SocketId, StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Claculate power of number + * + * + * + * @param[in] Value Number + * @param[in] Power Power + */ + +UINT32 +GnbLibPowerOf ( + IN UINT32 Value, + IN UINT32 Power + ) +{ + UINT32 Result; + if (Power == 0) { + return 1; + } + Result = Value; + while ((--Power) > 0) { + Result *= Value; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Search buffer for pattern + * + * + * @param[in] Buf1 Pointer to source buffer which will be subject of search + * @param[in] Buf1Length Length of the source buffer + * @param[in] Buf2 Pointer to pattern buffer + * @param[in] Buf2Length Length of the pattern buffer + * @retval Pointer on first accurance of Buf2 in Buf1 or NULL + */ + +VOID* +GnbLibFind ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ) +{ + UINT8 *CurrentBuf1Ptr; + CurrentBuf1Ptr = Buf1; + while (CurrentBuf1Ptr < (Buf1 + Buf1Length - Buf2Length)) { + UINT8 *SourceBufPtr; + UINT8 *PatternBufPtr; + UINTN PatternBufLength; + SourceBufPtr = CurrentBuf1Ptr; + PatternBufPtr = Buf2; + PatternBufLength = Buf2Length; + while ((*SourceBufPtr++ == *PatternBufPtr++) && (PatternBufLength-- != 0)); + if (PatternBufLength == 0) { + return CurrentBuf1Ptr; + } + CurrentBuf1Ptr++; + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump buffer to HDTOUT + * + * + * @param[in] Buffer Buffer pointer + * @param[in] Count Count of data elements + * @param[in] DataWidth DataWidth 1 - Byte; 2 - Word; 3 - DWORD; 4 - QWORD + * @param[in] LineWidth Number of data item per line + */ +VOID +GnbLibDebugDumpBuffer ( + IN VOID *Buffer, + IN UINT32 Count, + IN UINT8 DataWidth, + IN UINT8 LineWidth + ) +{ + UINT32 Index; + UINT32 DataItemCount; + ASSERT (LineWidth != 0); + ASSERT (DataWidth >= 1 && DataWidth <= 4); + DataItemCount = 0; + for (Index = 0; Index < Count; ) { + switch (DataWidth) { + case 1: + IDS_HDT_CONSOLE (GNB_TRACE, "%02x ", *((UINT8 *) Buffer + Index)); + Index += 1; + break; + case 2: + IDS_HDT_CONSOLE (GNB_TRACE, "%04x ", *(UINT16 *) ((UINT8 *) Buffer + Index)); + Index += 2; + break; + case 3: + IDS_HDT_CONSOLE (GNB_TRACE, "%08x ", *(UINT32 *) ((UINT8 *) Buffer + Index)); + Index += 4; + break; + case 4: + IDS_HDT_CONSOLE (GNB_TRACE, "%08x%08", *(UINT32 *) ((UINT8 *) Buffer + Index), *(UINT32 *) ((UINT8 *) Buffer + Index + 4)); + Index += 8; + break; + default: + IDS_HDT_CONSOLE (GNB_TRACE, "ERROR! Incorrect Data Width\n"); + return; + } + if (++DataItemCount >= LineWidth) { + IDS_HDT_CONSOLE (GNB_TRACE, "\n"); + DataItemCount = 0; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump buffer to HDTOUT + * + * + * @param[in] ServiceId Service ID + * @param[in] SocketId Socket ID + * @param[in] ServiceProtocol Service protocol + * @param[in] StdHeader Standard Configuration Header + */ +AGESA_STATUS +GnbLibLocateService ( + IN GNB_SERVICE_ID ServiceId, + IN UINT8 SocketId, + IN VOID **ServiceProtocol, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GNB_SERVICE *SeviceEntry; + CPU_LOGICAL_ID LogicalId; + SeviceEntry = ServiceTable; + GetLogicalIdOfSocket (SocketId, &LogicalId, StdHeader); + while (SeviceEntry != NULL) { + if (SeviceEntry->ServiceId == ServiceId && (LogicalId.Family & SeviceEntry->Family) != 0) { + *ServiceProtocol = SeviceEntry->ServiceProtocol; + return AGESA_SUCCESS; + } + SeviceEntry = SeviceEntry->NextService; + } + return AGESA_UNSUPPORTED; +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLib.h new file mode 100755 index 0000000000..a983d5cdd0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLib.h @@ -0,0 +1,195 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 47656 $ @e \$Date: 2011-02-25 02:39:38 +0800 (Fri, 25 Feb 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ +#ifndef _GNBLIB_H_ +#define _GNBLIB_H_ + +#define IOC_WRITE_ENABLE 0x80 + +typedef AGESA_STATUS (F_GNB_REGISTER_ACCESS) ( + UINT8 RegisterSpaceType, + UINT32 Address, + VOID *Value, + UINT32 Flags, + AMD_CONFIG_PARAMS *StdHeader +); + +typedef F_GNB_REGISTER_ACCESS *PF_GNB_REGISTER_ACCESS; + +/// Register Read/Write protocol +typedef struct { + PF_GNB_REGISTER_ACCESS Read; ///< Read Register + PF_GNB_REGISTER_ACCESS Write; ///< Write Register +} GNB_REGISTER_PROTOCOL; + +VOID +GnbLibPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *Config + ); + +VOID +GnbLibPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *Config + ); + +VOID +GnbLibPciIndirectRMW ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +VOID +GnbLibPciIndirectWriteField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN VOID *Config + ); + + +VOID +GnbLibPciRMW ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +VOID +GnbLibIoRMW ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +UINT32 +GnbGetNumberOfSockets ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbGetNumberOfSiliconsOnSocket ( + IN UINT32 SiliconId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbIsDevicePresentInSocket ( + IN UINT32 SocketId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +PCI_ADDR +GnbGetPciAddress ( + IN UINT32 SocketId, + IN UINT32 SiliconId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbLibPowerOf ( + IN UINT32 Value, + IN UINT32 Power + ); + +VOID* +GnbLibFind ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ); + +VOID +GnbLibIndirectIoBlockRead ( + IN UINT16 IndexPort, + IN UINT16 DataPort, + IN ACCESS_WIDTH Width, + IN UINT32 IndexAddress, + IN UINT32 Count, + IN VOID *Buffer, + IN VOID *Config + ); + +UINT8 +GnbLiGetIoapicId ( + IN UINT64 IoApicBaseAddress, + IN VOID *Config + ); + +VOID +GnbLibDebugDumpBuffer ( + IN VOID *Buffer, + IN UINT32 Count, + IN UINT8 DataWidth, + IN UINT8 LineWidth + ); + +AGESA_STATUS +GnbLibLocateService ( + IN GNB_SERVICE_ID ServiceId, + IN UINT8 SocketId, + IN VOID **ServiceProtocol, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c new file mode 100755 index 0000000000..ffa9281f69 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c @@ -0,0 +1,130 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access various CPU registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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 "Porting.h" +#include "AMD.h" +#include "GnbLibPciAcc.h" +#include "GnbLibCpuAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBCPUACC_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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read CPU (DCT) indirect registers + * + * + * + * @param[in] Address PCI address of DCT register + * @param[in] IndirectAddress Offset of DCT register + * @param[out] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibCpuPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + OUT UINT32 *Value, + IN VOID *Config + ) +{ + UINT32 OffsetRegisterValue; + GnbLibPciWrite (Address, AccessWidth32, &IndirectAddress, Config); + do { + GnbLibPciRead (Address , AccessWidth32, &OffsetRegisterValue, Config); + } while ((OffsetRegisterValue & BIT31) == 0); + GnbLibPciRead (Address + 4, AccessWidth32, Value, Config); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Write CPU (DCT) indirect registers + * + * + * + * @param[in] Address PCI address of DCT register + * @param[in] IndirectAddress Offset of DCT register + * @param[in] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibCpuPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT32 *Value, + IN VOID *Config + ) +{ + UINT32 OffsetRegisterValue; + OffsetRegisterValue = IndirectAddress | BIT30; + GnbLibPciWrite (Address + 4, AccessWidth32, Value, Config); + GnbLibPciWrite (Address, AccessWidth32, &IndirectAddress, Config); + do { + GnbLibPciRead (Address , AccessWidth32, &OffsetRegisterValue, Config); + } while ((OffsetRegisterValue & BIT31) == 0); +} + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h new file mode 100755 index 0000000000..2ec1d0cc2f --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access various CPU registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _CPUACCLIB_H_ +#define _CPUACCLIB_H_ + +VOID +GnbLibCpuPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT32 *Value, + IN VOID *Config + ); + +VOID +GnbLibCpuPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + OUT UINT32 *Value, + IN VOID *Config + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c new file mode 100755 index 0000000000..b1f36c3255 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c @@ -0,0 +1,159 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access heap. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "heapManager.h" +#include "GnbLibPciAcc.h" +#include "GnbLibHeap.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBHEAP_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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Allocates space for a new buffer in the heap + * + * + * @param[in] Handle Buffer handle + * @param[in] Length Buffer length + * @param[in] StdHeader Standard configuration header + * + * @retval NULL Buffer allocation fail + * + */ + +VOID * +GnbAllocateHeapBuffer ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + AllocHeapParams.RequestedBufferSize = (UINT32) Length; + AllocHeapParams.BufferHandle = Handle; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + Status = HeapAllocateBuffer (&AllocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + return NULL; + } + return AllocHeapParams.BufferPtr; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Allocates space for a new buffer in the heap and clear it + * + * + * @param[in] Handle Buffer handle + * @param[in] Length Buffer length + * @param[in] StdHeader Standard configuration header + * + * @retval NULL Buffer allocation fail + * + */ + +VOID * +GnbAllocateHeapBufferAndClear ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + VOID *Buffer; + Buffer = GnbAllocateHeapBuffer (Handle, Length, StdHeader); + if (Buffer != NULL) { + LibAmdMemFill (Buffer, 0x00, Length, StdHeader); + } + return Buffer; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Locates a previously allocated buffer on the heap. + * + * + * @param[in] Handle Buffer handle + * @param[in] StdHeader Standard configuration header + * + * @retval NULL Buffer handle not found + * + */ + +VOID * +GnbLocateHeapBuffer ( + IN UINT32 Handle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + LOCATE_HEAP_PTR LocHeapParams; + LocHeapParams.BufferHandle = Handle; + Status = HeapLocateBuffer (&LocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + return NULL; + } + return LocHeapParams.BufferPtr; +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h new file mode 100755 index 0000000000..b28adc8ab1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h @@ -0,0 +1,69 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access heap. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBHEAPLIB_H_ +#define _GNBHEAPLIB_H_ + +VOID * +GnbAllocateHeapBuffer ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +GnbLocateHeapBuffer ( + IN UINT32 Handle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +GnbAllocateHeapBufferAndClear ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c new file mode 100755 index 0000000000..742067f5ac --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c @@ -0,0 +1,122 @@ +/* $NoKeywords:$ */ +/** + * @file + * +* Service procedure to access I/O registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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 "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "GnbLibIoAcc.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBIOACC_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 + *---------------------------------------------------------------------------------------- + */ +/*----------------------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------*/ +/** + * Write I/O Port + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[in] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibIoWrite ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ) +{ + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_IO_WRITE (StdHeader, Address, Width, Value); + } + LibAmdIoWrite (Width, Address, Value, StdHeader); +} +/** + * Read IO port + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[out] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibIoRead ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ) +{ + LibAmdIoRead (Width, Address, Value, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h new file mode 100755 index 0000000000..a222b64257 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h @@ -0,0 +1,66 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access I/O registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _IOACCLIB_H_ +#define _IOACCLIB_H_ + + +VOID +GnbLibIoWrite ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ); + +VOID +GnbLibIoRead ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c new file mode 100755 index 0000000000..11ad3e0a6f --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c @@ -0,0 +1,125 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access MMIO registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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 "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "GnbLibMemAcc.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBMEMACC_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Write Memory/MMIO registers + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[in] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibMemWrite ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ) +{ + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_MEM_WRITE (StdHeader, Address, Width, Value); + } + LibAmdMemWrite (Width, Address, Value, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read Memory/MMIO registers + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[out] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibMemRead ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ) +{ + LibAmdMemRead (Width, Address, Value, StdHeader); +} + + + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h new file mode 100755 index 0000000000..0f46cc8141 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access MMIO registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _MEMACCLIB_H_ +#define _MEMACCLIB_H_ + +VOID +GnbLibMemWrite ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ); + +VOID +GnbLibMemRead ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ); + +VOID +GnbLibMemRMW ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c new file mode 100755 index 0000000000..dab2254b72 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c @@ -0,0 +1,410 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49526 $ @e \$Date: 2011-03-25 00:52:37 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + + +#include "AGESA.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbLibPciAcc.h" +#include "GnbLibPci.h" +#include "GnbLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBPCI_FILECODE + +UINT16 +GnbLibFindPcieExtendedCapability ( + IN UINT32 Address, + IN UINT16 ExtendedCapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device present + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is present + * @retval FALSE Device is not present + */ + +BOOLEAN +GnbLibPciIsDevicePresent ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 DeviceId; + GnbLibPciRead (Address, AccessWidth32, &DeviceId, StdHeader); + if (DeviceId == 0xffffffff) { + return FALSE; + } else { + return TRUE; + } +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device is bridge + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a bridge + * @retval FALSE Device is not a bridge + */ + +BOOLEAN +GnbLibPciIsBridgeDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Header; + GnbLibPciRead (Address | 0xe, AccessWidth8, &Header, StdHeader); + if ((Header & 0x7f) == 1) { + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device is multifunction + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a multifunction device. + * @retval FALSE Device is a single function device. + * + */ +BOOLEAN +GnbLibPciIsMultiFunctionDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Header; + GnbLibPciRead (Address | 0xe, AccessWidth8, &Header, StdHeader); + if ((Header & 0x80) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device is PCIe device + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a PCIe device + * @retval FALSE Device is not a PCIe device + * + */ + +BOOLEAN +GnbLibPciIsPcieDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + if (GnbLibFindPciCapability (Address, PCIE_CAP_ID, StdHeader) != 0 ) { + return TRUE; + } else { + return FALSE; + } +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Find PCI capability pointer + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] CapabilityId PCI capability ID + * @param[in] StdHeader Standard configuration header + * @retval Register address of capability pointer + * + */ + +UINT8 +GnbLibFindPciCapability ( + IN UINT32 Address, + IN UINT8 CapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 CapabilityPtr; + UINT8 CurrentCapabilityId; + CapabilityPtr = 0x34; + if (!GnbLibPciIsDevicePresent (Address, StdHeader)) { + return 0; + } + while (CapabilityPtr != 0) { + GnbLibPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, StdHeader); + if (CapabilityPtr != 0) { + GnbLibPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, StdHeader); + if (CurrentCapabilityId == CapabilityId) { + break; + } + CapabilityPtr++; + } + } + return CapabilityPtr; +} +/*----------------------------------------------------------------------------------------*/ +/* + * Find PCIe extended capability pointer + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] ExtendedCapabilityId Extended PCIe capability ID + * @param[in] StdHeader Standard configuration header + * @retval Register address of extended capability pointer + * + */ + + +UINT16 +GnbLibFindPcieExtendedCapability ( + IN UINT32 Address, + IN UINT16 ExtendedCapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 CapabilityPtr; + UINT32 ExtendedCapabilityIdBlock; + if (GnbLibPciIsPcieDevice (Address, StdHeader)) { + GnbLibPciRead (Address | 0x100 , AccessWidth32 , &ExtendedCapabilityIdBlock, StdHeader); + if ((ExtendedCapabilityIdBlock != 0) && ((UINT16)ExtendedCapabilityIdBlock != 0xffff)) { + do { + CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff); + if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) { + return CapabilityPtr; + } + GnbLibPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, StdHeader); + } while (((ExtendedCapabilityIdBlock >> 20) & 0xfff) != 0); + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Scan range of device on PCI bus. + * + * + * + * @param[in] Start Start address to start scan from + * @param[in] End End address of scan + * @param[in] ScanData Supporting data + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +GnbLibPciScan ( + IN PCI_ADDR Start, + IN PCI_ADDR End, + IN GNB_PCI_SCAN_DATA *ScanData + ) +{ + UINTN Bus; + UINTN Device; + UINTN LastDevice; + UINTN Function; + UINTN LastFunction; + PCI_ADDR PciDevice; + SCAN_STATUS Status; + + for (Bus = Start.Address.Bus; Bus <= End.Address.Bus; Bus++) { + Device = (Bus == Start.Address.Bus) ? Start.Address.Device : 0x00; + LastDevice = (Bus == End.Address.Bus) ? End.Address.Device : 0x1F; + for ( ; Device <= LastDevice; Device++) { + if ((Bus == Start.Address.Bus) && (Device == Start.Address.Device)) { + Function = Start.Address.Function; + } else { + Function = 0x0; + } + PciDevice.AddressValue = MAKE_SBDFO (0, Bus, Device, Function, 0); + if (!GnbLibPciIsDevicePresent (PciDevice.AddressValue, ScanData->StdHeader)) { + continue; + } + if (GnbLibPciIsMultiFunctionDevice (PciDevice.AddressValue, ScanData->StdHeader)) { + if ((Bus == End.Address.Bus) && (Device == End.Address.Device)) { + LastFunction = Start.Address.Function; + } else { + LastFunction = 0x7; + } + } else { + LastFunction = 0x0; + } + for ( ; Function <= LastFunction; Function++) { + PciDevice.AddressValue = MAKE_SBDFO (0, Bus, Device, Function, 0); + if (GnbLibPciIsDevicePresent (PciDevice.AddressValue, ScanData->StdHeader)) { + Status = ScanData->GnbScanCallback (PciDevice, ScanData); + if ((Status & SCAN_SKIP_FUNCTIONS) != 0) { + Function = LastFunction + 1; + } + if ((Status & SCAN_SKIP_DEVICES) != 0) { + Device = LastDevice + 1; + } + if ((Status & SCAN_SKIP_BUSES) != 0) { + Bus = End.Address.Bus + 1; + } + } + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Scan all subordinate buses + * + * + * @param[in] Bridge PCI bridge address + * @param[in,out] ScanData Scan configuration data + * + */ +VOID +GnbLibPciScanSecondaryBus ( + IN PCI_ADDR Bridge, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + PCI_ADDR StartRange; + PCI_ADDR EndRange; + UINT8 SecondaryBus; + GnbLibPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &SecondaryBus, ScanData->StdHeader); + if (SecondaryBus != 0) { + StartRange.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0); + EndRange.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0x1f, 0x7, 0); + GnbLibPciScan (StartRange, EndRange, ScanData); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCIe device type + * + * + * + * @param[in] Device PCI address of device. + * @param[in] StdHeader Northbridge configuration structure pointer. + * + * @retval PCIE_DEVICE_TYPE + */ + /*----------------------------------------------------------------------------------------*/ + +PCIE_DEVICE_TYPE +GnbLibGetPcieDeviceType ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + UINT8 Value; + + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRead (Device.AddressValue | (PcieCapPtr + 0x2) , AccessWidth8, &Value, StdHeader); + return Value >> 4; + } + return PcieNotPcieDevice; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Save config space area + * + * + * + * @param[in] Address PCI address of device. + * @param[in] StartRegisterAddress Start register address. + * @param[in] EndRegisterAddress End register address. + * @param[in] Width Acess width. + * @param[in] StdHeader Standard header. + * + */ + /*----------------------------------------------------------------------------------------*/ + +VOID +GnbLibS3SaveConfigSpace ( + IN UINT32 Address, + IN UINT16 StartRegisterAddress, + IN UINT16 EndRegisterAddress, + IN ACCESS_WIDTH Width, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Index; + UINT16 Delta; + UINT16 Length; + Length = (StartRegisterAddress < EndRegisterAddress) ? (EndRegisterAddress - StartRegisterAddress) : (StartRegisterAddress - EndRegisterAddress); + Delta = LibAmdAccessWidth (Width); + for (Index = 0; Index <= Length; Index = Index + Delta) { + GnbLibPciRMW ( + Address | ((StartRegisterAddress < EndRegisterAddress) ? (StartRegisterAddress + Index) : (StartRegisterAddress - Index)), + Width, + 0xffffffff, + 0x0, + StdHeader + ); + } +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h new file mode 100755 index 0000000000..a9fe6a7609 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h @@ -0,0 +1,150 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBLIBPCI_H_ +#define _GNBLIBPCI_H_ + +#define PCIE_CAP_ID 0x10 +#define IOMMU_CAP_ID 0x0F + +/// PCIe device type +typedef enum { + PcieDeviceEndPoint, ///< Endpoint + PcieDeviceLegacyEndPoint, ///< Legacy endpoint + PcieDeviceRootComplex = 4, ///< Root complex + PcieDeviceUpstreamPort, ///< Upstream port + PcieDeviceDownstreamPort, ///< Downstream Port + PcieDevicePcieToPcix, ///< PCIe to PCI/PCIx bridge + PcieDevicePcixToPcie, ///< PCI/PCIx to PCIe bridge + PcieNotPcieDevice = 0xff ///< unknown device +} PCIE_DEVICE_TYPE; + +typedef UINT32 SCAN_STATUS; + +#define SCAN_SKIP_FUNCTIONS 0x1 +#define SCAN_SKIP_DEVICES 0x2 +#define SCAN_SKIP_BUSES 0x4 +#define SCAN_SUCCESS 0x0 + +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (GNB_PCI_SCAN_DATA); + +typedef SCAN_STATUS (*GNB_SCAN_CALLBACK) ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +///Scan supporting data +typedef struct _GNB_PCI_SCAN_DATA { + GNB_SCAN_CALLBACK GnbScanCallback; ///< Callback for each found device + AMD_CONFIG_PARAMS *StdHeader; ///< Standard configuration header +} UnusedName; + +#define PCIE_CAP_ID 0x10 +#define PCIE_LINK_CAP_REGISTER 0x0C +#define PCIE_LINK_CTRL_REGISTER 0x10 +#define PCIE_DEVICE_CAP_REGISTER 0x04 +#define PCIE_ASPM_L1_SUPPORT_CAP BIT11 + +BOOLEAN +GnbLibPciIsDevicePresent ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbLibPciIsBridgeDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbLibPciIsMultiFunctionDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbLibPciIsPcieDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLibFindPciCapability ( + IN UINT32 Address, + IN UINT8 CapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibPciScan ( + IN PCI_ADDR Start, + IN PCI_ADDR End, + IN GNB_PCI_SCAN_DATA *ScanData + ); + +VOID +GnbLibPciScanSecondaryBus ( + IN PCI_ADDR Bridge, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +PCIE_DEVICE_TYPE +GnbLibGetPcieDeviceType ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibS3SaveConfigSpace ( + IN UINT32 Address, + IN UINT16 StartRegisterAddress, + IN UINT16 EndRegisterAddress, + IN ACCESS_WIDTH Width, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c new file mode 100755 index 0000000000..f82ccdf8e4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c @@ -0,0 +1,156 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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 "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "GnbLibPciAcc.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBPCIACC_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCI registers + * + * + * + * @param[in] Address PCI address (as presented in PCI_ADDR.AddressValue) + * @param[in] Width Access width + * @param[in] Value Pointer to value + * @param[in] StdHeader Pointer to standard header + */ +VOID +GnbLibPciWrite ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + PciAddress.AddressValue = Address; + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_PCI_WRITE (StdHeader, PciAddress, Width, Value); + } + LibAmdPciWrite (Width, PciAddress, Value, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCI registers + * + * + * + * @param[in] Address PCI address (as presented in PCI_ADDR.AddressValue) + * @param[in] Width Access width + * @param[out] Value Pointer to value + * @param[in] StdHeader Pointer to standard header + */ + +VOID +GnbLibPciRead ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + PciAddress.AddressValue = Address; + LibAmdPciRead (Width, PciAddress, Value, StdHeader); +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll PCI reg + * + * + * + * @param[in] Address PCI address (as presented in PCI_ADDR.AddressValue) + * @param[in] Width Access width + * @param[in] Data Data to compare + * @param[in] DataMask AND mask + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibPciPoll ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Data, + IN VOID *DataMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + PciAddress.AddressValue = Address; + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_PCI_POLL (StdHeader, PciAddress, Width, Data, DataMask, 0xffffffff); + } + LibAmdPciPoll (Width, PciAddress, Data, DataMask, 0xffffffff, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h new file mode 100755 index 0000000000..dbcf912d3c --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _GNBLIBPCIACC_H_ +#define _GNBLIBPCIACC_H_ + +VOID +GnbLibPciWrite ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibPciRead ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibPciPoll ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Data, + IN VOID *DataMask, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibStall.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibStall.c new file mode 100755 index 0000000000..74220a1c35 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibStall.c @@ -0,0 +1,152 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 01:16:51 -0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + + +#include "AGESA.h" +#include "amdlib.h" +#include "S3SaveState.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbLibStall.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBSTALL_FILECODE + + + + +/*----------------------------------------------------------------------------------------*/ +/* + * Stall and save to script table + * + * + * + * @param[in] Microsecond Stall time + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibStallS3Save ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + S3_SAVE_DISPATCH (StdHeader, GnbLibStallS3Script_ID, sizeof (Microsecond), &Microsecond); + GnbLibStall (Microsecond, StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Stall + * + * + * + * @param[in] Microsecond Stall time + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibStall ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TimeStampStart; + UINT32 TimeStampDelta; + UINT32 TimeStampCurrent; + + TimeStampStart = GnbLibTimeStamp (StdHeader); + do { + TimeStampCurrent = GnbLibTimeStamp (StdHeader); + TimeStampDelta = ((TimeStampCurrent > TimeStampStart) ? (TimeStampCurrent - TimeStampStart) : (0xffffffffull - TimeStampStart + TimeStampCurrent)); + } while (TimeStampDelta < Microsecond); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Stall S3 scrept + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[in] ContextLength Context Length (not used) + * @param[in] Context Context pointer (not used) + */ +VOID +GnbLibStallS3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID* Context + ) +{ + GnbLibStall (* ((UINT32*) Context), StdHeader); +} +/*----------------------------------------------------------------------------------------*/ +/* + * Time stamp in us + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a bridge + * @retval FALSE Device is not a bridge + */ + +UINT32 +GnbLibTimeStamp ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TimeStamp; + GnbLibPciIndirectRead ( + MAKE_SBDFO (0, 0, 0, 0, 0xE0), + 0x13080F0, + AccessWidth32, + &TimeStamp, + StdHeader + ); + return TimeStamp; +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibStall.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibStall.h new file mode 100755 index 0000000000..ed9b858b36 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbLibStall.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 01:16:51 -0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBLIBSTALL_H_ +#define _GNBLIBSTALL_H_ + +VOID +GnbLibStallS3Save ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibStall ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbLibTimeStamp ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibStallS3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID* Context + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbTable.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbTable.c new file mode 100755 index 0000000000..f8d216a2bc --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbTable.c @@ -0,0 +1,310 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39623 $ @e \$Date: 2010-10-13 13:37:42 -0700 (Wed, 13 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 "cpuFamilyTranslation.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbLibStall.h" +#include "GnbTable.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBTABLE_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Process table + * + * + * + * @param[in] Table Table pointer + * @param[in] Property Property + * @param[in] Flags Flags + * @param[in] Protocol Register access protocol + * @param[in] StdHeader Standard configuration header + */ +AGESA_STATUS +GnbProcessTable ( + IN GNB_TABLE *Table, + IN UINT32 Property, + IN UINT32 Flags, + IN GNB_REGISTER_PROTOCOL *Protocol, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return GnbProcessTableExt (0, 0, Table, Property, Flags, Protocol, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Process table + * + * @param[in] Socket Socket + * @param[in] Module Module + * @param[in] Table Table pointer + * @param[in] Property Property + * @param[in] Flags Flags + * @param[in] Protocol Register access protocol + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +GnbProcessTableExt ( + IN UINT32 Socket, + IN UINT8 Module, + IN GNB_TABLE *Table, + IN UINT32 Property, + IN UINT32 Flags, + IN GNB_REGISTER_PROTOCOL *Protocol, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *EntryPointer; + UINT64 Data; + UINT64 Temp; + UINT64 Mask; + UINT32 WriteAccFlags; + CPU_LOGICAL_ID LogicalId; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbProcessTableExt Enter\n"); + IDS_HDT_CONSOLE (GNB_TRACE, " Property - 0x%08x\n", Property); + GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader); + EntryPointer = (UINT8 *) Table; + WriteAccFlags = 0; + if ((Flags & GNB_TABLE_FLAGS_FORCE_S3_SAVE) != 0) { + WriteAccFlags |= GNB_REG_ACC_FLAG_S3SAVE; + } + while (*EntryPointer != GnbEntryTerminate) { + Data = 0; + Temp = 0; + switch (*EntryPointer) { + case GnbEntryWr: + Protocol->Write ( + ((GNB_TABLE_ENTRY_WR*) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_WR*) EntryPointer)->Address, + &((GNB_TABLE_ENTRY_WR*) EntryPointer)->Value, + WriteAccFlags, + StdHeader + ); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_WR); + break; + case GnbEntryPropertyWr: + if ((Property & ((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->Property) != 0) { + Protocol->Write ( + ((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->Address, + &((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->Value, + WriteAccFlags, + StdHeader + ); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_PROPERTY_WR); + break; + case GnbEntryFullWr: + if ((Property & ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Property) != 0) { + if ((LogicalId.Revision & ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Revision) != 0) { + Protocol->Write ( + ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Address, + &((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Value, + WriteAccFlags, + StdHeader + ); + } + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_FULL_WR); + break; + case GnbEntryRmw: + Protocol->Read ( + ((GNB_TABLE_ENTRY_RMW*) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_RMW*) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + Data = (Data & (~ (UINT64) ((GNB_TABLE_ENTRY_RMW*) EntryPointer)->AndMask)) | ((GNB_TABLE_ENTRY_RMW*) EntryPointer)->OrMask; + Protocol->Write ( + ((GNB_TABLE_ENTRY_RMW*) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_RMW*) EntryPointer)->Address, + &Data, + WriteAccFlags, + StdHeader + ); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_RMW); + break; + case GnbEntryPropertyRmw: + if ((Property & ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->Property) != 0) { + Protocol->Read ( + ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + Data = (Data & (~ (UINT64) ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->AndMask)) | ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->OrMask; + Protocol->Write ( + ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->Address, + &Data, + WriteAccFlags, + StdHeader + ); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_PROPERTY_RMW); + break; + case GnbEntryFullRmw: + if ((Property & ((GNB_TABLE_ENTRY_FULL_WR *) EntryPointer)->Property) != 0) { + if ((LogicalId.Revision & ((GNB_TABLE_ENTRY_FULL_WR *) EntryPointer)->Revision) != 0) { + Protocol->Read ( + ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + Data = (Data & (~ (UINT64) ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->AndMask)) | ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->OrMask; + Protocol->Write ( + ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->Address, + &Data, + WriteAccFlags, + StdHeader + ); + } + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_FULL_RMW); + break; + case GnbEntryPoll: + do { + Protocol->Read ( + ((GNB_TABLE_ENTRY_POLL *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_POLL *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + } while ((Data & ((GNB_TABLE_ENTRY_POLL*) EntryPointer)->AndMask) != ((GNB_TABLE_ENTRY_POLL*) EntryPointer)->CompareValue); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_POLL); + break; + case GnbEntryPropertyPoll: + if ((Property & ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->Property) != 0) { + do { + Protocol->Read ( + ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + } while ((Data & ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->AndMask) != ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->CompareValue); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_PROPERTY_POLL); + break; + case GnbEntryCopy: + Protocol->Read ( + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcRegisterSpaceType, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcAddress, + &Data, + 0, + StdHeader + ); + Mask = (1ull << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcFieldWidth) - 1; + Data = (Data >> ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcFieldOffset) & Mask; + Protocol->Read ( + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestRegisterSpaceType, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestAddress, + &Temp, + 0, + StdHeader + ); + Mask = (1ull << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestFieldWidth) - 1; + Temp = Temp & ( ~ (Mask << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestFieldOffset)); + Temp = Temp | ((Data & Mask) << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestFieldOffset); + Protocol->Write ( + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestRegisterSpaceType, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestAddress, + &Temp, + WriteAccFlags, + StdHeader + ); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_COPY); + break; + case GnbEntryStall: + if ((WriteAccFlags & GNB_TABLE_FLAGS_FORCE_S3_SAVE) != 0) { + GnbLibStallS3Save (((GNB_TABLE_ENTRY_STALL*) EntryPointer)->Microsecond, StdHeader); + } else { + GnbLibStall (((GNB_TABLE_ENTRY_STALL*) EntryPointer)->Microsecond, StdHeader); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_STALL); + break; + default: + ASSERT (FALSE); + IDS_HDT_CONSOLE (NB_MISC, " ERROR!!! Regiter table parse\n"); + return AGESA_ERROR; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbProcessTableExt Exit\n"); + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbTable.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbTable.h new file mode 100755 index 0000000000..365a9ef69a --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbCommonLib/GnbTable.h @@ -0,0 +1,225 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39623 $ @e \$Date: 2010-10-13 13:37:42 -0700 (Wed, 13 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. +* *************************************************************************** +* +*/ +#ifndef _GNBTABLE_H_ +#define _GNBTABLE_H_ + + +#pragma pack (push, 1) + +#define GNB_TABLE_FLAGS_FORCE_S3_SAVE 0x00000001 + +typedef UINT8 GNB_TABLE; + +#define __DATA(x) x + +#define _DATA32(Data) (__DATA(Data)) & 0xFF, ((__DATA(Data)) >> 8) & 0xFF, ((__DATA(Data)) >> 16) & 0xFF, ((__DATA(Data)) >> 24) & 0xFF + +/// Entry type +typedef enum { + GnbEntryWr, ///< Write register + GnbEntryPropertyWr, ///< Write register check property + GnbEntryFullWr, ///< Write Rgister check revision and property + GnbEntryRmw, ///< Read Modify Write register + GnbEntryPropertyRmw, ///< Read Modify Write register check property + GnbEntryFullRmw, ///< Read Modify Write register check revision and property + GnbEntryPoll, ///< Poll register + GnbEntryPropertyPoll, ///< Poll register check property + GnbEntryCopy, ///< Copy field from one register to another + GnbEntryStall, ///< Copy field from one register to another + GnbEntryTerminate = 0xFF ///< Terminate table +} GNB_TABLE_ENTRY_TYPE; + +#define GNB_ENTRY_WR(RegisterSpaceType, Address, Value) \ + GnbEntryWr, RegisterSpaceType, _DATA32 (Address), _DATA32 (Value) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 Value; ///< Value +} GNB_TABLE_ENTRY_WR; + +#define GNB_ENTRY_PROPERTY_WR(Property, RegisterSpaceType, Address, Value) \ + GnbEntryPropertyWr, _DATA32 (Property), RegisterSpaceType, _DATA32 (Address), _DATA32 (Value) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 Value; ///< Value +} GNB_TABLE_ENTRY_PROPERTY_WR; + + +#define GNB_ENTRY_RMW(RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryRmw, RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< And Mask + UINT32 OrMask; ///< Or Mask +} GNB_TABLE_ENTRY_RMW; + +#define GNB_ENTRY_FULL_WR(Property, Revision, RegisterSpaceType, Address, Value) \ + GnbEntryFullWr, _DATA32 (Property), _DATA64 (Revision), RegisterSpaceType, _DATA32 (Address), _DATA32 (Value) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT64 Revision; ///< Revision + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 Value; ///< Value +} GNB_TABLE_ENTRY_FULL_WR; + + +#define GNB_ENTRY_PROPERTY_RMW(Property, RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryPropertyRmw, _DATA32 (Property), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End Mask + UINT32 OrMask; ///< Or Mask +} GNB_TABLE_ENTRY_PROPERTY_RMW; + +#define GNB_ENTRY_FULL_RMW(Property, Revision, RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryFullRmw, _DATA32 (Property), _DATA64 (Revision), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT64 Revision; ///< Revision + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End Mask + UINT32 OrMask; ///< Or Mask +} GNB_TABLE_ENTRY_FULL_RMW; + +#define GNB_ENTRY_POLL(RegisterSpaceType, Address, AndMask, CompareValue) \ + GnbEntryPoll, RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (CompareValue) +/// Poll register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End mask + UINT32 CompareValue; ///< Compare value +} GNB_TABLE_ENTRY_POLL; + +#define GNB_ENTRY_PROPERTY_POLL(Property, RegisterSpaceType, Address, AndMask, CompareValue) \ + GnbEntryPropertyPoll, _DATA32 (Property), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (CompareValue) +/// Poll register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End mask + UINT32 CompareValue; ///< Compare value +} GNB_TABLE_ENTRY_PROPERTY_POLL; + + +#define GNB_ENTRY_COPY(DestRegSpaceType, DestAddress, DestFieldOffset, DestFieldWidth, SrcRegisterSpaceType, SrcAddress, SrcFieldOffset, SrcFieldWidth) \ + GnbEntryCopy, DestRegSpaceType, _DATA32 (DestAddress), DestFieldOffset, DestFieldWidth, SrcRegisterSpaceType, _DATA32 (SrcAddress), SrcFieldOffset, SrcFieldWidth + +/// Copy regster entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 DestRegisterSpaceType; ///< Register space + UINT32 DestAddress; ///< Register address + UINT8 DestFieldOffset; ///< Field Offset + UINT8 DestFieldWidth; ///< Field Width + UINT8 SrcRegisterSpaceType; ///< Register space + UINT32 SrcAddress; ///< Register address + UINT8 SrcFieldOffset; ///< Field Offset + UINT8 SrcFieldWidth; ///< Field Width +} GNB_TABLE_ENTRY_COPY; + +#define GNB_ENTRY_STALL(Microsecond) \ + GnbEntryStall, _DATA32 (Microsecond) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Microsecond; ///< Value +} GNB_TABLE_ENTRY_STALL; + +#define GNB_ENTRY_TERMINATE GnbEntryTerminate + +AGESA_STATUS +GnbProcessTableExt ( + IN UINT32 Socket, + IN UINT8 Module, + IN GNB_TABLE *Table, + IN UINT32 Property, + IN UINT32 Flags, + IN GNB_REGISTER_PROTOCOL *Protocol, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbProcessTable ( + IN GNB_TABLE *Table, + IN UINT32 Property, + IN UINT32 Flags, + IN GNB_REGISTER_PROTOCOL *Protocol, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#pragma pack (pop) + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c new file mode 100755 index 0000000000..2ba5acdd81 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c @@ -0,0 +1,486 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific function translation + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39255 $ @e \$Date: 2010-10-08 11:27:41 -0700 (Fri, 08 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBFAMTRANSLATION_GNBPCIETRANSLATION_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 + *---------------------------------------------------------------------------------------- + */ +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] EngineType Engine Type + * @param[in] ConfigurationId Configuration ID + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_UNSUPPORTED No more configuration available for given engine type + * @retval AGESA_ERROR Requested configuration not supported + */ +AGESA_STATUS +PcieFmConfigureEnginesLaneAllocation ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIE_ENGINE_TYPE EngineType, + IN UINT8 ConfigurationId + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Wrapper->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, &PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId); + } + return AGESA_ERROR; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get core configuration value + * + * + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] CoreId Core ID + * @param[in] ConfigurationSignature Configuration signature + * @param[out] ConfigurationValue Configuration value (for core configuration) + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_ERROR Core configuration value can not be determined + */ +AGESA_STATUS +PcieFmGetCoreConfigurationValue ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId, + IN UINT64 ConfigurationSignature, + IN UINT8 *ConfigurationValue + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Wrapper->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, &PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieInitService->PcieFmGetCoreConfigurationValue (Wrapper, CoreId, ConfigurationSignature, ConfigurationValue); + } + return AGESA_ERROR; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if engine can be remapped to Device/function number requested by user + * defined engine descriptor + * + * Function only called if requested device/function does not much native device/function + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieFmCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, &PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmCheckPortPciDeviceMapping (PortDescriptor, Engine); + } + return FALSE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get core configuration string + * + * Debug function for logging configuration + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] ConfigurationValue Configuration value + * @retval Configuration string + */ + +CONST CHAR8* +PcieFmDebugGetCoreConfigurationString ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 ConfigurationValue + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_DEBUG_SERVICES *PcieDebugService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, &PcieDebugService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieDebugService->PcieFmDebugGetCoreConfigurationString (Wrapper, ConfigurationValue); + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get wrapper name + * + * Debug function for logging wrapper name + * + * @param[in] Wrapper Pointer to internal configuration data area + * @retval Wrapper Name string + */ + +CONST CHAR8* +PcieFmDebugGetWrapperNameString ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_DEBUG_SERVICES *PcieDebugService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, &PcieDebugService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieDebugService->PcieFmDebugGetWrapperNameString (Wrapper); + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get register address name + * + * Debug function for logging register trace + * + * @param[in] Silicon Silicon config descriptor + * @param[in] AddressFrame Address Frame + * @retval Register address name + */ +CONST CHAR8* +PcieFmDebugGetHostRegAddressSpaceString ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT16 AddressFrame + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_DEBUG_SERVICES *PcieDebugService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Silicon->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, &PcieDebugService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieDebugService->PcieFmDebugGetHostRegAddressSpaceString (Silicon, AddressFrame); + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if the lane can be muxed by link width requested by user + * defined engine descriptor + * + * Check Engine StartCoreLane could be aligned by user requested link width(x1, x2, x4, x8, x16). + * Check Engine StartCoreLane could be aligned by user requested link width x2. + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Lane can be muxed + * @retval FALSE Lane can NOT be muxed + */ + +BOOLEAN +PcieFmCheckPortPcieLaneCanBeMuxed ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, &PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmCheckPortPcieLaneCanBeMuxed (PortDescriptor, Engine); + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Map engine to specific PCI device address + * + * + * + * @param[in] Engine Pointer to engine configuration + * @retval AGESA_ERROR Fail to map PCI device address + * @retval AGESA_SUCCESS Successfully allocate PCI address + */ + +AGESA_STATUS +PcieFmMapPortPciAddress ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, &PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmMapPortPciAddress (Engine); + } + return AGESA_ERROR; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get total number of silicons/wrappers/engines for this complex + * + * + * + * @param[in] SocketId Socket ID. + * @param[out] Length Length of configuration info block + * @param[out] StdHeader Standard Configuration Header + * @retval AGESA_SUCCESS Configuration data length is correct + */ +AGESA_STATUS +PcieFmGetComplexDataLength ( + IN UINT8 SocketId, + OUT UINTN *Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, &PcieConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmGetComplexDataLength (SocketId, Length, StdHeader); + } + return Status; +} + + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Build configuration + * + * + * @param[in] SocketId Socket ID. + * @param[out] Buffer Pointer to buffer to build internal complex data structure + * @param[out] StdHeader Standard configuration header. + * @retval AGESA_SUCCESS Configuration data build successfully + */ +AGESA_STATUS +PcieFmBuildComplexConfiguration ( + IN UINT8 SocketId, + OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, &PcieConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * 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 +PcieFmGetLinkSpeedCap ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, &PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieInitService->PcieFmGetLinkSpeedCap (Flags, Engine); + } + return PcieGen1; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get native PHY lane bitmap + * + * + * @param[in] PhyLaneBitmap Package PHY lane bitmap + * @param[in] Engine Standard configuration header. + * @retval Native PHY lane bitmap + */ +UINT32 +PcieFmGetNativePhyLaneBitmap ( + IN UINT32 PhyLaneBitmap, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, &PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieInitService->PcieFmGetNativePhyLaneBitmap (PhyLaneBitmap, Engine); + } + return 0x0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get SB port info + * + * + * @param[out] SocketId Socket ID + * @param[out] SbPort Pointer to SB configuration descriptor + * @param[in] StdHeader Standard configuration header. + * @retval AGESA_SUCCESS SB configuration determined successfully + */ +AGESA_STATUS +PcieFmGetSbConfigInfo ( + IN UINT8 SocketId, + OUT PCIe_PORT_DESCRIPTOR *SbPort, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, &PcieConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmGetSbConfigInfo (SocketId, SbPort, StdHeader); + } + return Status; +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c new file mode 100755 index 0000000000..05fb4ea8ff --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c @@ -0,0 +1,189 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39255 $ @e \$Date: 2010-10-08 11:27:41 -0700 (Fri, 08 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 "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbGfxConfig.h" +#include "GnbCommonLib.h" +#include "GfxConfigPost.h" +#include "GfxConfigData.h" +#include "GnbGfxInitLibV1.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXCONFIG_GFXCONFIGENV_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS 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 + *---------------------------------------------------------------------------------------- + */ + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get UMA info + * + * UMA info stored on heap by memory module + * + * @param[out] UmaInfo Pointer to UMA info structure + * @param[in] StdHeader Standard configuration header + */ + +VOID +GfxGetUmaInfo ( + OUT UMA_INFO *UmaInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UMA_INFO *MemUmaInfo; + + MemUmaInfo = GnbLocateHeapBuffer (AMD_UMA_INFO_HANDLE, StdHeader); + if (MemUmaInfo == NULL) { + LibAmdMemFill (UmaInfo, 0x00, sizeof (UMA_INFO), StdHeader); + UmaInfo->UmaMode = UMA_NONE; + } else { + LibAmdMemCopy (UmaInfo, MemUmaInfo, sizeof (UMA_INFO), StdHeader); + if ((UmaInfo->UmaBase == 0) || (UmaInfo->UmaSize == 0)) { + UmaInfo->UmaMode = UMA_NONE; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate UMA configuration data + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[in,out] Gfx Pointer to GFX configuration + * @retval AGESA_STATUS Data located + * @retval AGESA_FATA Data not found + */ + +AGESA_STATUS +GfxLocateConfigData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT GFX_PLATFORM_CONFIG **Gfx + ) +{ + *Gfx = GnbLocateHeapBuffer (AMD_GFX_PLATFORM_CONFIG_HANDLE, StdHeader); + if (*Gfx == NULL) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + (*Gfx)->StdHeader = StdHeader; + return AGESA_SUCCESS; +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update GFX config info at ENV + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxConfigEnvInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + AMD_ENV_PARAMS *EnvParamsPtr; + GFX_PLATFORM_CONFIG *Gfx; + AGESA_STATUS Status; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigEnvInterface Enter\n"); + Status = GfxLocateConfigData (StdHeader, &Gfx); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + EnvParamsPtr = (AMD_ENV_PARAMS *) StdHeader; + Gfx->Gnb3dStereoPinIndex = EnvParamsPtr->GnbEnvConfiguration.Gnb3dStereoPinIndex; + Gfx->LvdsSpreadSpectrum = EnvParamsPtr->GnbEnvConfiguration.LvdsSpreadSpectrum; + Gfx->LvdsSpreadSpectrumRate = EnvParamsPtr->GnbEnvConfiguration.LvdsSpreadSpectrumRate; + Gfx->LvdsPowerOnSeqDigonToDe = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqDigonToDe; + Gfx->LvdsPowerOnSeqDeToVaryBl = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqDeToVaryBl; + Gfx->LvdsPowerOnSeqDeToDigon = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqDeToDigon; + Gfx->LvdsPowerOnSeqVaryBlToDe = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqVaryBlToDe; + Gfx->LvdsPowerOnSeqOnToOffDelay = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqOnToOffDelay; + Gfx->LvdsPowerOnSeqVaryBlToBlon = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqVaryBlToBlon; + Gfx->LvdsPowerOnSeqBlonToVaryBl = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqBlonToVaryBl; + Gfx->LvdsMaxPixelClockFreq = EnvParamsPtr->GnbEnvConfiguration.LvdsMaxPixelClockFreq; + Gfx->LcdBitDepthControlValue = EnvParamsPtr->GnbEnvConfiguration.LcdBitDepthControlValue; + Gfx->Lvds24bbpPanelMode = EnvParamsPtr->GnbEnvConfiguration.Lvds24bbpPanelMode; + Gfx->PcieRefClkSpreadSpectrum = EnvParamsPtr->GnbEnvConfiguration.PcieRefClkSpreadSpectrum; + GfxGetUmaInfo (&Gfx->UmaInfo, StdHeader); + } + GNB_DEBUG_CODE ( + GfxConfigDebugDump (Gfx); + ); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigEnvInterface Exit [0x%x]\n", Status); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c new file mode 100755 index 0000000000..ac234ba134 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c @@ -0,0 +1,177 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39255 $ @e \$Date: 2010-10-08 11:27:41 -0700 (Fri, 08 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 "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GfxConfigPost.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXCONFIG_GFXCONFIGPOST_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS 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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate UMA configuration data + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxConfigPostInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GFX_PLATFORM_CONFIG *Gfx; + AMD_POST_PARAMS *PostParamsPtr; + AGESA_STATUS Status; + PostParamsPtr = (AMD_POST_PARAMS *)StdHeader; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigPostInterface Enter\n"); + Gfx = GnbAllocateHeapBuffer (AMD_GFX_PLATFORM_CONFIG_HANDLE, sizeof (GFX_PLATFORM_CONFIG), StdHeader); + ASSERT (Gfx != NULL); + if (Gfx != NULL) { + LibAmdMemFill (Gfx, 0x00, sizeof (GFX_PLATFORM_CONFIG), StdHeader); + if (GnbBuildOptions.IgfxModeAsPcieEp) { + Gfx->GfxControllerMode = GfxControllerPcieEndpointMode; + Gfx->GfxPciAddress.AddressValue = MAKE_SBDFO (0, 0, 1, 0, 0); + } else { + Gfx->GfxControllerMode = GfxControllerLegacyBridgeMode; + Gfx->GfxPciAddress.AddressValue = MAKE_SBDFO (0, 1, 5, 0, 0); + } + Gfx->StdHeader = StdHeader; + Gfx->GnbHdAudio = PostParamsPtr->PlatformConfig.GnbHdAudio; + Gfx->AbmSupport = PostParamsPtr->PlatformConfig.AbmSupport; + Gfx->DynamicRefreshRate = PostParamsPtr->PlatformConfig.DynamicRefreshRate; + Gfx->LcdBackLightControl = PostParamsPtr->PlatformConfig.LcdBackLightControl; + Gfx->ForceGfxMode = GfxEnableAuto; + Gfx->AmdPlatformType = UserOptions.CfgAmdPlatformType; + Gfx->GmcClockGating = OptionEnabled; + Gfx->GmcPowerGating = GnbBuildOptions.GmcPowerGateStutterOnly ? GmcPowerGatingStutterOnly : GmcPowerGatingWidthStutter; + Gfx->UmaSteering = Garlic; + GNB_DEBUG_CODE ( + GfxConfigDebugDump (Gfx); + ); + } else { + Status = AGESA_ERROR; + } + IDS_OPTION_HOOK (IDS_GNB_PLATFORMCFG_OVERRIDE, Gfx, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigPostInterface Exit [0x%x]\n", Status); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Debug dump + * + * + * + * @param[in] Gfx Pointer to GFX configuration + */ + +VOID +GfxConfigDebugDump ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + IDS_HDT_CONSOLE (GFX_MISC, "<-------------- GFX Config Start ------------->\n"); + IDS_HDT_CONSOLE (GFX_MISC, " HD Audio - %s\n", (Gfx->GnbHdAudio == 0) ? "Disabled" : "Enabled"); + IDS_HDT_CONSOLE (GFX_MISC, " DynamicRefreshRate - 0x%x\n", Gfx->DynamicRefreshRate); + IDS_HDT_CONSOLE (GFX_MISC, " LcdBackLightControl - 0x%x\n", Gfx->LcdBackLightControl); + IDS_HDT_CONSOLE (GFX_MISC, " AbmSupport - %s\n", (Gfx->AbmSupport == 0) ? "Disabled" : "Enabled"); + IDS_HDT_CONSOLE (GFX_MISC, " GmcClockGating - %s\n", (Gfx->GmcClockGating == 0) ? "Disabled" : "Enabled"); + IDS_HDT_CONSOLE (GFX_MISC, " GmcPowerGating - %s\n", + (Gfx->GmcPowerGating == GmcPowerGatingDisabled) ? "Disabled" : ( + (Gfx->GmcPowerGating == GmcPowerGatingStutterOnly) ? "GmcPowerGatingStutterOnly" : ( + (Gfx->GmcPowerGating == GmcPowerGatingWidthStutter) ? "GmcPowerGatingWidthStutter" : "Unknown")) + ); + IDS_HDT_CONSOLE (GFX_MISC, " UmaSteering - %s\n", + (Gfx->UmaSteering == Onion) ? "Onion" : ( + (Gfx->UmaSteering == Garlic) ? "Garlic" : "Unknown") + ); + IDS_HDT_CONSOLE (GFX_MISC, " ForceGfxMode - %s\n", + (Gfx->ForceGfxMode == GfxEnableAuto) ? "Auto" : ( + (Gfx->ForceGfxMode == GfxEnableForcePrimary) ? "Force Primary" : ( + (Gfx->ForceGfxMode == GfxEnableForceSecondary) ? "Force Secondary" : "Unknown")) + ); + IDS_HDT_CONSOLE (GFX_MISC, " UmaMode - %s\n", (Gfx->UmaInfo.UmaMode == UMA_NONE) ? "No UMA" : "UMA"); + if (Gfx->UmaInfo.UmaMode != UMA_NONE) { + IDS_HDT_CONSOLE (GFX_MISC, " UmaBase - 0x%x\n", Gfx->UmaInfo.UmaBase); + IDS_HDT_CONSOLE (GFX_MISC, " UmaSize - 0x%x\n", Gfx->UmaInfo.UmaSize); + IDS_HDT_CONSOLE (GFX_MISC, " UmaAttributes - 0x%x\n", Gfx->UmaInfo.UmaAttributes); + } + IDS_HDT_CONSOLE (GFX_MISC, "<-------------- GFX Config End --------------->\n"); + +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.h new file mode 100755 index 0000000000..760adc8637 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.h @@ -0,0 +1,59 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39255 $ @e \$Date: 2010-10-08 11:27:41 -0700 (Fri, 08 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. +* *************************************************************************** +* +*/ + +#ifndef _GFXCONFIGPOST_H_ +#define _GFXCONFIGPOST_H_ + +AGESA_STATUS +GfxConfigPostInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GfxConfigDebugDump ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h new file mode 100755 index 0000000000..698b873e25 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39255 $ @e \$Date: 2010-10-08 11:27:41 -0700 (Fri, 08 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBGFXCONFIG_H_ +#define _GNBGFXCONFIG_H_ + +AGESA_STATUS +GfxLocateConfigData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT GFX_PLATFORM_CONFIG **Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c new file mode 100755 index 0000000000..e090461075 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c @@ -0,0 +1,184 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to collect discrete GFX card info + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GfxCardInfo.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GFXCARDINFO_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 + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + GFX_CARD_CARD_INFO *GfxCardInfo; + PCI_ADDR BaseBridge; + UINT8 BusNumber; +} GFX_SCAN_DATA; + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +SCAN_STATUS +GfxScanPcieDevice ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get information about all discrete GFX card in system + * + * + * + * @param[out] GfxCardInfo Pointer to GFX card info structure + * @param[in] StdHeader Standard configuration header + */ + +VOID +GfxGetDiscreteCardInfo ( + OUT GFX_CARD_CARD_INFO *GfxCardInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GFX_SCAN_DATA GfxScanData; + PCI_ADDR Start; + PCI_ADDR End; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGetDiscreteCardInfo Enter\n"); + Start.AddressValue = MAKE_SBDFO (0, 0, 2, 0, 0); + End.AddressValue = MAKE_SBDFO (0, 0, 0x1f, 7, 0); + GfxScanData.BusNumber = 5; + GfxScanData.ScanData.GnbScanCallback = GfxScanPcieDevice; + GfxScanData.ScanData.StdHeader = StdHeader; + GfxScanData.GfxCardInfo = GfxCardInfo; + GnbLibPciScan (Start, End, &GfxScanData.ScanData); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGetDiscreteCardInfo Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +GfxScanPcieDevice ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + UINT8 ClassCode; + UINT32 VendorId; + + IDS_HDT_CONSOLE (GFX_MISC, " Evaluate device [%d:%d:%d]\n", + Device.Address.Bus, Device.Address.Device, Device.Address.Function + ); + + if (GnbLibPciIsBridgeDevice (Device.AddressValue, ScanData->StdHeader)) { + UINT32 SaveBusConfiguration; + UINT32 Value; + + if (Device.Address.Bus == 0) { + ((GFX_SCAN_DATA *) ScanData)->BaseBridge = Device; + } + GnbLibPciRead (Device.AddressValue | 0x18, AccessWidth32, &SaveBusConfiguration, ScanData->StdHeader); + Value = (((0xFF << 8) | ((GFX_SCAN_DATA *) ScanData)->BusNumber) << 8) | Device.Address.Bus; + GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &Value, ScanData->StdHeader); + ((GFX_SCAN_DATA *) ScanData)->BusNumber++; + + GnbLibPciScanSecondaryBus (Device, ScanData); + + ((GFX_SCAN_DATA *) ScanData)->BusNumber--; + GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &SaveBusConfiguration, ScanData->StdHeader); + return 0; + } + GnbLibPciRead (Device.AddressValue | 0x0b, AccessWidth8, &ClassCode, ScanData->StdHeader); + if (ClassCode == 3) { + IDS_HDT_CONSOLE (GFX_MISC, " Found GFX Card\n" + ); + + GnbLibPciRead (Device.AddressValue | 0x00, AccessWidth32, &VendorId, ScanData->StdHeader); + if (!GnbLibPciIsPcieDevice (Device.AddressValue, ScanData->StdHeader)) { + IDS_HDT_CONSOLE (GFX_MISC, " GFX Card is PCI device\n" + ); + ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->PciGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); + return 0; + } + if ((UINT16) VendorId == 0x1002) { + IDS_HDT_CONSOLE (GFX_MISC, " GFX Card is AMD PCIe device\n" + ); + ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->AmdPcieGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); + } + ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->PcieGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); + } + return 0; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h new file mode 100755 index 0000000000..40ca880728 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to collect discrete GFX card info + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 46832 $ @e \$Date: 2011-02-11 02:21:54 +0800 (Fri, 11 Feb 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + + +#ifndef _GFXCARDINFO_H_ +#define _GFXCARDINFO_H_ + +/// Graphics card information structure +//typedef struct { +// UINT32 AmdPcieGfxCardBitmap; ///< AMD PCIE graphics card information +// UINT32 PcieGfxCardBitmap; ///< All PCIE graphics card information +// UINT32 PciGfxCardBitmap; ///< All PCI graphics card information +//} GFX_CARD_CARD_INFO; + +VOID +GfxGetDiscreteCardInfo ( + OUT GFX_CARD_CARD_INFO *GfxCardInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c new file mode 100755 index 0000000000..83d2d7538f --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c @@ -0,0 +1,587 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Integrated Info Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieConfig.h" +#include "GnbGfxFamServices.h" +#include "GnbRegistersLN.h" +#include "GfxEnumConnectors.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GFXENUMCONNECTORS_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 + *---------------------------------------------------------------------------------------- + */ + + +typedef struct { + PCIE_CONNECTOR_TYPE ConnectorType; + UINT8 DisplayDeviceEnum; + UINT16 ConnectorEnum; + UINT16 EncoderEnum; + UINT8 ConnectorIndex; +} EXT_CONNECTOR_INFO; + +typedef struct { + UINT8 DisplayDeviceEnum; + UINT8 DeviceIndex; + UINT16 DeviceTag; + UINT16 DeviceAcpiEnum; +} EXT_DISPLAY_DEVICE_INFO; + +typedef struct { + AGESA_STATUS Status; + UINT8 DisplayDeviceEnum; + UINT8 RequestedPriorityIndex; + UINT8 CurrentPriorityIndex; + PCIe_ENGINE_CONFIG *Engine; +} CONNECTOR_ENUM_INFO; + + +/*---------------------------------------------------------------------------------------- + * 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 +GfxIntegratedEnumConnectorsForDevice ( + IN UINT8 DisplayDeviceEnum, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxIntegratedDebugDumpDisplayPath ( + IN EXT_DISPLAY_PATH *DisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +EXT_CONNECTOR_INFO* +GfxIntegratedExtConnectorInfo ( + IN UINT8 ConnectorType + ); + +EXT_DISPLAY_DEVICE_INFO* +GfxIntegratedExtDisplayDeviceInfo ( + IN UINT8 DisplayDeviceEnum, + IN UINT8 DisplayDeviceIndex + ); + + +EXT_CONNECTOR_INFO ConnectorInfoTable[] = { + { + ConnectorTypeDP, + DEVICE_DFP, + CONNECTOR_DISPLAYPORT_ENUM, + ENCODER_NOT_PRESENT, + 0, + }, + { + ConnectorTypeEDP, + DEVICE_LCD, + CONNECTOR_eDP_ENUM, + ENCODER_NOT_PRESENT, + 1 + }, + { + ConnectorTypeSingleLinkDVI, + DEVICE_DFP, + CONNECTOR_SINGLE_LINK_DVI_D_ENUM, + ENCODER_NOT_PRESENT, + 2 + }, + { + ConnectorTypeDualLinkDVI, + DEVICE_DFP, + CONNECTOR_DUAL_LINK_DVI_D_ENUM, + ENCODER_NOT_PRESENT, + 3 + }, + { + ConnectorTypeHDMI, + DEVICE_DFP, + CONNECTOR_HDMI_TYPE_A_ENUM, + ENCODER_NOT_PRESENT, + 4 + }, + { + ConnectorTypeTravisDpToVga, + DEVICE_CRT, + CONNECTOR_VGA_ENUM, + ENCODER_TRAVIS_ENUM_ID1, + 5 + }, + { + ConnectorTypeTravisDpToLvds, + DEVICE_LCD, + CONNECTOR_LVDS_ENUM, + ENCODER_TRAVIS_ENUM_ID2, + 6 + }, + { + ConnectorTypeNutmegDpToVga, + DEVICE_CRT, + CONNECTOR_VGA_ENUM, + ENCODER_ALMOND_ENUM_ID1, + 5 + }, + { + ConnectorTypeSingleLinkDviI, + DEVICE_DFP, + CONNECTOR_SINGLE_LINK_DVI_I_ENUM, + ENCODER_NOT_PRESENT, + 5 + }, + { + ConnectorTypeCrt, + DEVICE_CRT, + CONNECTOR_VGA_ENUM, + ENCODER_NOT_PRESENT, + 5 + }, + { + ConnectorTypeLvds, + DEVICE_LCD, + CONNECTOR_LVDS_ENUM, + ENCODER_NOT_PRESENT, + 6 + }, + { + ConnectorTypeAutoDetect, + DEVICE_LCD, + CONNECTOR_LVDS_eDP_ENUM, + ENCODER_TRAVIS_ENUM_ID2, + 7 + } +}; + +UINT8 ConnectorNumerArray[] = { +// DP eDP SDVI-D DDVI-D HDMI VGA LVDS Auto (eDP, LVDS, Travis LVDS) + 6, 1, 6, 6, 6, 1, 1, 2 +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] ConnectorType Connector type (see PCIe_DDI_DATA::ConnectorType). + * @retval Pointer to EXT_CONNECTOR_INFO + * @retval NULL if connector type unknown. + */ +EXT_CONNECTOR_INFO* +GfxIntegratedExtConnectorInfo ( + IN UINT8 ConnectorType + ) +{ + UINTN Index; + for (Index = 0; Index < (sizeof (ConnectorInfoTable) / sizeof (EXT_CONNECTOR_INFO)); Index++) { + if (ConnectorInfoTable[Index].ConnectorType == ConnectorType) { + return &ConnectorInfoTable[Index]; + } + } + return NULL; +} + +EXT_DISPLAY_DEVICE_INFO DisplayDeviceInfoTable[] = { + { + DEVICE_CRT, + 1, + ATOM_DEVICE_CRT1_SUPPORT, + 0x100, + }, + { + DEVICE_LCD, + 1, + ATOM_DEVICE_LCD1_SUPPORT, + 0x110, + }, + { + DEVICE_DFP, + 1, + ATOM_DEVICE_DFP1_SUPPORT, + 0x210, + }, + { + DEVICE_DFP, + 2, + ATOM_DEVICE_DFP2_SUPPORT, + 0x220, + }, + { + DEVICE_DFP, + 3, + ATOM_DEVICE_DFP3_SUPPORT, + 0x230, + }, + { + DEVICE_DFP, + 4, + ATOM_DEVICE_DFP4_SUPPORT, + 0x240, + }, + { + DEVICE_DFP, + 5, + ATOM_DEVICE_DFP5_SUPPORT, + 0x250, + }, + { + DEVICE_DFP, + 6, + ATOM_DEVICE_DFP6_SUPPORT, + 0x260, + } +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] DisplayDeviceEnum Display device enum + * @param[in] DisplayDeviceIndex Display device index + * @retval Pointer to EXT_DISPLAY_DEVICE_INFO + * @retval NULL if can not get display device info + */ +EXT_DISPLAY_DEVICE_INFO* +GfxIntegratedExtDisplayDeviceInfo ( + IN UINT8 DisplayDeviceEnum, + IN UINT8 DisplayDeviceIndex + ) +{ + UINT8 Index; + UINT8 LastIndex; + LastIndex = 0xff; + for (Index = 0; Index < (sizeof (DisplayDeviceInfoTable) / sizeof (EXT_DISPLAY_DEVICE_INFO)); Index++) { + if (DisplayDeviceInfoTable[Index].DisplayDeviceEnum == DisplayDeviceEnum) { + LastIndex = Index; + if (DisplayDeviceInfoTable[Index].DeviceIndex == DisplayDeviceIndex) { + return &DisplayDeviceInfoTable[Index]; + } + } + } + if (DisplayDeviceEnum == DEVICE_LCD && LastIndex != 0xff) { + return &DisplayDeviceInfoTable[LastIndex]; + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors + * + * + * + * @param[out] DisplayPathList Display path list + * @param[in,out] Pcie PCIe platform configuration info + * @param[in] Gfx Gfx configuration info + */ +AGESA_STATUS +GfxIntegratedEnumerateAllConnectors ( + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedEnumerateAllConnectors Enter\n"); + Status = GfxIntegratedEnumConnectorsForDevice ( + DEVICE_DFP, + DisplayPathList, + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + Status = GfxIntegratedEnumConnectorsForDevice ( + DEVICE_CRT, + DisplayPathList, + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + Status = GfxIntegratedEnumConnectorsForDevice ( + DEVICE_LCD, + DisplayPathList, + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedEnumerateAllConnectors Exit [0x%x]\n", Status); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] Engine Engine configuration info + * @param[in,out] Buffer Buffer pointer + * @param[in] Pcie PCIe configuration info + */ +VOID +STATIC +GfxIntegratedDdiInterfaceCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + CONNECTOR_ENUM_INFO *ConnectorEnumInfo; + EXT_CONNECTOR_INFO *ExtConnectorInfo; + ConnectorEnumInfo = (CONNECTOR_ENUM_INFO*) Buffer; + ExtConnectorInfo = GfxIntegratedExtConnectorInfo (Engine->Type.Ddi.DdiData.ConnectorType); + if (ExtConnectorInfo == NULL) { + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo->Status); + PcieConfigDisableEngine (Engine); + return; + } + if (ExtConnectorInfo->DisplayDeviceEnum != ConnectorEnumInfo->DisplayDeviceEnum) { + //Not device type we are looking for + return; + } + if (Engine->Type.Ddi.DisplayPriorityIndex >= ConnectorEnumInfo->RequestedPriorityIndex && + Engine->Type.Ddi.DisplayPriorityIndex < ConnectorEnumInfo->CurrentPriorityIndex) { + ConnectorEnumInfo->CurrentPriorityIndex = Engine->Type.Ddi.DisplayPriorityIndex; + ConnectorEnumInfo->Engine = Engine; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] DisplayDeviceEnum Display device list + * @param[out] DisplayPathList Display path list + * @param[in,out] Pcie PCIe configuration info + * @param[in] Gfx Gfx configuration info + */ +AGESA_STATUS +GfxIntegratedEnumConnectorsForDevice ( + IN UINT8 DisplayDeviceEnum, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 DisplayDeviceIndex; + CONNECTOR_ENUM_INFO ConnectorEnumInfo; + EXT_CONNECTOR_INFO *ExtConnectorInfo; + EXT_DISPLAY_DEVICE_INFO *ExtDisplayDeviceInfo; + AGESA_STATUS Status; + UINT8 ConnectorIdArray[sizeof (ConnectorNumerArray)]; + ConnectorEnumInfo.Status = AGESA_SUCCESS; + DisplayDeviceIndex = 1; + ConnectorEnumInfo.RequestedPriorityIndex = 0; + ConnectorEnumInfo.DisplayDeviceEnum = DisplayDeviceEnum; + LibAmdMemFill (ConnectorIdArray, 0x00, sizeof (ConnectorIdArray), GnbLibGetHeader (Gfx)); + do { + ConnectorEnumInfo.Engine = NULL; + ConnectorEnumInfo.CurrentPriorityIndex = 0xff; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_VIRTUAL | DESCRIPTOR_DDI_ENGINE, + GfxIntegratedDdiInterfaceCallback, + &ConnectorEnumInfo, + Pcie + ); + if (ConnectorEnumInfo.Engine == NULL) { + break; // No more connector support this + } + ConnectorEnumInfo.RequestedPriorityIndex = ConnectorEnumInfo.CurrentPriorityIndex + 1; + ExtConnectorInfo = GfxIntegratedExtConnectorInfo (ConnectorEnumInfo.Engine->Type.Ddi.DdiData.ConnectorType); + ASSERT (ExtConnectorInfo != NULL); + ASSERT (ExtConnectorInfo->ConnectorIndex < sizeof (ConnectorIdArray)); + if (ConnectorIdArray[ExtConnectorInfo->ConnectorIndex] >= ConnectorNumerArray[ExtConnectorInfo->ConnectorIndex]) { + //Run out of supported connectors + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo.Status); + PcieConfigDisableEngine (ConnectorEnumInfo.Engine); + continue; + } + ConnectorEnumInfo.Engine->Type.Ddi.ConnectorId = ConnectorIdArray[ExtConnectorInfo->ConnectorIndex] + 1; + ExtDisplayDeviceInfo = GfxIntegratedExtDisplayDeviceInfo (DisplayDeviceEnum, DisplayDeviceIndex); + if (ExtDisplayDeviceInfo == NULL) { + //Run out of supported display device types + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo.Status); + Status = AGESA_ERROR; + PcieConfigDisableEngine (ConnectorEnumInfo.Engine); + } + + if ((Gfx->Gnb3dStereoPinIndex != 0) && (ConnectorEnumInfo.Engine->Type.Ddi.DdiData.HdpIndex == (Gfx->Gnb3dStereoPinIndex - 1))) { + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo.Status); + Status = AGESA_ERROR; + PcieConfigDisableEngine (ConnectorEnumInfo.Engine); + } + + ConnectorEnumInfo.Engine->Type.Ddi.DisplayDeviceId = DisplayDeviceIndex; + + Status = GfxFmMapEngineToDisplayPath (ConnectorEnumInfo.Engine, DisplayPathList, Gfx); + AGESA_STATUS_UPDATE (Status, ConnectorEnumInfo.Status); + if (Status != AGESA_SUCCESS) { + continue; + } + ConnectorIdArray[ExtConnectorInfo->ConnectorIndex]++; + DisplayDeviceIndex++; + } while (ConnectorEnumInfo.Engine != NULL); + return ConnectorEnumInfo.Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize display path for given engine + * + * + * + * @param[in] Engine Engine configuration info + * @param[out] DisplayPath Display path list + * @param[out] SecondaryDisplayPath Secondary display path list + * @param[in] Gfx Gfx configuration info + */ + +VOID +GfxIntegratedCopyDisplayInfo ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPath, + OUT EXT_DISPLAY_PATH *SecondaryDisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + EXT_CONNECTOR_INFO *ExtConnectorInfo; + EXT_DISPLAY_DEVICE_INFO *ExtDisplayDeviceInfo; + ExtConnectorInfo = GfxIntegratedExtConnectorInfo (Engine->Type.Ddi.DdiData.ConnectorType); + ExtDisplayDeviceInfo = GfxIntegratedExtDisplayDeviceInfo (ExtConnectorInfo->DisplayDeviceEnum, Engine->Type.Ddi.DisplayDeviceId); + DisplayPath->usDeviceConnector = ExtConnectorInfo->ConnectorEnum | (Engine->Type.Ddi.ConnectorId << 8); + DisplayPath->usDeviceTag = ExtDisplayDeviceInfo->DeviceTag; + DisplayPath->usDeviceACPIEnum = ExtDisplayDeviceInfo->DeviceAcpiEnum; + DisplayPath->ucExtAUXDDCLutIndex = Engine->Type.Ddi.DdiData.AuxIndex; + DisplayPath->ucExtHPDPINLutIndex = Engine->Type.Ddi.DdiData.HdpIndex; + DisplayPath->ucChPNInvert = Engine->Type.Ddi.DdiData.LanePnInversionMask; + DisplayPath->usExtEncoderObjId = ExtConnectorInfo->EncoderEnum; + if (Engine->Type.Ddi.DdiData.Mapping[0].ChannelMappingValue == 0) { + DisplayPath->ChannelMapping.ucChannelMapping = (Engine->EngineData.StartLane < Engine->EngineData.EndLane) ? 0xE4 : 0x1B; + } else { + DisplayPath->ChannelMapping.ucChannelMapping = Engine->Type.Ddi.DdiData.Mapping[0].ChannelMappingValue; + } + GNB_DEBUG_CODE ( + GfxIntegratedDebugDumpDisplayPath (DisplayPath, Gfx); + ); + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDualLinkDVI) { + ASSERT (SecondaryDisplayPath != NULL); + GNB_DEBUG_CODE ( + GfxIntegratedDebugDumpDisplayPath (DisplayPath, Gfx); + ); + SecondaryDisplayPath->usDeviceConnector = DisplayPath->usDeviceConnector; + if (Engine->Type.Ddi.DdiData.Mapping[1].ChannelMappingValue == 0) { + DisplayPath->ChannelMapping.ucChannelMapping = (Engine->EngineData.StartLane < Engine->EngineData.EndLane) ? 0xE4 : 0x1B; + } else { + DisplayPath->ChannelMapping.ucChannelMapping = Engine->Type.Ddi.DdiData.Mapping[1].ChannelMappingValue; + } + } +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump display path settings + * + * + * + * @param[in] DisplayPath Display path + * @param[in] Gfx Gfx configuration + */ + +VOID +GfxIntegratedDebugDumpDisplayPath ( + IN EXT_DISPLAY_PATH *DisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + IDS_HDT_CONSOLE (GFX_MISC, " usDeviceConnector = 0x%x\n", + DisplayPath->usDeviceConnector + ); + IDS_HDT_CONSOLE (GFX_MISC, " usDeviceTag = 0x%x\n", + DisplayPath->usDeviceTag + ); + IDS_HDT_CONSOLE (GFX_MISC, " usDeviceACPIEnum = 0x%x\n", + DisplayPath->usDeviceACPIEnum + ); + IDS_HDT_CONSOLE (GFX_MISC, " usExtEncoderObjId = 0x%x\n", + DisplayPath->usExtEncoderObjId + ); + IDS_HDT_CONSOLE (GFX_MISC, " ucChannelMapping = 0x%x\n", + DisplayPath->ChannelMapping.ucChannelMapping + ); + IDS_HDT_CONSOLE (GFX_MISC, " ucChPNInvert = 0x%x\n", + DisplayPath->ucChPNInvert + ); +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h new file mode 100755 index 0000000000..1d467acc56 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h @@ -0,0 +1,64 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Integrated Info Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _GFXENUMCONNECTORS_H_ +#define _GFXENUMCONNECTORS_H_ + + +VOID +GfxIntegratedCopyDisplayInfo ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPath, + OUT EXT_DISPLAY_PATH *SecondaryDisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxIntegratedEnumerateAllConnectors ( + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxPowerPlayTable.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxPowerPlayTable.c new file mode 100755 index 0000000000..6642c8a962 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxPowerPlayTable.c @@ -0,0 +1,735 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Integrated Info Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "GnbFuseTable.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbFuseTable.h" +#include "GnbGfxFamServices.h" +#include "GnbCommonLib.h" +#include "GfxPowerPlayTable.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GFXPOWERPLAYTABLE_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 + *---------------------------------------------------------------------------------------- + */ +/// Software state +typedef struct { + BOOLEAN Valid; ///< State valid + UINT16 Classification; ///< State classification + UINT32 CapsAndSettings; ///< State capability and settings + UINT16 Classification2; ///< State classification2 + UINT32 Vclk; ///< UVD VCLK + UINT32 Dclk; ///< UVD DCLK + UINT8 NumberOfDpmStates; ///< Number of DPM states + UINT8 DpmSatesArray[MAX_NUM_OF_DPM_STATES]; ///< DPM state index array +} SW_STATE; + +/// DPM state +typedef struct { + BOOLEAN Valid; ///< State valid + UINT32 Sclk; ///< Sclk in kHz + UINT8 Vid; ///< VID index + UINT16 Tdp; ///< Tdp limit +} DPM_STATE; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +UINT16 +GfxPowerPlayLocateTdp ( + IN PP_FUSE_ARRAY *PpFuses, + IN UINT32 Sclk, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GfxPowerPlayAddDpmState ( + IN DPM_STATE *DpmStateArray, + IN UINT32 Sclk, + IN UINT8 Vid, + IN UINT16 Tdp + ); + +VOID +GfxPowerPlayAddDpmStateToSwState ( + IN OUT SW_STATE *SwStateArray, + IN UINT8 DpmStateIndex + ); + +SW_STATE* +GfxPowerPlayCreateSwState ( + IN OUT SW_STATE *SwStateArray + ); + +UINT8 +GfxPowerPlayCreateDpmState ( + IN DPM_STATE *DpmStateArray, + IN UINT32 Sclk, + IN UINT8 Vid, + IN UINT16 Tdp + ); + +UINT32 +GfxPowerPlayCopyStateInfo ( + IN OUT STATE_ARRAY *StateArray, + IN SW_STATE *SwStateArray, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GfxPowerPlayCopyClockInfo ( + IN CLOCK_INFO_ARRAY *ClockInfoArray, + IN DPM_STATE *DpmStateArray, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GfxPowerPlayCopyNonClockInfo ( + IN NON_CLOCK_INFO_ARRAY *NonClockInfoArray, + IN SW_STATE *SwStateArray, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GfxPowerPlayIsFusedStateValid ( + IN UINT8 Index, + IN PP_FUSE_ARRAY *PpFuses, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +UINT16 +GfxPowerPlayGetClassificationFromFuses ( + IN UINT8 Index, + IN PP_FUSE_ARRAY *PpFuses, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +UINT16 +GfxPowerPlayGetClassification2FromFuses ( + IN UINT8 Index, + IN PP_FUSE_ARRAY *PpFuses, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxIntegratedDebugDumpPpTable ( + IN ATOM_PPLIB_POWERPLAYTABLE3 *PpTable, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate existing tdp + * + * + * @param[in ] PpFuses Pointer to PP_FUSE_ARRAY + * @param[in] Sclk Sclk in 10kHz + * @param[in] StdHeader Standard configuration header + * @retval Tdp limit in DPM state array + */ + +UINT16 +GfxPowerPlayLocateTdp ( + IN PP_FUSE_ARRAY *PpFuses, + IN UINT32 Sclk, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + UINT32 DpmIndex; + UINT32 DpmSclk; + UINT32 DeltaSclk; + UINT32 MinDeltaSclk; + + DpmIndex = 0; + MinDeltaSclk = 0xFFFFFFFF; + for (Index = 0; Index < MAX_NUM_OF_FUSED_DPM_STATES; Index++) { + if (PpFuses->SclkDpmDid[Index] != 0) { + DpmSclk = GfxFmCalculateClock (PpFuses->SclkDpmDid[Index], StdHeader); + DeltaSclk = (DpmSclk > Sclk) ? (DpmSclk - Sclk) : (Sclk - DpmSclk); + if (DeltaSclk < MinDeltaSclk) { + MinDeltaSclk = MinDeltaSclk; + DpmIndex = Index; + } + } + } + return PpFuses->SclkDpmTdpLimit[DpmIndex]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create new software state + * + * + * @param[in, out] SwStateArray Pointer to SW state array + * @retval Pointer to state entry in SW state array + */ + +SW_STATE* +GfxPowerPlayCreateSwState ( + IN OUT SW_STATE *SwStateArray + ) +{ + UINTN Index; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (SwStateArray[Index].Valid == FALSE) { + SwStateArray[Index].Valid = TRUE; + return &SwStateArray[Index]; + } + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create new DPM state + * + * + * @param[in, out] DpmStateArray Pointer to DPM state array + * @param[in] Sclk SCLK in kHz + * @param[in] Vid Vid index + * @param[in] Tdp Tdp limit + * @retval Index of state entry in DPM state array + */ + +UINT8 +GfxPowerPlayCreateDpmState ( + IN DPM_STATE *DpmStateArray, + IN UINT32 Sclk, + IN UINT8 Vid, + IN UINT16 Tdp + ) +{ + UINT8 Index; + for (Index = 0; Index < MAX_NUM_OF_DPM_STATES; Index++) { + if (DpmStateArray[Index].Valid == FALSE) { + DpmStateArray[Index].Sclk = Sclk; + DpmStateArray[Index].Vid = Vid; + DpmStateArray[Index].Valid = TRUE; + DpmStateArray[Index].Tdp = Tdp; + return Index; + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate existing or Create new DPM state + * + * + * @param[in, out] DpmStateArray Pointer to DPM state array + * @param[in] Sclk SCLK in kHz + * @param[in] Vid Vid index + * @param[in] Tdp Tdp limit + * @retval Index of state entry in DPM state array + */ + +UINT8 +GfxPowerPlayAddDpmState ( + IN DPM_STATE *DpmStateArray, + IN UINT32 Sclk, + IN UINT8 Vid, + IN UINT16 Tdp + ) +{ + UINT8 Index; + for (Index = 0; Index < MAX_NUM_OF_DPM_STATES; Index++) { + if (DpmStateArray[Index].Valid && Sclk == DpmStateArray[Index].Sclk && Vid == DpmStateArray[Index].Vid) { + return Index; + } + } + return GfxPowerPlayCreateDpmState (DpmStateArray, Sclk, Vid, Tdp); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add reference to DPM state for SW state + * + * + * @param[in, out] SwStateArray Pointer to SW state array + * @param[in] DpmStateIndex DPM state index + */ + +VOID +GfxPowerPlayAddDpmStateToSwState ( + IN OUT SW_STATE *SwStateArray, + IN UINT8 DpmStateIndex + ) +{ + SwStateArray->DpmSatesArray[SwStateArray->NumberOfDpmStates++] = DpmStateIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy SW state info to PPTable + * + * + * @param[out] StateArray Pointer to PPtable SW state array + * @param[in] SwStateArray Pointer to SW state array + * @param[in] StdHeader Standard configuration header + */ +UINT32 +GfxPowerPlayCopyStateInfo ( + IN OUT STATE_ARRAY *StateArray, + IN SW_STATE *SwStateArray, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + UINT8 SwStateIndex; + ATOM_PPLIB_STATE_V2 *States; + States = &StateArray->States[0]; + SwStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (SwStateArray[Index].Valid && SwStateArray[Index].NumberOfDpmStates != 0) { + States->nonClockInfoIndex = SwStateIndex; + States->ucNumDPMLevels = SwStateArray[Index].NumberOfDpmStates; + LibAmdMemCopy ( + &States->ClockInfoIndex[0], + SwStateArray[Index].DpmSatesArray, + SwStateArray[Index].NumberOfDpmStates, + StdHeader + ); + States = (ATOM_PPLIB_STATE_V2*) ((UINT8*) States + sizeof (ATOM_PPLIB_STATE_V2) + sizeof (UINT8) * (States->ucNumDPMLevels - 1)); + SwStateIndex++; + } + } + StateArray->ucNumEntries = SwStateIndex; + return (UINT32) ((UINT8*) States - (UINT8*) StateArray); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Copy clock info to PPTable + * + * + * @param[out] ClockInfoArray Pointer to clock info array + * @param[in] DpmStateArray Pointer to DPM state array + * @param[in] StdHeader Standard configuration header + */ + +UINT32 +GfxPowerPlayCopyClockInfo ( + IN CLOCK_INFO_ARRAY *ClockInfoArray, + IN DPM_STATE *DpmStateArray, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + UINT8 ClkStateIndex; + ClkStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_DPM_STATES; Index++) { + if (DpmStateArray[Index].Valid == TRUE) { + ClockInfoArray->ClockInfo[ClkStateIndex].ucEngineClockHigh = (UINT8) (DpmStateArray[Index].Sclk >> 16); + ClockInfoArray->ClockInfo[ClkStateIndex].usEngineClockLow = (UINT16) (DpmStateArray[Index].Sclk); + ClockInfoArray->ClockInfo[ClkStateIndex].vddcIndex = DpmStateArray[Index].Vid; + ClockInfoArray->ClockInfo[ClkStateIndex].tdpLimit = DpmStateArray[Index].Tdp; + ClkStateIndex++; + } + } + ClockInfoArray->ucNumEntries = ClkStateIndex; + ClockInfoArray->ucEntrySize = sizeof (ATOM_PPLIB_SUMO_CLOCK_INFO); + return sizeof (CLOCK_INFO_ARRAY) + sizeof (ATOM_PPLIB_SUMO_CLOCK_INFO) * (ClkStateIndex) - sizeof (ATOM_PPLIB_SUMO_CLOCK_INFO); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy non clock info to PPTable + * + * + * @param[out] NonClockInfoArray Pointer to PPtable Non clock array + * @param[in] SwStateArray Pointer to SW state array + * @param[in] StdHeader Standard configuration header + */ + +UINT32 +GfxPowerPlayCopyNonClockInfo ( + IN NON_CLOCK_INFO_ARRAY *NonClockInfoArray, + IN SW_STATE *SwStateArray, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + UINT8 NonClkStateIndex; + NonClkStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (SwStateArray[Index].Valid && SwStateArray[Index].NumberOfDpmStates != 0) { + NonClockInfoArray->NonClockInfo[NonClkStateIndex].usClassification = SwStateArray[Index].Classification; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ulCapsAndSettings = SwStateArray[Index].CapsAndSettings; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].usClassification2 = SwStateArray[Index].Classification2; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ulDCLK = SwStateArray[Index].Dclk; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ulVCLK = SwStateArray[Index].Vclk; + NonClkStateIndex++; + } + } + NonClockInfoArray->ucNumEntries = NonClkStateIndex; + NonClockInfoArray->ucEntrySize = sizeof (ATOM_PPLIB_NONCLOCK_INFO); + return sizeof (NON_CLOCK_INFO_ARRAY) + sizeof (ATOM_PPLIB_NONCLOCK_INFO) * NonClkStateIndex - sizeof (ATOM_PPLIB_NONCLOCK_INFO); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if fused state valid + * + * + * @param[out] Index State index + * @param[in] PpFuses Pointer to fuse table + * @param[in] Gfx Gfx configuration info + * @retval TRUE State is valid + */ +BOOLEAN +GfxPowerPlayIsFusedStateValid ( + IN UINT8 Index, + IN PP_FUSE_ARRAY *PpFuses, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + BOOLEAN Result; + Result = FALSE; + if (PpFuses->SclkDpmValid[Index] != 0) { + Result = TRUE; + if (PpFuses->PolicyLabel[Index] == POLICY_LABEL_BATTERY && (Gfx->AmdPlatformType & AMD_PLATFORM_MOBILE) == 0) { + Result = FALSE; + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get SW state calssification from fuses + * + * + * @param[out] Index State index + * @param[in] PpFuses Pointer to fuse table + * @param[in] Gfx Gfx configuration info + * @retval State classification + */ + +UINT16 +GfxPowerPlayGetClassificationFromFuses ( + IN UINT8 Index, + IN PP_FUSE_ARRAY *PpFuses, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT16 Classification; + Classification = 0; + switch (PpFuses->PolicyFlags[Index]) { + case 0x1: + Classification |= ATOM_PPLIB_CLASSIFICATION_NONUVDSTATE; + break; + case 0x2: + Classification |= ATOM_PPLIB_CLASSIFICATION_UVDSTATE; + break; + case 0x4: + //Possible SD + HD state + break; + case 0x8: + Classification |= ATOM_PPLIB_CLASSIFICATION_HDSTATE; + break; + case 0x10: + Classification |= ATOM_PPLIB_CLASSIFICATION_SDSTATE; + break; + default: + break; + } + switch (PpFuses->PolicyLabel[Index]) { + case POLICY_LABEL_BATTERY: + Classification |= ATOM_PPLIB_CLASSIFICATION_UI_BATTERY; + break; + case POLICY_LABEL_PERFORMANCE: + Classification |= ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE; + break; + default: + break; + } + return Classification; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get SW state calssification2 from fuses + * + * + * @param[out] Index State index + * @param[in] PpFuses Pointer to fuse table + * @param[in] Gfx Gfx configuration info + * @retval State classification2 + */ + +UINT16 +GfxPowerPlayGetClassification2FromFuses ( + IN UINT8 Index, + IN PP_FUSE_ARRAY *PpFuses, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT16 Classification2; + Classification2 = 0; + + switch (PpFuses->PolicyFlags[Index]) { + + case 0x4: + Classification2 |= ATOM_PPLIB_CLASSIFICATION2_MVC; + break; + + default: + break; + } + + return Classification2; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build PP table + * + * + * @param[out] Buffer Buffer to create PP table + * @param[in] Gfx Gfx configuration info + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +GfxPowerPlayBuildTable ( + OUT VOID *Buffer, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + ATOM_PPLIB_POWERPLAYTABLE3 *PpTable; + SW_STATE SwStateArray [MAX_NUM_OF_SW_STATES]; + DPM_STATE DpmStateArray[MAX_NUM_OF_DPM_STATES]; + UINT8 ClkStateIndex; + UINT8 DpmFuseIndex; + UINT8 Index; + UINT32 StateArrayLength; + UINT32 ClockArrayLength; + UINT32 NonClockArrayLength; + SW_STATE *State; + PP_FUSE_ARRAY *PpFuses; + UINT32 Sclk; + + PpFuses = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, GnbLibGetHeader (Gfx)); + ASSERT (PpFuses != NULL); + if (PpFuses == NULL) { + return AGESA_ERROR; + } + + PpTable = (ATOM_PPLIB_POWERPLAYTABLE3 *) Buffer; + LibAmdMemFill (SwStateArray, 0x00, sizeof (SwStateArray), GnbLibGetHeader (Gfx)); + LibAmdMemFill (DpmStateArray, 0x00, sizeof (DpmStateArray), GnbLibGetHeader (Gfx)); + // Create States from Fuses + for (Index = 0; Index < MAX_NUM_OF_FUSED_SW_STATES; Index++) { + if (GfxPowerPlayIsFusedStateValid (Index, PpFuses, Gfx)) { + //Create new SW State; + State = GfxPowerPlayCreateSwState (SwStateArray); + State->Classification = GfxPowerPlayGetClassificationFromFuses (Index, PpFuses, Gfx); + State->Classification2 = GfxPowerPlayGetClassification2FromFuses (Index, PpFuses, Gfx); + if ((State->Classification & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_UVDSTATE)) != 0 || + (State->Classification2 & ATOM_PPLIB_CLASSIFICATION2_MVC) != 0) { + State->Vclk = (PpFuses->VclkDid[PpFuses->VclkDclkSel[Index]] != 0) ? GfxFmCalculateClock (PpFuses->VclkDid[PpFuses->VclkDclkSel[Index]], GnbLibGetHeader (Gfx)) : 0; + State->Dclk = (PpFuses->DclkDid[PpFuses->VclkDclkSel[Index]] != 0) ? GfxFmCalculateClock (PpFuses->DclkDid[PpFuses->VclkDclkSel[Index]], GnbLibGetHeader (Gfx)) : 0; + } + if ((State->Classification & 0x7) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) { + if (Gfx->AbmSupport != 0) { + State->CapsAndSettings |= ATOM_PPLIB_ENABLE_VARIBRIGHT; + } + if (Gfx->DynamicRefreshRate != 0) { + State->CapsAndSettings |= ATOM_PPLIB_ENABLE_DRR; + } + } + for (DpmFuseIndex = 0; DpmFuseIndex < MAX_NUM_OF_FUSED_DPM_STATES; DpmFuseIndex++) { + if ((PpFuses->SclkDpmValid[Index] & (1 << DpmFuseIndex)) != 0 ) { + Sclk = (PpFuses->SclkDpmDid[DpmFuseIndex] != 0) ? GfxFmCalculateClock (PpFuses->SclkDpmDid[DpmFuseIndex], GnbLibGetHeader (Gfx)) : 0; + if (Sclk != 0) { + ClkStateIndex = GfxPowerPlayAddDpmState (DpmStateArray, Sclk, PpFuses->SclkDpmVid[DpmFuseIndex], PpFuses->SclkDpmTdpLimit[DpmFuseIndex]); + GfxPowerPlayAddDpmStateToSwState (State, ClkStateIndex); + } + } + } + } + } + // Create Boot State + State = GfxPowerPlayCreateSwState (SwStateArray); + State->Classification = ATOM_PPLIB_CLASSIFICATION_BOOT; + Sclk = 200 * 100; + ClkStateIndex = GfxPowerPlayAddDpmState (DpmStateArray, Sclk, 0, GfxPowerPlayLocateTdp (PpFuses, Sclk, GnbLibGetHeader (Gfx))); + GfxPowerPlayAddDpmStateToSwState (State, ClkStateIndex); + + // Create Thermal State + State = GfxPowerPlayCreateSwState (SwStateArray); + State->Classification = ATOM_PPLIB_CLASSIFICATION_THERMAL; + Sclk = GfxFmCalculateClock (PpFuses->SclkThermDid, GnbLibGetHeader (Gfx)); + ClkStateIndex = GfxPowerPlayAddDpmState (DpmStateArray, Sclk, 0, GfxPowerPlayLocateTdp (PpFuses, Sclk, GnbLibGetHeader (Gfx))); + GfxPowerPlayAddDpmStateToSwState (State, ClkStateIndex); + + //Copy state info to actual PP table + StateArrayLength = GfxPowerPlayCopyStateInfo ( + &PpTable->StateArray, + SwStateArray, + GnbLibGetHeader (Gfx) + ); + ClockArrayLength = GfxPowerPlayCopyClockInfo ( + (CLOCK_INFO_ARRAY*) ((UINT8 *)&PpTable->StateArray + StateArrayLength), + DpmStateArray, + GnbLibGetHeader (Gfx) + ); + NonClockArrayLength = GfxPowerPlayCopyNonClockInfo ( + (NON_CLOCK_INFO_ARRAY*) ((UINT8 *)&PpTable->StateArray + StateArrayLength + ClockArrayLength), + SwStateArray, + GnbLibGetHeader (Gfx) + ); + //Fill static info + PpTable->sHeader.ucTableFormatRevision = 6; + PpTable->sHeader.ucTableContentRevision = 1; + PpTable->ucDataRevision = PpFuses->PPlayTableRev; + PpTable->sThermalController.ucType = ATOM_PP_THERMALCONTROLLER_SUMO; + PpTable->sThermalController.ucFanParameters = ATOM_PP_FANPARAMETERS_NOFAN; + if ((Gfx->AmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { + PpTable->ulPlatformCaps |= ATOM_PP_PLATFORM_CAP_POWERPLAY; + } + PpTable->usStateArrayOffset = offsetof (ATOM_PPLIB_POWERPLAYTABLE3, StateArray); + PpTable->usClockInfoArrayOffset = (USHORT) (offsetof (ATOM_PPLIB_POWERPLAYTABLE3, StateArray) + StateArrayLength); + PpTable->usNonClockInfoArrayOffset = (USHORT) (offsetof (ATOM_PPLIB_POWERPLAYTABLE3, StateArray) + StateArrayLength + ClockArrayLength); + PpTable->sHeader.usStructureSize = (USHORT) (offsetof (ATOM_PPLIB_POWERPLAYTABLE3, StateArray) + StateArrayLength + ClockArrayLength + NonClockArrayLength); + PpTable->usFormatID = 7; + GNB_DEBUG_CODE ( + GfxIntegratedDebugDumpPpTable (PpTable, Gfx); + ); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump PP table + * + * + * + * @param[in] PpTable Power Play table + * @param[in] Gfx Gfx configuration info + */ + +VOID +GfxIntegratedDebugDumpPpTable ( + IN ATOM_PPLIB_POWERPLAYTABLE3 *PpTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINTN Index; + UINTN DpmIndex; + ATOM_PPLIB_STATE_V2 *StatesPtr; + NON_CLOCK_INFO_ARRAY *NonClockInfoArrayPtr; + CLOCK_INFO_ARRAY *ClockInfoArrayPtr; + IDS_HDT_CONSOLE (GFX_MISC, " < --- Power Play Table ------ > \n"); + + IDS_HDT_CONSOLE (GFX_MISC, " Table Revision = %d\n", PpTable->ucDataRevision + ); + StatesPtr = PpTable->StateArray.States; + NonClockInfoArrayPtr = (NON_CLOCK_INFO_ARRAY *) ((UINT8 *) PpTable + PpTable->usNonClockInfoArrayOffset); + ClockInfoArrayPtr = (CLOCK_INFO_ARRAY *) ((UINT8 *) PpTable + PpTable->usClockInfoArrayOffset); + for (Index = 0; Index < PpTable->StateArray.ucNumEntries; Index++) { + IDS_HDT_CONSOLE (GFX_MISC, " State #%d\n", Index + 1 + ); + IDS_HDT_CONSOLE (GFX_MISC, " Classification 0x%x\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].usClassification + ); + IDS_HDT_CONSOLE (GFX_MISC, " Classification2 0x%x\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].usClassification2 + ); + IDS_HDT_CONSOLE (GFX_MISC, " VCLK = %dkHz\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].ulVCLK + ); + IDS_HDT_CONSOLE (GFX_MISC, " DCLK = %dkHz\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].ulDCLK + ); + IDS_HDT_CONSOLE (GFX_MISC, " DPM State Index: "); + for (DpmIndex = 0; DpmIndex < StatesPtr->ucNumDPMLevels; DpmIndex++) { + IDS_HDT_CONSOLE (GFX_MISC, "%d ", + StatesPtr->ClockInfoIndex [DpmIndex] + ); + } + IDS_HDT_CONSOLE (GFX_MISC, "\n"); + StatesPtr = (ATOM_PPLIB_STATE_V2 *) ((UINT8 *) StatesPtr + sizeof (ATOM_PPLIB_STATE_V2) + StatesPtr->ucNumDPMLevels - 1); + } + for (Index = 0; Index < ClockInfoArrayPtr->ucNumEntries; Index++) { + UINT32 Sclk; + Sclk = ClockInfoArrayPtr->ClockInfo[Index].usEngineClockLow | (ClockInfoArrayPtr->ClockInfo[Index].ucEngineClockHigh << 16); + IDS_HDT_CONSOLE (GFX_MISC, " DPM State #%d\n", + Index + ); + IDS_HDT_CONSOLE (GFX_MISC, " SCLK = %d\n", + ClockInfoArrayPtr->ClockInfo[Index].usEngineClockLow | (ClockInfoArrayPtr->ClockInfo[Index].ucEngineClockHigh << 16) + ); + IDS_HDT_CONSOLE (GFX_MISC, " VID index = %d\n", + ClockInfoArrayPtr->ClockInfo[Index].vddcIndex + ); + IDS_HDT_CONSOLE (GFX_MISC, " tdpLimit = %d\n", + ClockInfoArrayPtr->ClockInfo[Index].tdpLimit + ); + } +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxPowerPlayTable.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxPowerPlayTable.h new file mode 100755 index 0000000000..c806d77ef9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GfxPowerPlayTable.h @@ -0,0 +1,200 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Power Play Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 45407 $ @e \$Date: 2011-01-17 15:28:58 +0800 (Mon, 17 Jan 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ +#ifndef _GFXPOWERPLAYTABLE_H_ +#define _GFXPOWERPLAYTABLE_H_ + +#pragma pack (push, 1) + +#define POLICY_LABEL_BATTERY 0x1 +#define POLICY_LABEL_PERFORMANCE 0x2 + +#define MAX_NUM_OF_SW_STATES 10 +#define MAX_NUM_OF_DPM_STATES 10 +#define MAX_NUM_OF_FUSED_DPM_STATES 5 +#define MAX_NUM_OF_FUSED_SW_STATES 6 +/// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps +#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1 +#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2 +#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4 +#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8 +#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16 +#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32 +#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64 +#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128 +#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256 +#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512 +#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024 +#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048 +#define ATOM_PP_PLATFORM_CAP_MVDDCONTROL 4096 +#define ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT 0x2000 // Go to boot state on alerts, e.g. on an AC->DC transition. +#define ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT 0x4000 // Do NOT wait for VBLANK during an alert (e.g. AC->DC transition). +#define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000 // Does +#define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000 // Enable the 'regulator hot' feature. +#define ATOM_PP_PLATFORM_CAP_BACO 0x00020000 // Does the driver supports BACO state. + + +#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 +#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 +#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 + +#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 +#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 +#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 +#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 +#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 +#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100 +#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200 +#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400 +#define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800 +#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 +#define ATOM_PPLIB_CLASSIFICATION_HD2STATE 0x2000 +#define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 +#define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 +#define ATOM_PPLIB_CLASSIFICATION_NONUVDSTATE 0x0000 + +#define ATOM_PPLIB_CLASSIFICATION2_MVC 0x0004 //Multi-View + +#define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000 +#define ATOM_PPLIB_ENABLE_DRR 0x00080000 + +#define ATOM_PP_FANPARAMETERS_NOFAN 0x80 +#define ATOM_PP_THERMALCONTROLLER_SUMO 0x0E + +/// DPM state info +typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO { + USHORT usEngineClockLow; ///< Sclk [15:0] (Sclk in 10khz) + UCHAR ucEngineClockHigh; ///< Sclk [23:16](Sclk in 10khz) + UCHAR vddcIndex; ///< 2-bit VDDC index; + USHORT tdpLimit; ///< TDP Limit + USHORT rsv1; ///< Reserved + ULONG rsv2[2]; ///< Reserved +} ATOM_PPLIB_SUMO_CLOCK_INFO; + +/// Non clock info +typedef struct _ATOM_PPLIB_NONCLOCK_INFO { + USHORT usClassification; ///< State classification see ATOM_PPLIB_CLASSIFICATION_* + UCHAR ucMinTemperature; ///< Reserved + UCHAR ucMaxTemperature; ///< Reserved + ULONG ulCapsAndSettings; ///< Capability Setting (ATOM_PPLIB_ENABLE_DRR or ATOM_PPLIB_ENABLE_VARIBRIGHT or 0) + UCHAR ucRequiredPower; ///< Reserved + USHORT usClassification2; ///< Reserved + ULONG ulVCLK; ///< UVD clocks VCLK unit is in 10KHz + ULONG ulDCLK; ///< UVD clocks DCLK unit is in 10KHz + UCHAR ucUnused[5]; ///< Reserved +} ATOM_PPLIB_NONCLOCK_INFO; + +/// Thermal controller info stub +typedef struct _ATOM_PPLIB_THERMALCONTROLLER { + UCHAR ucType; ///< Reserved. Should be set 0xE + UCHAR ucI2cLine; ///< Reserved. Should be set 0 + UCHAR ucI2cAddress; ///< Reserved. Should be set 0 + UCHAR ucFanParameters; ///< Reserved. Should be set 0x80 + UCHAR ucFanMinRPM; ///< Reserved. Should be set 0 + UCHAR ucFanMaxRPM; ///< Reserved. Should be set 0 + UCHAR ucReserved; ///< Reserved. Should be set 0 + UCHAR ucFlags; ///< Reserved. Should be set 0 +} ATOM_PPLIB_THERMALCONTROLLER; + +/// SW state info +typedef struct _ATOM_PPLIB_STATE_V2 { + UCHAR ucNumDPMLevels; ///< Number of valid DPM levels in this state + UCHAR nonClockInfoIndex; ///< Index to the array of NonClockInfos + UCHAR ClockInfoIndex[1]; ///< Array of DPM states. Actual number calculated during state enumeration +} ATOM_PPLIB_STATE_V2; + +/// SW state Array +typedef struct { + UCHAR ucNumEntries; ///< Number of SW states + ATOM_PPLIB_STATE_V2 States[1]; ///< SW state info. Actual number calculated during state enumeration +} STATE_ARRAY; + +/// Clock info Array +typedef struct { + UCHAR ucNumEntries; ///< Number of ClockInfo entries + UCHAR ucEntrySize; ///< size of ATOM_PPLIB_SUMO_CLOCK_INFO + ATOM_PPLIB_SUMO_CLOCK_INFO ClockInfo[1]; ///< Clock info array. Size will be determined dynamically base on fuses +} CLOCK_INFO_ARRAY; + +/// Non clock info Array +typedef struct { + + UCHAR ucNumEntries; ///< Number of Entries; + UCHAR ucEntrySize; ///< Size of NonClockInfo + ATOM_PPLIB_NONCLOCK_INFO NonClockInfo[1]; ///< Non clock info array +} NON_CLOCK_INFO_ARRAY; + +/// Power Play table +typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 { + ATOM_COMMON_TABLE_HEADER sHeader; ///< Common header + UCHAR ucDataRevision; ///< Revision of PP table + UCHAR Reserved1[4]; ///< Reserved + USHORT usStateArrayOffset; ///< Offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures + USHORT usClockInfoArrayOffset; ///< Offset from start of the table to ClockInfoArray + USHORT usNonClockInfoArrayOffset; ///< Offset from Start of the table to NonClockInfoArray + USHORT Reserved2[2]; ///< Reserved + USHORT usTableSize; ///< the size of this structure, or the extended structure + ULONG ulPlatformCaps; ///< See ATOM_PPLIB_CAPS_* + ATOM_PPLIB_THERMALCONTROLLER sThermalController; ///< Thermal controller stub. + USHORT Reserved4[2]; ///< Reserved + UCHAR Reserved5; ///< Reserved + USHORT Reserved6; ///< Reserved + USHORT usFormatID; ///< Format ID + USHORT Reserved7[2]; ///< Reserved + STATE_ARRAY StateArray; ///< Array to hold the states. + CLOCK_INFO_ARRAY ClockInfoArray; ///< Array to hold clock info. + NON_CLOCK_INFO_ARRAY NonClockInfoArray; ///< Array to hold non clock info. +} ATOM_PPLIB_POWERPLAYTABLE3; + +#pragma pack (pop) + + +AGESA_STATUS +GfxPowerPlayBuildTable ( + OUT VOID *Buffer, + IN GFX_PLATFORM_CONFIG *Gfx + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c new file mode 100755 index 0000000000..bfd0f31a85 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c @@ -0,0 +1,143 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to collect discrete GFX card info + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 38931 $ @e \$Date: 2010-10-01 15:50:05 -0700 (Fri, 01 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 "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GfxCardInfo.h" +#include "GfxStrapsInit.h" +#include "GnbGfxInitLibV1.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GNBGFXINITLIBV1_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if GFX controller fused off + * + * + * @param[in] StdHeader Standard configuration header + * @retval TRUE Gfx controller present and available + */ +BOOLEAN +GfxLibIsControllerPresent ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return GnbLibPciIsDevicePresent (MAKE_SBDFO (0, 0, 1, 0, 0), StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Gfx SSID Registers + * + * + * + * @param[in] Gfx Pointer to global GFX configuration + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxInitSsid ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS Status; + UINT32 TempData; + PCI_ADDR IgpuAddress; + PCI_ADDR HdaudioAddress; + + Status = AGESA_SUCCESS; + TempData = 0; + + IgpuAddress = Gfx->GfxPciAddress; + HdaudioAddress = Gfx->GfxPciAddress; + HdaudioAddress.Address.Function = 1; + + // Set SSID for internal GPU + if (UserOptions.CfgGnbIGPUSSID != 0) { + GnbLibPciRMW ((IgpuAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, UserOptions.CfgGnbIGPUSSID, GnbLibGetHeader (Gfx)); + } else { + GnbLibPciRead (IgpuAddress.AddressValue, AccessS3SaveWidth32, &TempData, GnbLibGetHeader (Gfx)); + GnbLibPciRMW ((IgpuAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, TempData, GnbLibGetHeader (Gfx)); + } + + // Set SSID for internal HD Audio + if (UserOptions.CfgGnbHDAudioSSID != 0) { + GnbLibPciRMW ((HdaudioAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, UserOptions.CfgGnbHDAudioSSID, GnbLibGetHeader (Gfx)); + } else { + GnbLibPciRead (HdaudioAddress.AddressValue, AccessS3SaveWidth32, &TempData, GnbLibGetHeader (Gfx)); + GnbLibPciRMW ((HdaudioAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, TempData, GnbLibGetHeader (Gfx)); + } + + return Status; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h new file mode 100755 index 0000000000..3d142978cb --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Gfx Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + + +#ifndef _GNBGFXINITLIBV1_H_ +#define _GNBGFXINITLIBV1_H_ + +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GfxEnumConnectors.h" +#include "GfxPowerPlayTable.h" +#include "GfxCardInfo.h" + +BOOLEAN +GfxLibIsControllerPresent ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GfxGetUmaInfo ( + OUT UMA_INFO *UmaInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIommuIvrs/GnbIommuIvrs.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIommuIvrs/GnbIommuIvrs.c new file mode 100755 index 0000000000..0452de0308 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIommuIvrs/GnbIommuIvrs.c @@ -0,0 +1,242 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39433 $ @e \$Date: 2010-10-11 14:15:36 -0700 (Mon, 11 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 "cpuLateInit.h" +#include "Gnb.h" +#include "GnbFamServices.h" +#include "GnbCommonLib.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBIOMMUIVRS_GNBIOMMUIVRS_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 ROMDATA GnbBuildOptions; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +#define IVRS_TABLE_LENGTH 8 * 1024 + +/*---------------------------------------------------------------------------------------- + * 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 +GnbIommuIvrsTableDump ( + IN VOID *Ivrs, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +IOMMU_IVRS_HEADER IvrsHeader = { + {'I', 'V', 'R', 'S'}, + sizeof (IOMMU_IVRS_HEADER), + 2, + 0, + {'A', 'M', 'D', ' ', ' ', 0}, + {'A', 'M', 'D', 'I', 'O', 'M', 'M', 'U'}, + 1, + {'A','M','D',' '}, + 0, + 0, + 0 +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Build IVRS table + * + * + * + * @param[in] StdHeader Standard Configuration Header + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +GnbIommuIvrsTable ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AMD_LATE_PARAMS *LateParamsPtr; + VOID *Ivrs; + BOOLEAN IvrsSupport; + UINT32 SocketId; + UINT32 SiliconId; + UINT32 NumberOfSockets; + UINT32 NumberOfSilicons; + + Status = AGESA_SUCCESS; + LateParamsPtr = (AMD_LATE_PARAMS*) StdHeader; + IvrsSupport = FALSE; + Ivrs = LateParamsPtr->AcpiIvrs; + if (Ivrs == NULL) { + Ivrs = GnbAllocateHeapBuffer ( + AMD_ACPI_IVRS_BUFFER_HANDLE, + IVRS_TABLE_LENGTH, + StdHeader + ); + ASSERT (Ivrs != NULL); + if (Ivrs == NULL) { + return AGESA_ERROR; + } + LateParamsPtr->AcpiIvrs = Ivrs; + } + LibAmdMemFill (Ivrs, 0x0, IVRS_TABLE_LENGTH, StdHeader); + LibAmdMemCopy (Ivrs, &IvrsHeader, sizeof (IvrsHeader), StdHeader); + NumberOfSockets = GnbGetNumberOfSockets (StdHeader); + for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) { + if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) { + NumberOfSilicons = GnbGetNumberOfSiliconsOnSocket (SocketId, StdHeader); + for (SiliconId = 0; SiliconId < NumberOfSilicons; SiliconId++) { + if (GnbFmCheckIommuPresent (SocketId, SiliconId, StdHeader)) { + IDS_HDT_CONSOLE (GNB_TRACE, "Build IVRS for Socket %d Silicon %d\n", SocketId, SiliconId); + IvrsSupport = TRUE; + GnbFmCreateIvrsEntry (SocketId, SiliconId, IvrsIvhdBlock, Ivrs, StdHeader); + if (GnbBuildOptions.IvrsRelativeAddrNamesSupport) { + GnbFmCreateIvrsEntry (SocketId, SiliconId, IvrsIvhdrBlock, Ivrs, StdHeader); + } + } + } + } + } + if (IvrsSupport == TRUE) { + ChecksumAcpiTable ((ACPI_TABLE_HEADER*) Ivrs, StdHeader); + GNB_DEBUG_CODE (GnbIommuIvrsTableDump (Ivrs, StdHeader)); + } else { + IDS_HDT_CONSOLE (GNB_TRACE, " IVRS table not generated\n"); + LateParamsPtr->AcpiIvrs = NULL; + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump IVRS table + * + * + * @param[in] Ivrs Pointer to IVRS table + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +GnbIommuIvrsTableDump ( + IN VOID *Ivrs, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *Block; + UINT8 *Entry; + Block = (UINT8 *) Ivrs + sizeof (IOMMU_IVRS_HEADER); + IDS_HDT_CONSOLE (GNB_TRACE, "<---------- IVRS Table Start -----------> \n"); + IDS_HDT_CONSOLE (GNB_TRACE, " IVInfo = 0x%08x\n", ((IOMMU_IVRS_HEADER *) Ivrs)-> IvInfo); + while (Block < ((UINT8 *) Ivrs + ((IOMMU_IVRS_HEADER *) Ivrs)->TableLength)) { + if (*Block == IvrsIvhdBlock) { + IDS_HDT_CONSOLE (GNB_TRACE, " <-------------IVHD Block Start -------->\n"); + IDS_HDT_CONSOLE (GNB_TRACE, " Flags = 0x%02x\n", ((IVRS_IVHD_ENTRY *) Block)->Flags); + IDS_HDT_CONSOLE (GNB_TRACE, " DeviceId = 0x%04x\n", ((IVRS_IVHD_ENTRY *) Block)->DeviceId); + IDS_HDT_CONSOLE (GNB_TRACE, " CapabilityOffset = 0x%02x\n", ((IVRS_IVHD_ENTRY *) Block)->CapabilityOffset); + IDS_HDT_CONSOLE (GNB_TRACE, " BaseAddress = 0x%08x%08x\n", (UINT32) (((IVRS_IVHD_ENTRY *) Block)->BaseAddress >> 32), (UINT32) ((IVRS_IVHD_ENTRY *) Block)->BaseAddress); + IDS_HDT_CONSOLE (GNB_TRACE, " PCI Segment = 0x%04x\n", ((IVRS_IVHD_ENTRY *) Block)->PciSegment); + IDS_HDT_CONSOLE (GNB_TRACE, " IommuInfo = 0x%04x\n", ((IVRS_IVHD_ENTRY *) Block)->IommuInfo); + IDS_HDT_CONSOLE (GNB_TRACE, " IommuEfr = 0x%08x\n", ((IVRS_IVHD_ENTRY *) Block)->IommuEfr); + Entry = Block + sizeof (IVRS_IVHD_ENTRY); + IDS_HDT_CONSOLE (GNB_TRACE, " <-------------IVHD Block Device Entries Start -------->\n"); + while (Entry < (Block + ((IVRS_IVHD_ENTRY *) Block)->Length)) { + IDS_HDT_CONSOLE (GNB_TRACE, " "); + switch (*Entry) { + case IvhdEntrySelect: + case IvhdEntryEndRange: + GnbLibDebugDumpBuffer (Entry, 4, 1, 4); + Entry = Entry + 4; + break; + case IvhdEntryStartRange: + GnbLibDebugDumpBuffer (Entry, 8, 1, 8); + Entry = Entry + 8; + break; + case IvhdEntryAliasStartRange: + GnbLibDebugDumpBuffer (Entry, 12, 1, 12); + Entry = Entry + 12; + break; + case IvhdEntryAliasSelect: + case IvhdEntryExtendedSelect: + case IvhdEntrySpecialDevice: + GnbLibDebugDumpBuffer (Entry, 8, 1, 8); + Entry = Entry + 8; + break; + case IvhdEntryPadding: + Entry = Entry + 4; + break; + default: + IDS_HDT_CONSOLE (GNB_TRACE, " Unsupported entry type [%d]\n"); + ASSERT (FALSE); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, " <-------------IVHD Block Device Entries End -------->\n"); + IDS_HDT_CONSOLE (GNB_TRACE, " <-------------IVHD Block End ---------->\n"); + Block = Block + ((IVRS_IVHD_ENTRY *) Block)->Length; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "<---------- IVRS Table Raw Data --------> \n"); + GnbLibDebugDumpBuffer (Ivrs, ((IOMMU_IVRS_HEADER *) Ivrs)->TableLength, 1, 16); + IDS_HDT_CONSOLE (GNB_TRACE, "\n"); + IDS_HDT_CONSOLE (GNB_TRACE, "<---------- IVRS Table End -------------> \n"); +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIommuIvrs/GnbIommuIvrs.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIommuIvrs/GnbIommuIvrs.h new file mode 100755 index 0000000000..d01cf53476 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIommuIvrs/GnbIommuIvrs.h @@ -0,0 +1,54 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39433 $ @e \$Date: 2010-10-11 14:15:36 -0700 (Mon, 11 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBIOMMUIVRS_H_ +#define _GNBIOMMUIVRS_H_ + +AGESA_STATUS +GnbIommuIvrsTable ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIvrsLib/GnbIvrsLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIvrsLib/GnbIvrsLib.c new file mode 100755 index 0000000000..e366e31e39 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIvrsLib/GnbIvrsLib.c @@ -0,0 +1,181 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39433 $ @e \$Date: 2010-10-11 14:15:36 -0700 (Mon, 11 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 "cpuLateInit.h" +#include "Gnb.h" +#include "GnbFamServices.h" +#include "GnbCommonLib.h" +#include "GnbIommuIvrs.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBIVRSLIB_GNBIVRSLIB_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Create IVHDR entry for device range + * + * + * @param[in] StartRange Address of start range + * @param[in] EndRange Address of end range + * @param[in] DataSetting Data setting + * @param[in] Ivhd Pointer to IVHD entry + * @param[in] StdHeader Standard configuration header + * + */ +VOID +GnbIvhdAddDeviceRangeEntry ( + IN PCI_ADDR StartRange, + IN PCI_ADDR EndRange, + IN UINT8 DataSetting, + IN IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IVHD_GENERIC_ENTRY *Entry; + Entry = (IVHD_GENERIC_ENTRY *) ((UINT8 *) Ivhd + Ivhd->Length); + Entry->Type = IvhdEntryStartRange; + Entry->DeviceId = DEVICE_ID (StartRange); + Entry->DataSetting = DataSetting; + Ivhd->Length += sizeof (IVHD_GENERIC_ENTRY); + Entry = (IVHD_GENERIC_ENTRY *) ((UINT8 *) Ivhd + Ivhd->Length); + Entry->Type = IvhdEntryEndRange; + Entry->DeviceId = DEVICE_ID (EndRange); + Ivhd->Length += sizeof (IVHD_GENERIC_ENTRY); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create IVHDR entry for aliased range + * + * + * @param[in] StartRange Address of start range + * @param[in] EndRange Address of end range + * @param[in] Alias Address of alias requestor ID for range + * @param[in] DataSetting Data setting + * @param[in] Ivhd Pointer to IVHD entry + * @param[in] StdHeader Standard configuration header + * + */ +VOID +GnbIvhdAddDeviceAliasRangeEntry ( + IN PCI_ADDR StartRange, + IN PCI_ADDR EndRange, + IN PCI_ADDR Alias, + IN UINT8 DataSetting, + IN IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IVHD_ALIAS_ENTRY *RangeEntry; + IVHD_GENERIC_ENTRY *Entry; + UINT8 Padding; + Padding = (UINT8) ((Ivhd->Length + 0x7) & (~ 0x7)); + RangeEntry = (IVHD_ALIAS_ENTRY *) ((UINT8 *) Ivhd + Padding); + RangeEntry->Type = IvhdEntryAliasStartRange; + RangeEntry->DeviceId = DEVICE_ID (StartRange); + RangeEntry->AliasDeviceId = DEVICE_ID (Alias); + RangeEntry->DataSetting = DataSetting; + Ivhd->Length += sizeof (IVHD_ALIAS_ENTRY); + Entry = (IVHD_GENERIC_ENTRY *) ((UINT8 *) Ivhd + Ivhd->Length); + Entry->Type = IvhdEntryEndRange; + Entry->DeviceId = DEVICE_ID (EndRange); + Ivhd->Length += (sizeof (IVHD_GENERIC_ENTRY) + Padding); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create IVHDR entry for special device + * + * + * @param[in] SpecialDevice Special device Type + * @param[in] Device Address of requestor ID for special device + * @param[in] Id Apic ID/ Hpet ID + * @param[in] DataSetting Data setting + * @param[in] Ivhd Pointer to IVHD entry + * @param[in] StdHeader Standard configuration header + * + */ +VOID +GnbIvhdAddSpecialDeviceEntry ( + IN IVHD_SPECIAL_DEVICE SpecialDevice, + IN PCI_ADDR Device, + IN UINT8 Id, + IN UINT8 DataSetting, + IN IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IVHD_SPECIAL_ENTRY *SpecialEntry; + UINT8 Padding; + Padding = (UINT8) ((Ivhd->Length + 0x7) & (~ 0x7)); + SpecialEntry = (IVHD_SPECIAL_ENTRY *) ((UINT8 *) Ivhd + Padding); + SpecialEntry->Type = IvhdEntrySpecialDevice; + SpecialEntry->AliasDeviceId = DEVICE_ID (Device); + SpecialEntry->Variety = (UINT8) SpecialDevice; + Ivhd->Length += (sizeof (IVHD_SPECIAL_ENTRY) + Padding); +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIvrsLib/GnbIvrsLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIvrsLib/GnbIvrsLib.h new file mode 100755 index 0000000000..d227baad66 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbIvrsLib/GnbIvrsLib.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39433 $ @e \$Date: 2010-10-11 14:15:36 -0700 (Mon, 11 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBIVRSLIB_H_ +#define _GNBIVRSLIB_H_ + + +VOID +GnbIvhdAddDeviceRangeEntry ( + IN PCI_ADDR StartRange, + IN PCI_ADDR EndRange, + IN UINT8 DataSetting, + IN IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbIvhdAddDeviceAliasRangeEntry ( + IN PCI_ADDR StartRange, + IN PCI_ADDR EndRange, + IN PCI_ADDR Alias, + IN UINT8 DataSetting, + IN IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbIvhdAddSpecialDeviceEntry ( + IN IVHD_SPECIAL_DEVICE SpecialDevice, + IN PCI_ADDR Device, + IN UINT8 Id, + IN UINT8 DataSetting, + IN IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.c new file mode 100755 index 0000000000..e668f1bb03 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.c @@ -0,0 +1,400 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49911 $ @e \$Date: 2011-03-30 17:43:29 +0800 (Wed, 30 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "GnbFuseTable.h" +#include "GnbCommonLib.h" +#include "GnbNbInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBNBINITLIBV1_GNBNBINITLIBV1_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Init NB set top of memory + * + * + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +AGESA_STATUS +GnbSetTom ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + UINT64 MsrData; + UINT32 Value; + Status = AGESA_SUCCESS; + //Read memory size below 4G from MSR C001_001A + LibAmdMsrRead (TOP_MEM, &MsrData, StdHeader); + //Write to NB register 0x90 + Value = (UINT32)MsrData & 0xFF800000; //Keep bits 31:23 + GnbLibPciRMW ( + NbPciAddress.AddressValue | D0F0x90_ADDRESS, + AccessS3SaveWidth32, + 0x007FFFFF, + Value, + StdHeader + ); + if (Value == 0) { + Status = AGESA_WARNING; + } + + LibAmdMsrRead (SYS_CFG, &MsrData, StdHeader); + if ((MsrData & BIT21) != 0) { + //Read memory size above 4G from MSR C001_001D + LibAmdMsrRead (TOP_MEM2, &MsrData, StdHeader); + // Write memory size[39:32] to indirect register 1A[7:0] + Value = (UINT32) ((MsrData >> 32) & 0xFF); + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x1A_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0xFFFFFF00, + Value, + StdHeader + ); + + // Write memory size[31:23] to indirect register 19[31:23] and enable memory through bit 0 + Value = (UINT32)MsrData & 0xFF800000; //Keep bits 31:23 + Value |= BIT0; // Enable top of memory + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x19_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0x007FFFFF, + Value, + StdHeader + ); + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Avoid LPC DMA transaction deadlock + * + * + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +GnbLpcDmaDeadlockPrevention ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // For GPP Link core, enable special NP memory write protocol on the processor side PCIE controller + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0xE0_ADDRESS, + CORE_SPACE (1, D0F0xE4_CORE_0010_ADDRESS), + AccessWidth32, + 0xFFFFFFFF, + 1 << D0F0xE4_CORE_0010_UmiNpMemWrite_OFFSET, + StdHeader + ); + + //Enable special NP memory write protocol in ORB + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x06_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), + AccessS3SaveWidth32, + 0xFFFFFFFF, + 1 << D0F0x98_x06_UmiNpMemWrEn_OFFSET, + StdHeader + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Dynamic Wake + * ORB_CNB_Wake signal is used to inform the CNB NCLK controller and GNB LCLK controller + * that ORB is (or will soon) push data into the synchronizer FIFO (i.e. wake is high). + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +GnbOrbDynamicWake ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + D0F0x98_x2C_STRUCT D0F0x98_x2C; + + GnbLibPciIndirectRead ( + NbPciAddress.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x2C_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), + AccessWidth32, + &D0F0x98_x2C.Value, + StdHeader + ); + + // Enable Dynamic wake + // Wake Hysteresis timer value. Specifies the number of SMU pulses to count. + D0F0x98_x2C.Field.DynWakeEn = 1; + D0F0x98_x2C.Field.WakeHysteresis = 0x64; + + IDS_OPTION_HOOK (IDS_GNB_ORBDYNAMIC_WAKE, &D0F0x98_x2C, StdHeader); + + GnbLibPciIndirectWrite ( + NbPciAddress.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x2C_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), + AccessS3SaveWidth32, + &D0F0x98_x2C.Value, + StdHeader + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Lock NB registers + * + * + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +GnbLock ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GnbLibPciIndirectWriteField ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x00_ADDRESS | IOC_WRITE_ENABLE, + D0F0x64_x00_HwInitWrLock_OFFSET, + D0F0x64_x00_HwInitWrLock_WIDTH, + 0x1, + TRUE, + StdHeader + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * UnitID Clumping + * + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +GnbClumpUnitID ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Value; + GnbLibPciRead (MAKE_SBDFO (0, NbPciAddress.Address.Bus, 2, 0, 0), AccessWidth32, &Value, StdHeader); + if (Value != 0xFFFFFFFF) { + GnbLibPciRead (MAKE_SBDFO (0, NbPciAddress.Address.Bus, 3, 0, 0), AccessWidth32, &Value, StdHeader); + if (Value == 0xFFFFFFFF) { + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x3A_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), + AccessS3SaveWidth32, + 0xFFFFFFFF, + 1 << D0F0x98_x3A_ClumpingEn_OFFSET, + StdHeader + ); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the index of highest SCLK VID + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID index + */ +UINT8 +GnbLocateHighestVidIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVid; + UINT8 MaxVidIndex; + UINTN Index; + PP_FUSE_ARRAY *PpFuseArray; + + PpFuseArray = (PP_FUSE_ARRAY *) GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); + ASSERT (PpFuseArray != NULL); + if (PpFuseArray == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return 0; + } + + MaxVidIndex = 0; + MaxVid = 0xff; + for (Index = 0; Index < 4; Index++) { + if (PpFuseArray->SclkVid[Index] != 0 && PpFuseArray->SclkVid[Index] < MaxVid) { + MaxVid = PpFuseArray->SclkVid[Index]; + MaxVidIndex = (UINT8) Index; + } + } + ASSERT (PpFuseArray->SclkVid[MaxVidIndex] != 0); + return MaxVidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the index of lowest SCLK VID + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID index + */ +UINT8 +GnbLocateLowestVidIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MinVidIndex; + UINTN Index; + PP_FUSE_ARRAY *PpFuseArray; + + PpFuseArray = (PP_FUSE_ARRAY *) GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); + ASSERT (PpFuseArray != NULL); + if (PpFuseArray == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return 0; + } + + MinVidIndex = 0; + + for (Index = 0; Index < 4; Index++) { + if (PpFuseArray->SclkVid[Index] > PpFuseArray->SclkVid[MinVidIndex]) { + MinVidIndex = (UINT8) Index; + } + } + ASSERT (PpFuseArray->SclkVid[MinVidIndex] != 0); + return MinVidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the highest SCLK VID (high voltage) + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID + */ +UINT8 +GnbLocateHighestVidCode ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVidIndex; + PP_FUSE_ARRAY *PpFuseArray; + + PpFuseArray = (PP_FUSE_ARRAY *) GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); + ASSERT (PpFuseArray != NULL); + + MaxVidIndex = GnbLocateHighestVidIndex (StdHeader); + ASSERT (PpFuseArray->SclkVid[MaxVidIndex] != 0); + return PpFuseArray->SclkVid[MaxVidIndex]; + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the lowest SCLK VID (low voltage) + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID + */ +UINT8 +GnbLocateLowestVidCode ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MinVidIndex; + PP_FUSE_ARRAY *PpFuseArray; + + PpFuseArray = (PP_FUSE_ARRAY *) GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); + ASSERT (PpFuseArray != NULL); + MinVidIndex = GnbLocateLowestVidIndex (StdHeader); + ASSERT (PpFuseArray->SclkVid[MinVidIndex] != 0); + return PpFuseArray->SclkVid[MinVidIndex]; +} + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h new file mode 100755 index 0000000000..79c819aff2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h @@ -0,0 +1,99 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49911 $ @e \$Date: 2011-03-30 17:43:29 +0800 (Wed, 30 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ +#ifndef _GNBNBINITLIBV1_H_ +#define _GNBNBINITLIBV1_H_ + + +AGESA_STATUS +GnbSetTom ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLpcDmaDeadlockPrevention ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbOrbDynamicWake ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLock ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbClumpUnitID ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT8 +GnbLocateLowestVidIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidCode ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateLowestVidCode ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlib.c new file mode 100755 index 0000000000..8563d6e538 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlib.c @@ -0,0 +1,439 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49916 $ @e \$Date: 2011-03-30 19:03:54 +0800 (Wed, 30 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "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 "GnbRegistersLN.h" +#include "OptionGnb.h" +#include "PcieAlib.h" +#include "GnbFuseTable.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEALIBV1_PCIEALIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern UINT8 AlibSsdt[]; + +/*---------------------------------------------------------------------------------------- + * 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 +STATIC +PcieAlibSetPortMaxSpeedCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +STATIC +PcieAlibSetPortOverrideSpeedCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +STATIC +PcieAlibSetPortInfoCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieAlibBuildAcpiTable ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **AlibSsdtPtr + ); + +VOID +STATIC +PcieAlibSetSclkVid ( + IN OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Create ACPI ALIB SSDT table + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PcieAlibFeature ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_LATE_PARAMS *LateParamsPtr; + LateParamsPtr = (AMD_LATE_PARAMS*) StdHeader; + return PcieAlibBuildAcpiTable (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 +PcieAlibBuildAcpiTable ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **AlibSsdtPtr + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + UINT32 AmlObjName; + PCIe_PLATFORM_CONFIG *Pcie; + PP_FUSE_ARRAY *PpFuseArray; + VOID *AlibSsdtBuffer; + VOID *AmlObjPtr; + UINT8 BootUpVidIndex; + UINT8 Gen1VidIndex; + UINTN AlibSsdtlength; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTable Enter\n"); + AgesaStatus = AGESA_SUCCESS; + AlibSsdtlength = ((ACPI_TABLE_HEADER*) &AlibSsdt[0])->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; + } + // Copy template to buffer + LibAmdMemCopy (AlibSsdtBuffer, &AlibSsdt[0], AlibSsdtlength, StdHeader); + // Set PCI MMIO configuration +// AmlObjName = '10DA'; + AmlObjName = 0x31304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + UINT64 LocalMsrRegister; + LibAmdMsrRead (MSR_MMIO_Cfg_Base, &LocalMsrRegister, StdHeader); + if ((LocalMsrRegister & BIT0) != 0 && (LocalMsrRegister & 0xFFFFFFFF00000000ull) == 0) { + *(UINT32*)((UINT8*) AmlObjPtr + 5) = (UINT32)(LocalMsrRegister & 0xFFFFF00000ull); + } else { + AgesaStatus = AGESA_FATAL; + } + } else { + AgesaStatus = AGESA_FATAL; + } + // Set voltage configuration + PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); + ASSERT (PpFuseArray != NULL); + if (PpFuseArray != NULL) { +// AmlObjName = '30DA'; + AmlObjName = 0x33304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + *(UINT8*)((UINT8*) AmlObjPtr + 5) = PpFuseArray->PcieGen2Vid; + } else { + AgesaStatus = AGESA_FATAL; + } + } else { + AgesaStatus = AGESA_FATAL; + } + + Gen1VidIndex = GnbLocateLowestVidIndex (StdHeader); + BootUpVidIndex = GnbLocateHighestVidIndex (StdHeader); +// AmlObjName = '40DA'; + AmlObjName = 0x34304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + *(UINT8*)((UINT8*) AmlObjPtr + 5) = Gen1VidIndex; + } else { + AgesaStatus = AGESA_FATAL; + } +// AmlObjName = '50DA'; + AmlObjName = 0x35304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + *(UINT8*)((UINT8*) AmlObjPtr + 5) = BootUpVidIndex; + } else { + AgesaStatus = AGESA_FATAL; + } +// AmlObjName = '01DA'; + AmlObjName = 0x30314441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + PcieAlibSetSclkVid ((UINT8*) ((UINT8*)AmlObjPtr + 7), StdHeader); + } else { + Status = AGESA_ERROR; + } + // Set PCIe configuration + if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { +// AmlObjName = '20DA'; + AmlObjName = 0x32304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + *(UINT8*)((UINT8*) AmlObjPtr + 5) = Pcie->PsppPolicy; + } else { + AgesaStatus = AGESA_FATAL; + } +// AmlObjName = '60DA'; + AmlObjName = 0x36304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieAlibSetPortMaxSpeedCallback, + (UINT8*)((UINT8*) AmlObjPtr + 7), + Pcie + ); + } else { + AgesaStatus = AGESA_FATAL; + } +// AmlObjName = '60DA'; + AmlObjName = 0x36304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieAlibSetPortOverrideSpeedCallback, + (UINT8*)((UINT8*) AmlObjPtr + 7), + Pcie + ); + } else { + AgesaStatus = AGESA_FATAL; + } +// AmlObjName = '70DA'; + AmlObjName = 0x37304441; + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr != NULL) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieAlibSetPortInfoCallback, + (UINT8*)((UINT8*) AmlObjPtr + 4), + Pcie + ); + } else { + AgesaStatus = AGESA_FATAL; + } + } else { + ASSERT (FALSE); + AgesaStatus = AGESA_ERROR; + } + Status = PcieFmAlibBuildAcpiTable (AlibSsdtBuffer, StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + 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, "PcieAlibBuildAcpiTable Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init max port speed capability + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieAlibSetPortMaxSpeedCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 *PsppMaxPortSpeedPackage; + PsppMaxPortSpeedPackage = (UINT8*) Buffer; + if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + PsppMaxPortSpeedPackage[(Engine->Type.Port.Address.Address.Device - 2) * 2 + 1] = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_MAX, Engine); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init max port speed capability + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieAlibSetPortOverrideSpeedCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 *PsppOverridePortSpeedPackage; + PsppOverridePortSpeedPackage = (UINT8*) Buffer; + if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + PsppOverridePortSpeedPackage[(Engine->Type.Port.Address.Address.Device - 2) * 2 + 1] = Engine->Type.Port.PortData.MiscControls.LinkSafeMode; + } + if (Engine->Type.Port.PortData.LinkHotplug == HotplugBasic && !PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + PsppOverridePortSpeedPackage[(Engine->Type.Port.Address.Address.Device - 2) * 2 + 1] = PcieGen1; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init port info + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieAlibSetPortInfoCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + ALIB_PORT_INFO_PACKAGE *PortInfoPackage; + UINT8 PortIndex; + PortInfoPackage = (ALIB_PORT_INFO_PACKAGE*) Buffer; + PortIndex = (UINT8) Engine->Type.Port.Address.Address.Device - 2; + PortInfoPackage->PortInfo[PortIndex].StartPhyLane = (UINT8) Engine->EngineData.StartLane; + PortInfoPackage->PortInfo[PortIndex].EndPhyLane = (UINT8) Engine->EngineData.EndLane; + PortInfoPackage->PortInfo[PortIndex].StartCoreLane = (UINT8) Engine->Type.Port.StartCoreLane; + PortInfoPackage->PortInfo[PortIndex].EndCoreLane = (UINT8) Engine->Type.Port.EndCoreLane; + PortInfoPackage->PortInfo[PortIndex].PortId = Engine->Type.Port.PortId; + PortInfoPackage->PortInfo[PortIndex].WrapperId = 0x0130 + (UINT16)(PcieConfigGetParentWrapper (Engine)->WrapId); + PortInfoPackage->PortInfo[PortIndex].LinkHotplug = Engine->Type.Port.PortData.LinkHotplug; + PortInfoPackage->PortInfo[PortIndex].MaxSpeedCap = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_MAX, Engine); +} + +VOID +STATIC +PcieAlibSetSclkVid ( + IN OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *SclkVid; + PP_FUSE_ARRAY *PpFuseArray; + UINT8 Index; + + SclkVid = (UINT8*) Buffer; + PpFuseArray = (PP_FUSE_ARRAY *) GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); + ASSERT (PpFuseArray != NULL); + if (PpFuseArray == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return; + } + + for (Index = 0; Index < 4; Index++) { + SclkVid[Index * 2 + 1] = PpFuseArray->SclkVid[Index]; + } +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlib.h new file mode 100755 index 0000000000..3af347c8f1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlib.h @@ -0,0 +1,82 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEALIB_H_ +#define _PCIEALIB_H_ + +#pragma pack (push, 1) +///Port info asl buffer +typedef struct { + UINT8 BufferOp; ///< Opcode + UINT8 PkgLength; ///< Package length + UINT8 BufferSize; ///< Buffer size + UINT8 ByteList; ///< Byte lisy + UINT8 StartPhyLane; ///< Port Start PHY lane + UINT8 EndPhyLane; ///< Port End PHY lane + UINT8 StartCoreLane; ///< Port Start Core lane + UINT8 EndCoreLane; ///< Port End Core lane + UINT8 PortId; ///< Port ID + UINT16 WrapperId; ///< Wrapper ID + UINT8 LinkHotplug; ///< Link hotplug type + UINT8 MaxSpeedCap; ///< Max port speed capability + UINT8 Reserved[1]; ///< Reserved +} ALIB_PORT_INFO_BUFFER; +///Ports info asl package +typedef struct { + UINT8 PackageOp; ///< Opcode + UINT8 PkgLength; ///< Package length + UINT8 NumElements; ///< number of elements + UINT8 PackageElementList; ///< package element list + ALIB_PORT_INFO_BUFFER PortInfo[7]; ///< Array of port info buffers +} ALIB_PORT_INFO_PACKAGE; + +#pragma pack (pop) + +AGESA_STATUS +PcieAlibFeature ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibConfig.esl b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibConfig.esl new file mode 100755 index 0000000000..8aa9a7e67f --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibConfig.esl @@ -0,0 +1,107 @@ +/** + * @file + * + * ALIB PSPP config + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49214 $ @e \$Date: 2011-03-19 07:05:12 +0800 (Sat, 19 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEALIBCONFIG_H_ +#define _PCIEALIBCONFIG_H_ + +//#define PCIE_PHY_LANE_POWER_GATE_SUPPORT +// #define PCIE_DISABLE_UNUSED_LANES_ON_ACTIVE_LINK + +#define DEF_OFFSET_START_CORE_LANE 2 +#define DEF_OFFSET_END_CORE_LANE 3 +#define DEF_OFFSET_START_PHY_LANE 0 +#define DEF_OFFSET_END_PHY_LANE 1 +#define DEF_OFFSET_PORT_ID 4 +#define DEF_OFFSET_WRAPPER_ID 5 +#define DEF_OFFSET_LINK_HOTPLUG 7 +#define DEF_OFFSET_GEN2_CAP 8 +#define DEF_BASIC_HOTPLUG 1 + +#define DEF_PSPP_POLICY_START 1 +#define DEF_PSPP_POLICY_STOP 0 +#define DEF_PSPP_POLICY_PERFORMANCE 1 +#define DEF_PSPP_POLICY_BALANCEHIGH 2 +#define DEF_PSPP_POLICY_BALANCELOW 3 +#define DEF_PSPP_POLICY_POWERSAVING 4 +#define DEF_PSPP_STATE_AC 0 +#define DEF_PSPP_STATE_DC 1 + +#define DEF_TRAINING_STATE_COMPLETE 0 +#define DEF_TRAINING_STATE_DETECT_PRESENCE 1 +#define DEF_TRAINING_STATE_PRESENCE_DETECTED 2 +#define DEF_TRAINING_GEN2_WORKAROUND 3 +#define DEF_TRAINING_STATE_NOT_PRESENT 4 +#define DEF_TRAINING_DEVICE_PRESENT 5 +#define DEF_TRAINING_STATE_RELEASE_TRAINING 6 +#define DEF_TRAINING_STATE_REQUEST_RESET 7 +#define DEF_TRAINING_STATE_EXIT 8 + +#define DEF_LINK_SPEED_GEN1 1 +#define DEF_LINK_SPEED_GEN2 2 + +#define DEF_HOTPLUG_STATUS_DEVICE_NOT_PRESENT 0 +#define DEF_HOTPLUG_STATUS_DEVICE_PRESENT 1 + +#define DEF_PORT_NOT_ALLOCATED 0 +#define DEF_PORT_ALLOCATED 1 + +#define DEF_PCIE_LANE_POWERON 1 +#define DEF_PCIE_LANE_POWEROFF 0 +#define DEF_PCIE_LANE_POWEROFFUNUSED 2 + +#define DEF_SCARTCH_PSPP_START_OFFSET 0 +#define DEF_SCARTCH_PSPP_POLICY_OFFSET 1 +#define DEF_SCARTCH_PSPP_ACDC_OFFSET 5 +#define DEF_SCARTCH_PSPP_ACDC_OVR_OFFSET 6 +#define DEF_SCARTCH_PSPP_REQ_OFFSET 16 + +#define DEF_LINKWIDTH_ACTIVE 0 +#define DEF_LINKWIDTH_MAX_PHY 1 + + + +#define TRUE 1 +#define FALSE 0 + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibCore.esl b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibCore.esl new file mode 100755 index 0000000000..d4cc767393 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibCore.esl @@ -0,0 +1,359 @@ +/** + * @file + * + * ALIB ASL library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + + + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe MMIO Base address + * + */ + + Name ( + AD01, + 0xE0000000 + ) + + Alias ( + AD01, + varPcieBase + ) + + + + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe port info + * + */ + + Name ( + AD07, + Package () { + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev2 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev3 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev4 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev5 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev6 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev7 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev8 + Buffer () {0,0,0,0,0,0,0,0,0,0}, //dev9 + } + ) + + Alias ( + AD07, + varPortInfo + ) + + + Name (varStringBuffer, Buffer (256) {}) + + /*----------------------------------------------------------------------------------------*/ + /** + * Master control method + * + * Arg0 - Function ID + * Arg1 - Function specific data buffer + */ + Method (ALIB, 2, NotSerialized) { + If (Lequal (Arg0, 0x1)) { + return (procPsppReportAcDsState (Arg1)) + } + If (LEqual (Arg0, 0x2)) { + return (procPsppPerformanceRequest (Arg1)) + } + If (LEqual (Arg0, 0x3)) { + return (procPsppControl (Arg1)) + } + If (LEqual (Arg0, 0x4)) { + return (procPcieSetBusWidth (Arg1)) + } + If (LEqual (Arg0, 0x5)) { + return (procAlibInit ()) + } + If (LEqual (Arg0, 0x6)) { + return (procPciePortHotplug (Arg1)) + } + return (0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Alib Init + * + * + */ + Method (procAlibInit, 0, Serialized) { + + return (0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCI config register through MMIO + * + * Arg0 - PCI address Bus/device/func + * Arg1 - Register offset + */ + Method (procPciDwordRead, 2, Serialized) { + Add (varPcieBase, ShiftLeft (Arg0, 12), Local0) + Add (Arg1, Local0, Local0) + OperationRegion(varOperationRegionMmio, SystemMemory, Local0, 0x4) + Field(varOperationRegionMmio, DWordAcc, NoLock, Preserve) { + Offset (0x0), + varPciReg32, 32, + } + return (varPciReg32) + } + /*----------------------------------------------------------------------------------------*/ + /** + * Write PCI config register through MMIO + * + * Arg0 - PCI address Bus/device/func + * Arg1 - Register offset + * Arg2 - Value + */ + Method (procPciDwordWrite, 3, Serialized) { + Add (varPcieBase, ShiftLeft (Arg0, 12), Local0) + Add (Arg1, Local0, Local0) + OperationRegion(varOperationRegionMmio, SystemMemory, Local0, 0x4) + Field(varOperationRegionMmio, DWordAcc, NoLock, Preserve) { + Offset (0x0), + varPciReg32, 32, + } + Store (Arg2, varPciReg32) + } + /*----------------------------------------------------------------------------------------*/ + /** + * Write PCI config register through MMIO + * + * Arg0 - PCI address Bus/device/func + * Arg1 - Register offset + * Arg2 - AND mask + * Arg3 - OR mask + */ + Method (procPciDwordRMW, 4, Serialized) { + Store (procPciDwordRead (Arg0, Arg1), Local0) + Or (And (Local0, Arg2), Arg3, Local0) + procPciDwordWrite (Arg0, Arg1, Local0) + } + + Mutex(varPciePortAccessMutex, 0) + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCIe port indirect register + * + * Arg0 - Port Index + * Arg1 - Register offset + * + */ + Method (procPciePortIndirectRegisterRead, 2, NotSerialized) { + Acquire(varPciePortAccessMutex, 0xFFFF) + Store (ShiftLeft (Add( Arg0, 2), 3), Local0) + procPciDwordWrite (Local0, 0xe0, Arg1) + Store (procPciDwordRead (Local0, 0xe4), Local0) + Release (varPciePortAccessMutex) + return (Local0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Write PCIe port indirect register + * + * Arg0 - Port Index + * Arg1 - Register offset + * Arg2 - Value + */ + Method (procPciePortIndirectRegisterWrite, 3, NotSerialized) { + Acquire(varPciePortAccessMutex, 0xFFFF) + Store (ShiftLeft (Add( Arg0, 2), 3), Local0) + procPciDwordWrite (Local0, 0xe0, Arg1) + procPciDwordWrite (Local0, 0xe4, Arg2) + Release (varPciePortAccessMutex) + } + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCIe port indirect register + * + * Arg0 - Port Index + * Arg1 - Register offset + * Arg2 - AND Mask + * Arg3 - OR Mask + * + */ + Method (procPciePortIndirectRegisterRMW, 4, NotSerialized) { + Store (procPciePortIndirectRegisterRead (Arg0, Arg1), Local0) + Or (And (Local0, Arg2), Arg3, Local0) + procPciePortIndirectRegisterWrite (Arg0, Arg1, Local0) + } + Mutex(varHostAccessMutex, 0) + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCIe port indirect register + * + * Arg0 - BDF + * Arg1 - Register offset + * Arg2 - Register address + * + */ + Method (procIndirectRegisterRead, 3, NotSerialized) { + Acquire(varHostAccessMutex, 0xFFFF) + procPciDwordWrite (Arg0, Arg1, Arg2) + Store (procPciDwordRead (Arg0, Add (Arg1, 4)), Local0) + Release(varHostAccessMutex) + return (Local0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Write PCIe port indirect register + * + * Arg0 - BDF + * Arg1 - Register offset + * Arg2 - Register address + * Arg3 - Value + */ + Method (procIndirectRegisterWrite, 4, NotSerialized) { + Acquire(varHostAccessMutex, 0xFFFF) + procPciDwordWrite (Arg0, Arg1, Arg2) + procPciDwordWrite (Arg0, Add (Arg1, 4), Arg3) + Release(varHostAccessMutex) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Read Modify Write indirect registers + * + * Arg0 - BDF + * Arg1 - Register Offset + * Arg2 - Register Address + * Arg3 - AND Mask + * Arg4 - OR Mask + * + */ + Method (procIndirectRegisterRMW, 5, NotSerialized) { + Store (procIndirectRegisterRead (Arg0, Arg1, Arg2), Local0) + Or (And (Local0, Arg3), Arg4, Local0) + procIndirectRegisterWrite (Arg0, Arg1, Arg2, Local0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * + * + * Arg0 - Port ID + * Retval - buffer that represent port data set + */ + Method (procPcieGetPortInfo, 1, NotSerialized) { + return (DeRefOf (Index (varPortInfo, Arg0))) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Find Pci Capability + * + * Arg0 - PCI address Bus/device/func + * Arg1 - Capability id + */ + Method (procFindPciCapability, 2, NotSerialized) { + Store (0x34, Local1) + if (LEqual (procPciDwordRead (Arg0, 0x0), 0xFFFFFFFF)) { + // Device not present + return (0) + } + Store (1, Local0) + while (LEqual (Local0, 1)) { + Store (And (procPciDwordRead (Arg0, Local1), 0xFF), Local1) + if (LEqual (Local1, 0)) { + break + } + if (LEqual (And (procPciDwordRead (Arg0, Local1), 0xFF), Arg1)) { + Store (0, Local0) + } else { + Increment (Local1) + } + } + return (Local1) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * + * + * Arg0 - Aspm + * Arg1 - 0: Read, 1: Write + */ + Method (procPcieSbAspmControl, 2, Serialized) { + // Create an opregion for PM IO Registers + OperationRegion (PMIO, SystemIO, 0xCD6, 0x2) + Field (PMIO, ByteAcc, NoLock, Preserve) + { + PMRI, 8, + PMRD, 8 + } + IndexField (PMRI, PMRD, ByteAcc, NoLock, Preserve) + { + Offset(0xE0), // IO Base address of A-Link Express/ A-Link Bridge register + ABAR, 32, + } + OperationRegion (ACFG, SystemIO, ABAR, 0x8) + Field (ACFG, DWordAcc, Nolock, Preserve) //AB_INDX/AB_DATA + { + ABIX, 32, + ABDA, 32 + } + + Store (0, Local0) + if (LEqual (Arg1, 0)) { + Store (0x80000068, ABIX) + Store (ABDA, Local0) + return (Local0) + } else { + Store (0x80000068, ABIX) + Store (ABDA, Local0) + Or (And (Local0, 0xfffffffc), Arg0, Local0) + Store (Local0, ABDA) + } + } + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl new file mode 100755 index 0000000000..bbe7c18f78 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl @@ -0,0 +1,532 @@ +/** + * @file + * + * ALIB ASL library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49874 $ @e \$Date: 2011-03-30 11:18:34 +0800 (Wed, 30 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + + External(\_SB.ALIC, MethodObj) + + Name (varStartPhyLane, 0) + Name (varEndPhyLane, 0) + Name (varStartCoreLane, 0) + Name (varEndCoreLane, 0) + Name (varWrapperId, 0) + Name (varPortId, 0) + + Name (varNormalizeLinkWidthBuffer, Buffer () {1, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16}) + /*----------------------------------------------------------------------------------------*/ + /** + * Set PCIe Bus Width + * + * Arg0 - Data Buffer + */ + Method (procPcieSetBusWidth, 1, NotSerialized) { + Store ("procPcieSetBusWidth Enter", Debug) + + Name (varClientBus, 0) + Name (varArgBusWidth, 0) + Store (0, varPortIndex) + Store (Buffer (10) {}, Local7) + + //ClientId: WORD + //Bits 2-0: Function number. + //Bits 7-3: Device number. + //Bits 15-8: Bus number. + Store (DerefOf (Index (Arg0, 0x3)), varClientBus) + Store (DerefOf (Index (Arg0, 0x4)), varArgBusWidth) + Store (Concatenate (" Client Bus : ", ToHexString (varClientBus), varStringBuffer), Debug) + Store (Concatenate (" Arg Bus Width : ", ToHexString (varArgBusWidth), varStringBuffer), Debug) + + Store (3, Index (Local7, 0x0)) // Return Buffer Length + Store (0, Index (Local7, 0x1)) // Return Buffer Length + Store (varArgBusWidth, Index (Local7, 0x2)) // Return BusWidth + + + //deternime correct lane bitmap (check for reversal) gate/ungate unused lanes + + // determine port index base on "Client ID" + while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) { + if (LEqual (procChecPortAllocated (varPortIndex), DEF_PORT_ALLOCATED)) { + Store (procPciDwordRead (ShiftLeft (Add( varPortIndex, 2), 3), 0x18), Local1) + And (ShiftRight (Local1, 16), 0xff, varSubordinateBusLocal2) //Local2 Port Subordinate Bus number + And (ShiftRight (Local1, 8), 0xff, varSecondaryBusLocal1) //Local1 Port Secondary Bus number + if (LAnd (LGreaterEqual (varClientBus, Local1), LLessEqual(varClientBus, Local2))) { + break + } + } + Increment (varPortIndex) + } + if (LGreater (varPortIndex, varMaxPortIndexNumber)) { + Store ("procPcieSetBusWidth Exit -- over max port index", Debug) + return (Local7) + } + + Store (Concatenate (" Pcie Set BusWidth for port index : ", ToHexString (varPortIndex), varStringBuffer), Debug) + + // Normalize link width (Num Lanes) to correct value x1, x2.x4,x8,x16, + // make sure that number of lanes requested to be powered on less or equal mx port link width + if (LLessEqual (procPcieGetLinkWidth (varPortIndex, DEF_LINKWIDTH_MAX_PHY), varArgBusWidth)) { + // Active link equal max link width, nothing needs to be done + Store ("procPcieSetBusWidth Exit -- over max lanes supported", Debug) + return (Local7) + } + Store (DeRefOf (Index (varNormalizeLinkWidthBuffer, varArgBusWidth)), Local1) + + + // call procPcieLaneControl to power on all lanes (Arg0 - port index , Arg1 - 1, Arg2 = 0) + procPcieLaneControl (varPortIndex, DEF_PCIE_LANE_POWERON, 0) + + // call procPcieLaneControl power off unused lanes (Arg0 - port index, Arg1 - 1, Arg2 = Link width) + procPcieLaneControl (varPortIndex, DEF_PCIE_LANE_POWEROFFUNUSED, Local1) + +#ifdef PHY_SPEED_REPORT_SUPPORT + procReportPhySpeedCap () +#endif + Store (Local1, Index (Local7, 0x2)) // Return BusWidth + + Store ("procPcieSetBusWidth Exit", Debug) + return (Local7) + } + + + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe port hotplug + * + * Arg0 - Data Buffer + * Retval - Return buffer + */ + Method (procPciePortHotplug, 1, Serialized) { + Store ("PciePortHotplug Enter", Debug) + Store (DerefOf (Index (Arg0, 4)), varHotplugStateLocal0) + Store (DerefOf (Index (Arg0, 2)), varPortIndexLocal1) + + Subtract (ShiftRight (varPortBdfLocal1, 3), 2, varPortIndexLocal1) + if (LEqual(varHotplugStateLocal0, 1)) { + // Enable port + Store (DEF_TRAINING_STATE_RELEASE_TRAINING, Local2) + } else { + // Disable port + Store (DEF_TRAINING_STATE_NOT_PRESENT, Local2) + } + + Store (procPciePortTraining (varPortIndexLocal1, Local2), varHotplugStateLocal0) + +#ifdef PHY_SPEED_REPORT_SUPPORT + procReportPhySpeedCap () +#endif + + Store (Buffer (10) {}, Local7) + CreateWordField (Local7, 0x0, varReturnBufferLength) + CreateByteField (Local7, 0x2, varReturnStatus) + CreateByteField (Local7, 0x3, varReturnDeviceStatus) + Store (0x4, varReturnBufferLength) + Store (0x0, varReturnStatus) + Store (varHotplugStateLocal0, varReturnDeviceStatus) + Store ("PciePortHotplug Exit", Debug) + return (Local7) + } + + Name (varSpeedRequest, Buffer (10) {0,0,0,0,0,0,0,0,0,0}) + + /*----------------------------------------------------------------------------------------*/ + /** + * Train PCIe port + * + * + * Arg0 - Port Index + * Arg1 - Initial state + */ + Method (procPciePortTraining, 2, Serialized) { + Store ("PciePortTraining Enter", Debug) + Store (DEF_HOTPLUG_STATUS_DEVICE_NOT_PRESENT, varResultLocal4) + Store (procPcieGetPortInfo (Arg0), Local7) + // Check if port supports basic hotplug + Store (DerefOf (Index (Local7, DEF_OFFSET_LINK_HOTPLUG)), varTempLocal1) + if (LNotEqual (varTempLocal1, DEF_BASIC_HOTPLUG)) { + Store (" No action.[Hotplug type]", Debug) + Store ("procPciePortTraining Exit", Debug) + return (varResultLocal4) + } + Store (Arg1, varStateLocal2) + while (LNotEqual (varStateLocal2, DEF_TRAINING_STATE_EXIT)) { + if (LEqual (varStateLocal2, DEF_TRAINING_STATE_RELEASE_TRAINING)) { + Store (" State: Release training", Debug) + // Remove link speed override + Store (0, Index (varOverrideLinkSpeed, Arg0)) + // Enable link width upconfigure + procPciePortIndirectRegisterRMW (Arg0, 0xA2, Not (0x2000), 0x0000) + // Request Max link speed for hotplug by going to AC state + Store (0, varPsppAcDcOverride) + procApplyPsppState () + // Power on/enable port lanes + procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWERON, 0) + // Release training + procPcieTrainingControl (Arg0, 0) + // Move to next state to check presence detection + Store (DEF_TRAINING_STATE_DETECT_PRESENCE, varStateLocal2) + // Initialize retry count + Store(0, varCountLocal3) + } + if (LEqual (varStateLocal2, DEF_TRAINING_STATE_DETECT_PRESENCE)) { + Store (" State: Detect presence", Debug) + And (procPciePortIndirectRegisterRead (Arg0, 0xa5), 0x3f, varTempLocal1) + if (LGreater (varTempLocal1, 0x4)) { + // device connection detected move to next state + Store (DEF_TRAINING_STATE_PRESENCE_DETECTED, varStateLocal2) + // reset retry counter + Store(0, varCountLocal3) + continue + } + if (LLess (varCountLocal3, 80)) { + Sleep (1) + Increment (varCountLocal3) + } else { + // detection time expired move to device not present state + Store (DEF_TRAINING_STATE_NOT_PRESENT, varStateLocal2) + } + } + if (LEqual (varStateLocal2, DEF_TRAINING_STATE_PRESENCE_DETECTED)) { + Store (" State: Device detected", Debug) + Store (procPciePortIndirectRegisterRead (Arg0, 0xa5), varTempLocal1) + And (varTempLocal1, 0x3f, varTempLocal1) + if (LEqual (varTempLocal1, 0x10)) { + Store (DEF_TRAINING_DEVICE_PRESENT, varStateLocal2) + continue + } + if (LLess (varCountLocal3, 80)) { + Sleep (1) + Increment (varCountLocal3) + continue + } + Store (DEF_TRAINING_STATE_NOT_PRESENT, varStateLocal2) + + if (LEqual (DeRefOf (Index (varOverrideLinkSpeed, Arg0)), DEF_LINK_SPEED_GEN1)) { + // GEN2 workaround already applied but device not trained successfully move device not present state + continue + } + + if (LEqual (procPcieCheckForGen2Workaround (Arg0), TRUE)) { + Store (" Request Gen2 workaround", Debug) + procPciePortIndirectRegisterRMW (Arg0, 0xA2, Not (0x2000), 0x2000) + Store (DEF_LINK_SPEED_GEN1, Index (varOverrideLinkSpeed, Arg0)) + procPcieSetLinkSpeed (Arg0, DEF_LINK_SPEED_GEN1) + Store (DEF_TRAINING_STATE_REQUEST_RESET, varStateLocal2) + } + } + if (LEqual (varStateLocal2, DEF_TRAINING_STATE_NOT_PRESENT)) { + Store (" State: Device not present", Debug) + procPcieTrainingControl (Arg0, 1) + procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWEROFF, 0) + // Exclude device from PSPP managment since it is not present + Store (DEF_LINK_SPEED_GEN1, Index (varOverrideLinkSpeed, Arg0)) + Store (DEF_TRAINING_STATE_COMPLETE, varStateLocal2) + } + if (LEqual (varStateLocal2, DEF_TRAINING_STATE_REQUEST_RESET)) { + Store (" State: Request Reset", Debug) + if (CondRefOf (\_SB.ALIC, Local6)) { + Store (" Call ALIC method", Debug) + //varTempLocal1 contain port BDF + Store(ShiftLeft (Add (Arg0, 2), 3), varTempLocal1) + \_SB.ALIC (varTempLocal1, 0) + Sleep (2) + \_SB.ALIC (varTempLocal1, 1) + Store (0, varCountLocal3) + Store (DEF_TRAINING_STATE_DETECT_PRESENCE, varStateLocal2) + continue + } + Store (DEF_TRAINING_STATE_NOT_PRESENT, varStateLocal2) + } + if (LEqual (varStateLocal2, DEF_TRAINING_DEVICE_PRESENT)) { + Store (" State: Device present", Debug) + Store (DEF_HOTPLUG_STATUS_DEVICE_PRESENT, varResultLocal4) + Store (DEF_TRAINING_STATE_COMPLETE, varStateLocal2) +#ifdef PCIE_DISABLE_UNUSED_LANES_ON_ACTIVE_LINK + procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWEROFFUNUSED, 0) +#endif + } + if (LEqual (varStateLocal2, DEF_TRAINING_STATE_COMPLETE)) { + + Store (1, varPsppAcDcOverride) + procApplyPsppState () + + Store (DEF_TRAINING_STATE_EXIT, varStateLocal2) + } + } + Store ("PciePortTraining Exit", Debug) + return (varResultLocal4) + } + + + /*----------------------------------------------------------------------------------------*/ + /** + * Lane control + * + * Arg0 - Port Index + * Arg1 - 0 - Power off all lanes / 1 - Power on all Lanes / 2 Power off unused lanes + * Arg2 - link width + */ + + Method (procPcieLaneControl, 3, Serialized) { + Store ("PcieLaneControl Enter", Debug) + Store (Concatenate (" Arg0 : ", ToHexString (Arg0), varStringBuffer), Debug) + Store (Concatenate (" Arg1 : ", ToHexString (Arg1), varStringBuffer), Debug) + Store (procPcieGetPortInfo (Arg0), Local7) +#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT + Store (DerefOf (Index (Local7, DEF_OFFSET_START_PHY_LANE)), varStartPhyLane) + Store (DerefOf (Index (Local7, DEF_OFFSET_END_PHY_LANE)), varEndPhyLane) +#endif + Store (DerefOf (Index (Local7, DEF_OFFSET_START_CORE_LANE)), varStartCoreLane) + Store (DerefOf (Index (Local7, DEF_OFFSET_END_CORE_LANE)), varEndCoreLane) + + if (LEqual (Arg1, DEF_PCIE_LANE_POWEROFF)) { + procPcieLaneEnableControl (Arg0, varStartCoreLane, varEndCoreLane, 1) +#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT + procPcieLanePowerControl (varStartPhyLane, varEndPhyLane, 1) +#endif + } + if (LEqual (Arg1, DEF_PCIE_LANE_POWERON)) { +#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT + procPcieLanePowerControl (varStartPhyLane, varEndPhyLane, 0) +#endif + procPcieLaneEnableControl (Arg0, varStartCoreLane, varEndCoreLane, 0) + } + if (LNotEqual (Arg1, DEF_PCIE_LANE_POWEROFFUNUSED)) { + return (0) + } + + // Local2 should have link width (active lanes) + // Local3 should have first non active lanes + // Local4 should have last non active lanes + + if (LEqual(Arg2, 0)) { + Store (procPcieGetLinkWidth (Arg0, DEF_LINKWIDTH_ACTIVE), varActiveLinkWidthLocal2) + } else { + Store ( Arg2 , varActiveLinkWidthLocal2) + } + // Let say Link width is x1 than local2 = 1, Local3 = 1 Local4 = 15 for non reversed case + // while for reversed case should be Local2 = 1 Local3 = 0 and Local4 = 14 + + if (LLessEqual (procPcieGetLinkWidth (Arg0, DEF_LINKWIDTH_MAX_PHY), varActiveLinkWidthLocal2)) { + // Active link equal max link width, nothing needs to be done + return (0) + } + + Store (procPcieIsPortReversed (Arg0), varIsReversedLocal1) + //There is unused lanes after device plugged + if (LEqual(varIsReversedLocal1, FALSE)) { + Store (" Port Not Reversed", Debug) + // Link not reversed + Add (varStartCoreLane, varActiveLinkWidthLocal2, Local3) + Store (varEndCoreLane, Local4) + } else { + // Link reversed + Store (" Port Reversed", Debug) + Subtract (varEndCoreLane, varActiveLinkWidthLocal2, Local4) + Store (varStartCoreLane, Local3) + } + procPcieLaneEnableControl (Arg0, Local3, Local4, 1) +#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT + if (LGreater (varStartPhyLane, varEndPhyLane)) { + Store (varEndPhyLane, Local3) + Store (varStartPhyLane, Local4) + } else { + Store (varEndPhyLane, Local4) + Store (varStartPhyLane, Local3) + } + if (LEqual(varIsReversedLocal1, FALSE)) { + // Not reversed + Add (Local3, varActiveLinkWidthLocal2, Local3) + } else { + // Link reversed + Subtract (Local4, varActiveLinkWidthLocal2, Local4) + } + procPcieLanePowerControl (Local3, Local4, 1) +#endif + return (0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Check if GEN2 workaround applicable + * + * Arg0 - Port Index + * Retval - TRUE / FALSE + */ + + Method (procPcieCheckForGen2Workaround, 1, NotSerialized) { + Store (Buffer (16) {}, Local1) + Store (0x0, Local0) + while (LLessEqual (Local0, 0x3)) { + Store (procPciePortIndirectRegisterRead (Arg0, Add (Local0, 0xA5)), Local2) + Store (Local2, Index (Local1, Multiply (Local0, 4))) + Store (ShiftRight (Local2, 8), Index (Local1, Add (Multiply (Local0, 4), 1))) + Store (ShiftRight (Local2, 16), Index (Local1, Add (Multiply (Local0, 4), 2))) + Store (ShiftRight (Local2, 24), Index (Local1, Add (Multiply (Local0, 4), 3))) + Increment (Local0) + } + Store (0, Local0) + while (LLess (Local0, 15)) { + if (LAnd (LEqual (DeRefOf (Index (Local1, Local0)), 0x2a), LEqual (DeRefOf (Index (Local1, Add (Local0, 1))), 0x9))) { + return (TRUE) + } + Increment (Local0) + } + return (FALSE) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Is port reversed + * + * Arg0 - Port Index + * Retval - 0 - Not reversed / !=0 - Reversed + */ + Method (procPcieIsPortReversed , 1, Serialized) { + Store (procPcieGetPortInfo (Arg0), Local7) + + Store (DerefOf (Index (Local7, DEF_OFFSET_START_PHY_LANE)), varStartPhyLane) + Store (DerefOf (Index (Local7, DEF_OFFSET_END_PHY_LANE)), varEndPhyLane) + Store (0, Local0) + if (LGreater (varStartPhyLane, varEndPhyLane)) { + Store (1, Local0) + } + And (procPciePortIndirectRegisterRead (Arg0, 0x50), 0x1, Local1) + return (And (Xor (Local0, Local1), 0x1)) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Training Control + * + * Arg0 - Port Index + * Arg1 - Hold Training (1) / Release Training (0) + */ + Method (procPcieTrainingControl , 2, NotSerialized) { + Store ("PcieTrainingControl Enter", Debug) + Store (procPcieGetPortInfo (Arg0), Local7) + Store (DerefOf (Index (Local7, DEF_OFFSET_PORT_ID)), varPortId) + Store ( + Or (ShiftLeft (DerefOf (Index (Local7, Add (DEF_OFFSET_WRAPPER_ID, 1))), 8), DerefOf (Index (Local7, DEF_OFFSET_WRAPPER_ID))), + varWrapperId + ) + procIndirectRegisterRMW (0x0, 0xE0, Or (ShiftLeft (varWrapperId, 16), Add (0x800, Multiply (0x100, varPortId))), Not (0x1), Arg1); + Store ("PcieTrainingControl Exit", Debug) + } + + +Name (varLinkWidthBuffer, Buffer () {0, 1, 2, 4, 8, 12, 16}) +/*----------------------------------------------------------------------------------------*/ + /** + * Get actual negotiated/PHY or core link width + * + * Arg0 - Port Index + * Arg1 - 0/1 Negotiated/Phy + * Retval - Link Width + */ + Method (procPcieGetLinkWidth, 2, NotSerialized) { + Store ("PcieGetLinkWidth Enter", Debug) + Store (Concatenate (" Arg0 : ", ToHexString (Arg0), varStringBuffer), Debug) + Store (Concatenate (" Arg1 : ", ToHexString (Arg1), varStringBuffer), Debug) + + if (LEqual (Arg1, DEF_LINKWIDTH_ACTIVE)){ + //Get negotiated length + And (ShiftRight (procPciePortIndirectRegisterRead (Arg0, 0xA2), 4), 0x7, Local0) + Store (DeRefOf (Index (varLinkWidthBuffer, Local0)), Local1) + Store (Concatenate (" Active Link Width :", ToHexString (Local1), varStringBuffer), Debug) + } else { + //Get phy length + Store (procPcieGetPortInfo (Arg0), Local7) + Store (DerefOf (Index (Local7, DEF_OFFSET_START_PHY_LANE)), varStartPhyLane) + Store (DerefOf (Index (Local7, DEF_OFFSET_END_PHY_LANE)), varEndPhyLane) + if (LGreater (varStartPhyLane, varEndPhyLane)) { + Subtract (varStartPhyLane, varEndPhyLane, Local1) + } else { + Subtract (varEndPhyLane, varStartPhyLane, Local1) + } + Increment (Local1) + Store (Concatenate (" PHY Link Width :", ToHexString (Local1), varStringBuffer), Debug) + } + Store ("PcieGetLinkWidth Exit", Debug) + return (Local1) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe lane mux lane enable control (hotplug support) + * + * Arg0 - Port Index + * Arg1 - Start Lane + * Arg2 - End Lane + * Arg3 - Enable(0) / Disable(1) + */ + Method (procPcieLaneEnableControl, 4, Serialized) { + Store ("PcieLaneEnableControl Enter", Debug) + Store (Concatenate (" Arg0 : ", ToHexString (Arg0), varStringBuffer), Debug) + Store (Concatenate (" Arg1 : ", ToHexString (Arg1), varStringBuffer), Debug) + Store (Concatenate (" Arg2 : ", ToHexString (Arg2), varStringBuffer), Debug) + Store (Concatenate (" Arg3 : ", ToHexString (Arg3), varStringBuffer), Debug) + Store (procPcieGetPortInfo (Arg0), Local7) + Store (Arg1, varStartCoreLane) + Store (Arg2, varEndCoreLane) + Store ( + Or (ShiftLeft (DerefOf (Index (Local7, Add (DEF_OFFSET_WRAPPER_ID, 1))), 8), DerefOf (Index (Local7, DEF_OFFSET_WRAPPER_ID))), + varWrapperId + ) + if (LGreater (varStartCoreLane, varEndCoreLane)) { + Subtract (varStartCoreLane, varEndCoreLane, Local1) + Store (varEndCoreLane, Local2) + } else { + Subtract (varEndCoreLane, varStartCoreLane, Local1) + Store (varStartCoreLane, Local2) + } + ShiftLeft (Subtract (ShiftLeft (1, Add (Local1, 1)), 1), Local2, varLaneBitmapOrMaskLocal3) + Store (Not (varLaneBitmapOrMaskLocal3), varLaneBitmapAndMaskLocal4) + Store (Concatenate (" Lane Bitmap : ", ToHexString (varLaneBitmapOrMaskLocal3), varStringBuffer), Debug) + if (Lequal (Arg3, 1)) { + Store (0, varLaneBitmapOrMaskLocal3) + } + procIndirectRegisterRMW (0x0, 0xE0, Or (ShiftLeft (varWrapperId, 16), 0x8023), varLaneBitmapAndMaskLocal4, varLaneBitmapOrMaskLocal3); + Stall (10) + Store ("PcieLaneEnableControl Exit", Debug) + } + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibPspp.esl b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibPspp.esl new file mode 100755 index 0000000000..5dcfccebe4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibPspp.esl @@ -0,0 +1,772 @@ +/** +* @file +* +* ALIB PSPP ASL library +* +* +* +* @xrefitem bom "File Content Label" "Release Content" +* @e project: AGESA +* @e sub-project: GNB +* @e \$Revision: 49911 $ @e \$Date: 2011-03-30 17:43:29 +0800 (Wed, 30 Mar 2011) $ +* +*/ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe Performance Policy + * + * varPsppPolicy - 0 Disabled + * 1 Performance + * 2 Balance Hight + * 3 Balance Low + * 4 Power Saving + */ + Name ( + AD02, + 0x0 + ) + + Alias ( + AD02, + varPsppPolicy + ) + + /*----------------------------------------------------------------------------------------*/ + /** + * GEN2 VID + * + */ + + Name ( + AD03, + 0x0 + ) + + Alias ( + AD03, + varGen2Vid + ) + + /*----------------------------------------------------------------------------------------*/ + /** + * GEN1 VID + * + */ + Name ( + AD04, + 0x0 + ) + + Alias ( + AD04, + varGen1Vid + ) + + /*----------------------------------------------------------------------------------------*/ + /** + * Boot VID + * + */ + + Name ( + AD05, + 0x0 + ) + + Alias ( + AD05, + varBootVid + ) + + /*----------------------------------------------------------------------------------------*/ + /** + * Max Port link speed + * + */ + Name (AD06, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + + Alias (AD06, varMaxLinkSpeed) + + + /*----------------------------------------------------------------------------------------*/ + /** + * Max link speed that was changed during runtime (hotplug for instance) + * + */ + + Name (AD08, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + + Alias (AD08, varOverrideLinkSpeed) + + /*----------------------------------------------------------------------------------------*/ + /** + * Policy service status + * + * varPsppPolicyService - 0 (Stopped) + * 1 (Started) + */ + + Name (varPsppPolicyService, 0x0 ) + + /*----------------------------------------------------------------------------------------*/ + /** + * AC DC state + * + * varPsppAcDcState - 0 (AC) + * 1 (DC) + */ + + Name (varPsppAcDcState, 0x0) + Name (varPsppAcDcOverride, 0x1) + + /*----------------------------------------------------------------------------------------*/ + /** + * Client ID array + * + */ + + Name (varPsppClientIdArray, + Package () {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000} + ) + + Name (varDefaultPsppClientIdArray, + Package () {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000} + ) + /*----------------------------------------------------------------------------------------*/ + /** + * LInk speed requested by device driver + * + */ + + Name (varRequestedLinkSpeed, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + + /*----------------------------------------------------------------------------------------*/ + /** + * Current link speed + * + */ + Name (AD09, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) + Alias (AD09, varCurrentLinkSpeed) + /*----------------------------------------------------------------------------------------*/ + /** + * Template link speed + * + */ + Name ( + varGen1LinkSpeedTemplate, + Package () { + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1, + DEF_LINK_SPEED_GEN1 + }) + + /*----------------------------------------------------------------------------------------*/ + /** + * Template link speed + * + */ + Name (varLowVoltageRequest, Package () {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }) + + /*----------------------------------------------------------------------------------------*/ + /** + * Global varuable + * + */ + Name (varPortIndex, 0) + + /*----------------------------------------------------------------------------------------*/ + /** + * Sclk VID that was changed during runtime + * + */ + + Name (AD10, Package () {0x00, 0x00, 0x00, 0x00}) + + Alias (AD10, varSclkVid) + + /*----------------------------------------------------------------------------------------*/ + /** + * Report AC/DC state + * + * Arg0 - Data Buffer + */ + Method (procPsppReportAcDsState, 1, Serialized) { + Store ("PsppReportAcDsState Enter", Debug) + + Store (DeRefOf (Index (Arg0, 0x2)), varArgAcDcStateLocal1) + Store (Concatenate (" AC/DC state: ", ToHexString (varArgAcDcStateLocal1), varStringBuffer), Debug) + + Store (procPsppGetAcDcState(), varCurrentAcDcStateLocal0) + Store (varArgAcDcStateLocal1, varPsppAcDcState) + + Or (ShiftLeft (1, DEF_SCARTCH_PSPP_ACDC_OFFSET), ShiftLeft (1, DEF_SCARTCH_PSPP_ACDC_OVR_OFFSET), Local2) + Or (ShiftLeft (varPsppAcDcState, DEF_SCARTCH_PSPP_ACDC_OFFSET), ShiftLeft (varPsppAcDcOverride, DEF_SCARTCH_PSPP_ACDC_OVR_OFFSET), Local3) + procIndirectRegisterRMW (0x0, 0x60, 0xF4, Not (Local2), And (Local2, Local3)) + + + if (LEqual (varArgAcDcStateLocal1, varCurrentAcDcStateLocal0)) { + Store (" No action. [AC/DC state not changed]", Debug) + Store ("PsppReportAcDsState Exit", Debug) + return (0) + } + + // Disable both APM (boost) and PDM flow on DC event enable it on AC. + procApmPdmActivate(varPsppAcDcState) + + // Set DPM state for Power Saving, due to this policy will not attend ApplyPsppState service. + if (LEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING)) { + procNbLclkDpmActivate(DEF_LINK_SPEED_GEN1) +#ifdef ALTVDDNB_SUPPORT + procNbAltVddNb (DEF_LINK_SPEED_GEN1) +#endif + } + if (LOr (LLessEqual (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LGreaterEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) { + Store (" No action. [Policy type]", Debug) + Store ("PsppReportAcDsState Exit", Debug) + return (0) + } + if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_STOP)) { + Store (" No action. [Policy not started]", Debug) + Store ("PsppReportAcDsState Exit", Debug) + return (0) + } + procApplyPsppState () + Store ("PsppReportAcDsState Exit", Debug) + return (0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe Performance Request + * + * Arg0 - Data Buffer + */ + Method (procPsppPerformanceRequest, 1, NotSerialized) { + Store (procPsppProcessPerformanceRequest (Arg0), Local7) + Store (DeRefOf (Index (Local7, 2)), varReturnStatusLocal0) + if (LNotEqual (varReturnStatusLocal0, 2)) { + return (Local7) + } + procApplyPsppState () + return (Local7) + } + /*----------------------------------------------------------------------------------------*/ + /** + * PCIe Performance Request + * + * Arg0 - Data Buffer + */ + Method (procPsppProcessPerformanceRequest, 1, NotSerialized) { + Store ("PsppProcessPerformanceRequest Enter", Debug) + Name (varClientBus, 0) + Store (0, varPortIndex) + Store (Buffer (10) {}, Local7) + CreateWordField (Local7, 0x0, varReturnBufferLength) + Store (3, varReturnBufferLength) + CreateByteField (Local7, 0x2, varReturnStatus) + Store (1, varReturnStatus) + + if (LOr (LLessEqual (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LGreaterEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) { + Store (" No action. [Policy type]", Debug) + Store ("PsppPerformanceRequest Exit", Debug) + return (Local7) + } + if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_STOP)) { + Store (" No action. [Policy not started]", Debug) + Store ("PsppPerformanceRequest Exit", Debug) + return (Local7) + } + CreateWordField (Arg0, 0x2, varClientId) + CreateWordField (Arg0, 0x4, varValidFlag) + CreateWordField (Arg0, 0x6, varFlag) + CreateByteField (Arg0, 0x8, varRequestType) + CreateByteField (Arg0, 0x9, varRequestData) + + Store (Concatenate (" Client ID : ", ToHexString (varClientId), varStringBuffer), Debug) + Store (Concatenate (" Valid Flags : ", ToHexString (varValidFlag), varStringBuffer), Debug) + Store (Concatenate (" Flags : ", ToHexString (varFlag), varStringBuffer), Debug) + Store (Concatenate (" Request Type: ", ToHexString (varRequestType), varStringBuffer), Debug) + Store (Concatenate (" Request Data: ", ToHexString (varRequestData), varStringBuffer), Debug) + + + And (ShiftRight (varClientId, 8), 0xff, varClientBus) + while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) { + if (LEqual (procChecPortAllocated (varPortIndex), DEF_PORT_ALLOCATED)) { + Store (procPciDwordRead (ShiftLeft (Add( varPortIndex, 2), 3), 0x18), Local1) + And (ShiftRight (Local1, 16), 0xff, varSubordinateBusLocal2) //Local2 Port Subordinate Bus number + And (ShiftRight (Local1, 8), 0xff, varSecondaryBusLocal1) //Local1 Port Secondary Bus number + if (LAnd (LGreaterEqual (varClientBus, Local1), LLessEqual(varClientBus, Local2))) { + break + } + } + Increment (varPortIndex) + } + if (LGreater (varPortIndex, varMaxPortIndexNumber)) { + Store ("PsppPerformanceRequest Exit", Debug) + return (Local7) + } + + Store (Concatenate (" Performance request for port index : ", ToHexString (varPortIndex), Local6), Debug) + + if (LEqual (DeRefOf (Index (varPsppClientIdArray, varPortIndex)), 0x0000)) { + Store (varClientId, Index (varPsppClientIdArray, varPortIndex)) + } ElseIf (LNotEqual (DeRefOf (Index (varPsppClientIdArray, varPortIndex)), varClientId)) { + // We already have registered client + Store (" No action. [Unsupported request]", Debug) + Store ("PsppPerformanceRequest Exit", Debug) + return (Local7) + } + Store (0, Index (varLowVoltageRequest, varPortIndex)) + if (LEqual (varRequestData, 0)) { + Store (0x0000, Index (varPsppClientIdArray, varPortIndex)) + } + if (LEqual (varRequestData, 1)) { + Store (1, Index (varLowVoltageRequest, varPortIndex)) + } + if (LEqual (varRequestData, 2)) { + Store (DEF_LINK_SPEED_GEN1, Index (varRequestedLinkSpeed, varPortIndex)) + } + if (LEqual (varRequestData, 3)) { + Store (DEF_LINK_SPEED_GEN2, Index (varRequestedLinkSpeed, varPortIndex)) + } + if (LEqual (And (varValidFlag, varFlag), 0x1)) { + Store (DerefOf (Index (varMaxLinkSpeed, varPortIndex)), Index (varRequestedLinkSpeed, varPortIndex)) + } + Store (2, varReturnStatus) + Store ("PsppProcessPerformanceRequest Exit", Debug) + return (Local7) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * PSPP Start/Stop Management Request + * + * Arg0 - Data Buffer + */ + + Method (procChecPortAllocated, 1, Serialized) { + if (LEqual (DeRefOf (Index (varMaxLinkSpeed, Arg0)), 0)) { + return (DEF_PORT_NOT_ALLOCATED) + } + return (DEF_PORT_ALLOCATED) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * PSPP Start/Stop Management Request + * + * Arg0 - Data Buffer + */ + Method (procPsppControl, 1, Serialized) { + Store ("PsppControl Enter", Debug) + Store (Buffer (256) {}, Local7) + Store (3, Index (Local7, 0x0)) // Return Buffer Length + Store (0, Index (Local7, 0x1)) // Return Buffer Length + Store (0, Index (Local7, 0x2)) // Return Status + + Store (DerefOf (Index (Arg0, 0x2)), varPsppPolicyService) + + Store (procIndirectRegisterRead (0x0, 0x60, 0xF4), varPsppScratchLocal0) + + if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_START)) { + if (LEqual (And (varPsppScratchLocal0, 1), DEF_PSPP_POLICY_START)) { + // Policy already started + Store (" No action. [Policy already started]", Debug) + Store ("PsppControl Exit", Debug) + return (Local7) + } + Or (varPsppScratchLocal0, DEF_PSPP_POLICY_START, varPsppScratchLocal0) + } + if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_STOP)) { + if (LEqual (And (varPsppScratchLocal0, 1), DEF_PSPP_POLICY_STOP)) { + // Policy already stopped + Store (" No action. [Policy already stopped]", Debug) + Store ("PsppControl Exit", Debug) + return (Local7) + } + And (varPsppScratchLocal0, Not (DEF_PSPP_POLICY_START), varPsppScratchLocal0) + } + Or (varPsppScratchLocal0, Shiftleft (varPsppPolicy, DEF_SCARTCH_PSPP_POLICY_OFFSET), varPsppScratchLocal0) + procIndirectRegisterWrite (0x0, 0x60, 0xF4, varPsppScratchLocal0) + + procCopyPackage (RefOf (varDefaultPsppClientIdArray), RefOf (varPsppClientIdArray)) + + // Reevaluate APM/PDM state here on S3 resume while staying on DC. + procApmPdmActivate(varPsppAcDcState) + + // Set DPM state for PSPP Power Saving, due to this policy will not attend ApplyPsppState service. + if (LEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING)) { + procNbLclkDpmActivate(DEF_LINK_SPEED_GEN1) +#ifdef ALTVDDNB_SUPPORT + procNbAltVddNb (DEF_LINK_SPEED_GEN1) +#endif + } + //Reevaluate PCIe speed for all devices base on PSPP state switch to boot up voltage + if (LAnd (LGreater (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LLess (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) { + // Load default speed capability state + if (LEqual (varPsppPolicy, DEF_PSPP_POLICY_BALANCEHIGH)) { + procCopyPackage (RefOf (varMaxLinkSpeed), RefOf (varCurrentLinkSpeed)) + Store (0, varPortIndex) + while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) { + if (LNotEqual (DeRefOf (Index (varOverrideLinkSpeed, varPortIndex)), 0)) { + Store (DeRefOf (Index (varOverrideLinkSpeed, varPortIndex)), Index (varCurrentLinkSpeed, varPortIndex)) + } + Increment (varPortIndex) + } + } else { + procCopyPackage (RefOf (varGen1LinkSpeedTemplate), RefOf (varCurrentLinkSpeed)) + } + procApplyPsppState () + } + Store ("PsppControl Exit", Debug) + return (Local7) + } + + Name (varNewLinkSpeed, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) + + /*----------------------------------------------------------------------------------------*/ + /** + * Evaluate PCIe speed on all links according to PSPP state and client requests + * + * + * + */ + Method (procApplyPsppState, 0, Serialized) { + Store ("ApplyPsppState Enter", Debug) + Store (0, varPortIndex) + + procCopyPackage (RefOf (varGen1LinkSpeedTemplate), RefOf (varNewLinkSpeed)) + while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) { + if (LEqual (procChecPortAllocated(varPortIndex), DEF_PORT_ALLOCATED)) { + Store (procGetPortRequestedCapability (varPortIndex), Index (varNewLinkSpeed, varPortIndex)) + } + Increment (varPortIndex) + } + if (LNotEqual(Match (varLowVoltageRequest, MEQ, 0x01, MTR, 0, 0), ONES)) { + procCopyPackage (RefOf (varGen1LinkSpeedTemplate), RefOf (varNewLinkSpeed)) + } + if (LNotEqual(Match (varNewLinkSpeed, MEQ, DEF_LINK_SPEED_GEN2, MTR, 0, 0), ONES)) { + // Set GEN2 voltage + Store ("Set GEN2 VID", Debug) +#ifdef ALTVDDNB_SUPPORT + procNbAltVddNb (DEF_LINK_SPEED_GEN2) +#endif + procPcieSetVoltage (varGen2Vid, 1) +// procPcieAdjustPll (DEF_LINK_SPEED_GEN2) + procNbLclkDpmActivate(DEF_LINK_SPEED_GEN2) + } + Store (0, varPortIndex) + while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) { + if (LEqual (procChecPortAllocated(varPortIndex), DEF_PORT_NOT_ALLOCATED)) { + Increment (varPortIndex) + continue + } + Store (DerefOf (Index (varCurrentLinkSpeed, varPortIndex)), varCurrentLinkSpeedLocal0) + Store (DerefOf (Index (varNewLinkSpeed, varPortIndex)), varNewLinkSpeedLocal2) + if (LEqual (varCurrentLinkSpeedLocal0, varNewLinkSpeedLocal2)) { + Increment (varPortIndex) + continue + } + Store (varNewLinkSpeedLocal2, Index (varCurrentLinkSpeed, varPortIndex)) + procSetPortCapabilityAndSpeed (varPortIndex, varNewLinkSpeedLocal2) + Increment (varPortIndex) + } + if (LEqual(Match (varNewLinkSpeed, MEQ, DEF_LINK_SPEED_GEN2, MTR, 0, 0), ONES)) { + // Set GEN1 voltage + Store ("Set GEN1 VID", Debug) + procNbLclkDpmActivate(DEF_LINK_SPEED_GEN1) +// procPcieAdjustPll (DEF_LINK_SPEED_GEN1) + procPcieSetVoltage (varGen1Vid, 0) +#ifdef ALTVDDNB_SUPPORT + procNbAltVddNb (DEF_LINK_SPEED_GEN1) +#endif + } +#ifdef PHY_SPEED_REPORT_SUPPORT + procReportPhySpeedCap () +#endif + Store ("ApplyPsppState Exit", Debug) + } + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCI config register + * + * Arg0 - Port Index + * + */ + Method (procGetPortRequestedCapability, 1) { + Store (DEF_LINK_SPEED_GEN2, Local0) + if (LEqual (DerefOf (Index (varPsppClientIdArray, Arg0)), 0x0000)) { + if (LOr (LEqual (procPsppGetAcDcState(), DEF_PSPP_STATE_DC), LEqual (varPsppPolicy, DEF_PSPP_POLICY_BALANCELOW))) { + // Default policy cap to GEN1 + Store (DEF_LINK_SPEED_GEN1, Local0) + } + if (LNotEqual (DerefOf (Index (varOverrideLinkSpeed, Arg0)), 0)) { + Store (DerefOf (Index (varOverrideLinkSpeed, Arg0)), Local0) + } + } else { + Store (DerefOf (Index (varRequestedLinkSpeed, Arg0)), Local0) + } + return (Local0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Set capability and speed + * + * Arg0 - Port Index + * Arg1 - Link speed + */ + Method (procSetPortCapabilityAndSpeed, 2, NotSerialized) { + Store ("SetPortCapabilityAndSpeed Enter", Debug) + Store (Concatenate (" Port Index : ", ToHexString (Arg0), varStringBuffer), Debug) + Store (Concatenate (" Speed : ", ToHexString (Arg1), varStringBuffer), Debug) + + //UnHide UMI port + if (LEqual (Arg0, 6)) { + procIndirectRegisterRMW (0x0, 0x60, 0x80, Not (0x40), 0x40); + } + + procPcieSetLinkSpeed (Arg0, Arg1) + + // Programming for LcInitSpdChgWithCsrEn + if (LNotEqual (DeRefOf (Index (varPsppClientIdArray, Arg0)), 0x0000)) { + // Registered port, LcInitSpdChgWithCsrEn = 0. + procPciePortIndirectRegisterRMW (Arg0, 0xA1, Not (0x00001000), 0x0) + } else { + procPciePortIndirectRegisterRMW (Arg0, 0xA1, Not (0x00001000), 0x00001000) + } + + // Determine port PCI address and check port present + Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1) + And (procPciDwordRead (varPortBdfLocal1, 0x70), 0x400000, varPortPresentLocal3) + if (LNotEqual (varPortPresentLocal3, 0)) { + procDisableAndSaveAspm (Arg0) + Store (1, Local2) + while (Local2) { + //retrain port + procPciDwordRMW (varPortBdfLocal1, 0x68, Not (0x00000000), 0x20) + Sleep (30) + while (And (procPciDwordRead (varPortBdfLocal1, 0x68), 0x08000000)) { + Sleep (10) + } + Store (0, Local2) + if (LEqual (Arg1, DEF_LINK_SPEED_GEN1)) { + Store (procPciePortIndirectRegisterRead (Arg0, 0xA4), varLcCurrentDataRateLocal4) + if (LNotEqual (And (varLcCurrentDataRateLocal4, 0x800), 0)) { + Store (1, Local2) + } + } + } + procRestoreAspm (Arg0) + } else { + Store (" Device not present. Set capability and speed only", Debug) + } + //Hide UMI port + if (LEqual (Arg0, 6)) { + procIndirectRegisterRMW (0x0, 0x60, 0x80, Not (0x40), 0x00); + } + Store ("SetPortCapabilityAndSpeed Exit", Debug) + } + + Name (varPcieLinkControlArray, Package () {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) + Name (varPcieLinkControlOffset, 0) + Name (varPcieLinkControlData, 0) + + /*----------------------------------------------------------------------------------------*/ + /** + * Disable and save ASPM state + * + * Arg0 - Port Index + */ + Method (procDisableAndSaveAspm, 1, Serialized) { + Store (0, varPcieLinkControlOffset) + Store (0, varPcieLinkControlData) + + Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1) + if (LEqual (Arg0, 6)) { + Store (" Disable SB ASPM", Debug) + Store (procPcieSbAspmControl (0, 0), Index (varPcieLinkControlArray, 0)) + Store (Concatenate (" PcieLinkControl Data : ", ToHexString (DerefOf(Index (varPcieLinkControlArray, 0))), varStringBuffer), Debug) + procPcieSbAspmControl (0, 1) + return (0) + } + + Store (procPciDwordRead (varPortBdfLocal1, 0x18), varTempLocal3) + Store (And (ShiftRight (varTempLocal3, 8), 0xFF), varTempLocal3) + + Store (Concatenate (" Disable EP ASPM on Secondary Bus : ", ToHexString (varTempLocal3), varStringBuffer), Debug) + + Store (ShiftLeft (varTempLocal3, 8), varEndpointBdfLocal2) + Store (procPciDwordRead (varEndpointBdfLocal2, 0xC), varTempLocal3) + Store (And (ShiftRight (varTempLocal3, 16), 0xFF), varTempLocal3) + + Store (Concatenate (" EP Header type : ", ToHexString (varTempLocal3), varStringBuffer), Debug) + + if (LNotEqual (And (varTempLocal3, 0x80), 0)) { + Store (0x7, varMaxFunctionLocal0) + } else { + Store (0x0, varMaxFunctionLocal0) + } + Store (0, varFunctionLocal4) + while (LLessEqual (varFunctionLocal4, varMaxFunctionLocal0)) { + //Find PcieLinkControl register offset = PcieCapPtr + 0x10 + Store (procFindPciCapability (Add (varEndpointBdfLocal2, varFunctionLocal4), 0x10), varPcieLinkControlOffset) + if (LEqual (varPcieLinkControlOffset, 0)) { + Increment (varFunctionLocal4) + continue + } + Add (varPcieLinkControlOffset, 0x10, varPcieLinkControlOffset) + + Store (Concatenate (" Function number of Secondary Bus : ", ToHexString (varFunctionLocal4), varStringBuffer), Debug) + Store (Concatenate (" PcieLinkControl register offset : ", ToHexString (varPcieLinkControlOffset), varStringBuffer), Debug) + // Save ASPM on EP + Store (procPciDwordRead (Add (varEndpointBdfLocal2, varFunctionLocal4) , varPcieLinkControlOffset), varPcieLinkControlData) + Store (And (varPcieLinkControlData, 0x3), Index (varPcieLinkControlArray, varFunctionLocal4)) + + Store (Concatenate (" PcieLinkControl Data : ", ToHexString (varPcieLinkControlData), varStringBuffer), Debug) + + procPciDwordRMW (Add (varEndpointBdfLocal2, varFunctionLocal4), varPcieLinkControlOffset, Not (0x00000003), 0x00) + Store ("Disable ASPM on EP Complete!!", Debug) + Increment (varFunctionLocal4) + } + } + /*----------------------------------------------------------------------------------------*/ + /** + * Restore ASPM + * + * Arg0 - Port Index + */ + Method (procRestoreAspm, 1, Serialized) { + + Store (0, varPcieLinkControlOffset) + Store (0, varPcieLinkControlData) + + + // Restore SB ASPM + if (LEqual (Arg0, 6)) { + Store (" Restore SB ASPM", Debug) + Store (Concatenate (" PcieLinkControl Data : ", ToHexString (DerefOf(Index (varPcieLinkControlArray, 0))), varStringBuffer), Debug) + procPcieSbAspmControl (DerefOf(Index (varPcieLinkControlArray, 0)), 1) + return (0) + } + Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1) + // Restore EP ASPM + Store (procPciDwordRead (varPortBdfLocal1, 0x18), varTempLocal3) + Store (And (ShiftRight (varTempLocal3, 8), 0xFF), varTempLocal3) + + Store (Concatenate (" Disable EP ASPM on SecondaryBus : ", ToHexString (varTempLocal3), varStringBuffer), Debug) + + Store (ShiftLeft (varTempLocal3, 8), varEndpointBdfLocal2) + Store (procPciDwordRead (varEndpointBdfLocal2, 0xC), varTempLocal3) + Store (And (ShiftRight (varTempLocal3, 16), 0xFF), varTempLocal3) + + Store (Concatenate (" EP Header type : ", ToHexString (varTempLocal3), varStringBuffer), Debug) + + if (LNotEqual (And (varTempLocal3, 0x80), 0)) { + Store (0x7, varMaxFunctionLocal0) + } else { + Store (0x0, varMaxFunctionLocal0) + } + Store (0, varFunctionLocal4) + while (LLessEqual (varFunctionLocal4, varMaxFunctionLocal0)) { + //Find PcieLinkControl register offset = PcieCapPtr + 0x10 + Store (procFindPciCapability (Add (varEndpointBdfLocal2, varFunctionLocal4), 0x10), varPcieLinkControlOffset) + if (LEqual (varPcieLinkControlOffset, 0)) { + Increment (varFunctionLocal4) + continue + } + Add (varPcieLinkControlOffset, 0x10, varPcieLinkControlOffset) + + Store (Concatenate (" Restore Function number of SecondaryBus : ", ToHexString (varFunctionLocal4), varStringBuffer), Debug) + Store (Concatenate (" Restore PcieLinkControl register offset : ", ToHexString (varPcieLinkControlOffset), varStringBuffer), Debug) + Store (Concatenate (" PcieLinkControl Data : ", ToHexString (DerefOf (Index (varPcieLinkControlArray, varFunctionLocal4))), varStringBuffer), Debug) + + procPciDwordWrite (Add (varEndpointBdfLocal2, varFunctionLocal4), varPcieLinkControlOffset, DerefOf (Index (varPcieLinkControlArray, varFunctionLocal4))) + Increment (varFunctionLocal4) + } + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Request VID + * + * Arg0 - Port Index + * Arg1 - PCIe speed + */ + + Method (procPcieSetLinkSpeed, 2) { + Store (ShiftLeft (Add( Arg0, 2), 3), Local0) + if (LEqual (Arg1, DEF_LINK_SPEED_GEN1)) { + procPciDwordRMW (Local0, 0x88, Not (0x0000002f), 0x21) + procPciePortIndirectRegisterRMW (Arg0, 0xA4, Not (0x20000001), 0x0) + } else { + procPciePortIndirectRegisterRMW (Arg0, 0xA4, Not (0x20000001), 0x20000001) + procPciDwordRMW (Local0, 0x88, Not (0x0000002f), 0x2) + } + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCIe port indirect register + * + * Arg0 - Ref Source Pckage + * Arg1 - Ref to Destination Package + * + */ + Method (procCopyPackage, 2, NotSerialized) { + + Store (SizeOf (Arg0), Local1) + Store (0, Local0) + While (LLess (Local0, Local1)) { + Store (DerefOf(Index(DerefOf (Arg0), Local0)), Index(DerefOf (Arg1), Local0)) + Increment (Local0) + } + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Read PCIe port indirect register + * + * Arg0 - Ref Source Pckage + * Arg1 - Ref to Destination Package + * + */ + Method (procPsppGetAcDcState, 0 , NotSerialized) { + Return (And (varPsppAcDcState, varPsppAcDcOverride)) + } diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h new file mode 100755 index 0000000000..38849ffd21 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h @@ -0,0 +1,53 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _GNBPCIECONFIG_H_ +#define _GNBPCIECONFIG_H_ + + +#include "PcieConfigData.h" +#include "PcieConfigLib.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c new file mode 100755 index 0000000000..6f4f8fb8a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c @@ -0,0 +1,521 @@ +/* $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: 49916 $ @e \$Date: 2011-03-30 19:03:54 +0800 (Wed, 30 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "OptionGnb.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "PcieMapTopology.h" +#include "PcieInputParser.h" +#include "PcieConfigLib.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 + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +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 +PcieConfigurationInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PcieConfigAttachComplexes ( + IN OUT PCIe_COMPLEX_CONFIG *Base, + IN OUT PCIe_COMPLEX_CONFIG *New + ); + +AGESA_STATUS +PcieUpdateConfigurationData ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +STATIC +PcieConfigBuildData ( + IN AMD_EARLY_PARAMS *EarlyParamsPtr, + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +PCIe_COMPLEX_DESCRIPTOR * +PcieConfigProcessUserConfig ( + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * 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 *PcieComplexList; + AGESA_STATUS Status; + EarlyParamsPtr = (AMD_EARLY_PARAMS *) StdHeader; + PcieComplexList = PcieConfigProcessUserConfig (EarlyParamsPtr->GnbConfig.PcieComplexList, StdHeader); + if (PcieComplexList == NULL) { + return AGESA_FATAL; + } + GNB_DEBUG_CODE ( + PcieUserConfigConfigDump (PcieComplexList); + ); + Status = PcieConfigBuildData (EarlyParamsPtr, PcieComplexList, StdHeader); + HeapDeallocateBuffer (AMD_GNB_TEMP_DATA_HANDLE, StdHeader); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * 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 +STATIC +PcieConfigBuildData ( + IN AMD_EARLY_PARAMS *EarlyParamsPtr, + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + 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; + UINT8 SocketId; + PCIe_SILICON_CONFIG *Silicon; + UINTN CurrentComplexesDataLength; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Enter\n"); + AgesaStatus = AGESA_SUCCESS; + ComplexesDataLength = 0; + NumberOfSockets = GnbGetNumberOfSockets (StdHeader); + for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) { + if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) { + Status = PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + ComplexesDataLength += CurrentComplexesDataLength; + } + } + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList); + 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->Header.Child = offsetof (PCIe_PLATFORM_CONFIG, ComplexList); + PcieConfigSetDescriptorFlags (Pcie, DESCRIPTOR_PLATFORM | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_TOPOLOGY); + Buffer = (UINT8 *) (Pcie) + sizeof (PCIe_PLATFORM_CONFIG); + ComplexIndex = 0; + for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) { + if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) { + if (ComplexIndex > MAX_NUMBER_OF_COMPLEXES) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + Pcie->ComplexList[ComplexIndex].Header.Child = (UINT16) ((UINT8 *) Buffer - (UINT8 *) &Pcie->ComplexList[ComplexIndex]); + Pcie->ComplexList[ComplexIndex].Header.Parent = (UINT16) ((UINT8 *) &Pcie->ComplexList[ComplexIndex] - (UINT8 *) Pcie); + PcieConfigSetDescriptorFlags (&Pcie->ComplexList[ComplexIndex], DESCRIPTOR_COMPLEX | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY); + PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader); + Silicon = PcieConfigGetChildSilicon (&Pcie->ComplexList[ComplexIndex]); + Silicon->Header.Parent = (UINT16) ((UINT8 *) Silicon - (UINT8 *) &Pcie->ComplexList[ComplexIndex]); + for (Index = 0; Index < NumberOfComplexes; Index++) { + ComplexDescriptor = PcieInputParserGetComplexDescriptor (PcieComplexList, Index); + if (ComplexDescriptor->SocketId == SocketId) { + Status = PcieMapTopologyOnComplex (ComplexDescriptor, &Pcie->ComplexList[ComplexIndex], Pcie); + Pcie->ComplexList[ComplexIndex].SocketId = SocketId; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (ComplexIndex > 0) { + PcieConfigAttachComplexes (&Pcie->ComplexList[ComplexIndex - 1], &Pcie->ComplexList[ComplexIndex]); + } + } + } + PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); + Buffer = (VOID *) ((UINT8 *) Buffer + CurrentComplexesDataLength); + ComplexIndex++; + } + } + Pcie->LinkReceiverDetectionPooling = GnbBuildOptions.CfgGnbLinkReceiverDetectionPooling; + Pcie->LinkL0Pooling = GnbBuildOptions.CfgGnbLinkL0Pooling; + Pcie->LinkGpioResetAssertionTime = GnbBuildOptions.CfgGnbLinkGpioResetAssertionTime; + Pcie->LinkResetToTrainingTime = GnbBuildOptions.CfgGnbLinkResetToTrainingTime; + Pcie->GfxCardWorkaround = GfxWorkaroundEnable; + Pcie->TrainingExitState = LinkStateTrainingCompleted; + Pcie->TrainingAlgorithm = GnbBuildOptions.CfgGnbTrainingAlgorithm; + 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] PcieComplexList User PCIe topology configuration + * @param[out] StdHeader Standard configuration header + * @retval Updated topology configuration + */ +PCIe_COMPLEX_DESCRIPTOR * +PcieConfigProcessUserConfig ( + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Node0SocketId; + UINT32 Node0SiliconId; + UINTN NumberOfComplexes; + UINTN NumberOfPorts; + UINTN Index; + UINT16 DescriptorLoLane; + UINT16 DescriptorHiLane; + PCIe_COMPLEX_DESCRIPTOR *ResultComplexConfig; + PCIe_COMPLEX_DESCRIPTOR *SbComplexDescriptor; + PCIe_PORT_DESCRIPTOR *SbPortDescriptor; + PCIe_PORT_DESCRIPTOR DefaultSbPortDescriptor; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + AGESA_STATUS Status; + SbPortDescriptor = NULL; + GetSocketModuleOfNode (0, &Node0SocketId, &Node0SiliconId, StdHeader); + Status = PcieFmGetSbConfigInfo ((UINT8) Node0SocketId, &DefaultSbPortDescriptor, StdHeader); + if (Status == AGESA_UNSUPPORTED) { + return PcieComplexList; + } + if (PcieComplexList == NULL) { + // No complex descriptor for any silicon was provided + // 1. Create complex descriptor + // 2. Create SB port descriptor + // 3. Attach SB descriptor to complex descriptor created in step #1 + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBufferAndClear ( + AMD_GNB_TEMP_DATA_HANDLE, + sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + SbComplexDescriptor = ResultComplexConfig; + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8 *) ResultComplexConfig + sizeof (PCIe_COMPLEX_DESCRIPTOR)); + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + SbPortDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + // Attach post array to complex descriptor + SbComplexDescriptor->PciePortList = SbPortDescriptor; + SbComplexDescriptor->SocketId = Node0SocketId; + SbComplexDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + } else { + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList); + SbComplexDescriptor = PcieInputParserGetComplexDescriptorOfSocket (PcieComplexList, Node0SocketId); + if (SbComplexDescriptor == NULL) { + // No complex descriptor for silicon that have SB attached. + // 1. Create complex descriptor. Will be first one in the list + // 2. Create SB port descriptor + // 3. Attach SB descriptor to complex descriptor created in step #1 + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBufferAndClear ( + AMD_GNB_TEMP_DATA_HANDLE, + (NumberOfComplexes + 1) * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + SbComplexDescriptor = ResultComplexConfig; + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8 *) ResultComplexConfig + (NumberOfComplexes + 1) * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + SbPortDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + // Attach post array to complex descriptor + SbComplexDescriptor->PciePortList = SbPortDescriptor; + SbComplexDescriptor->SocketId = Node0SocketId; + SbComplexDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + LibAmdMemCopy ( + (UINT8 *) ResultComplexConfig + sizeof (PCIe_COMPLEX_DESCRIPTOR), + PcieComplexList, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + StdHeader + ); + + } else { + // Complex descriptor that represent silicon that have SB attached exist + // 1. Determine if complex have descriptor for SB + // 2. Create new descriptor for SB if needed + NumberOfPorts = PcieInputParserGetLengthOfPcieEnginesList (SbComplexDescriptor); + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBuffer ( + AMD_GNB_TEMP_DATA_HANDLE, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + (NumberOfPorts + 1) * sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Copy complex descriptor array + LibAmdMemCopy ( + ResultComplexConfig, + PcieComplexList, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + StdHeader + ); + if (NumberOfPorts != 0) { + // Copy port descriptor array associated with complex with SB attached + LibAmdMemCopy ( + (UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + SbComplexDescriptor->PciePortList, + NumberOfPorts * sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Update SB complex pointer on in memory list + SbComplexDescriptor = PcieInputParserGetComplexDescriptorOfSocket ((PCIe_COMPLEX_DESCRIPTOR *) ResultComplexConfig, Node0SocketId); + // Attach port descriptor array to complex + SbComplexDescriptor->PciePortList = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR)); + for (Index = 0; Index < NumberOfPorts; ++Index) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (SbComplexDescriptor, Index); + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + if (DescriptorLoLane >= DefaultSbPortDescriptor.EngineData.StartLane && DescriptorLoLane <= DefaultSbPortDescriptor.EngineData.EndLane) { + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) EngineDescriptor; + } + } + } + } + if (SbPortDescriptor == NULL) { + // No descriptor that represent SB where found, create new one, will be first one in list + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + // Copy default config info + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + // Reattach descriptor list to complex + SbComplexDescriptor->PciePortList = SbPortDescriptor; + } else { + // Move SB descriptor to be first one in array + LibAmdMemCopy ( + (UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + SbPortDescriptor, + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Disable original SB descriptor + SbPortDescriptor->EngineData.EngineType = PcieUnusedEngine; + //Update pointer to new SB descriptor + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + //It is no longer a descriptor that terminates list + SbPortDescriptor->Flags &= (~ DESCRIPTOR_TERMINATE_LIST); + // Reattach descriptor list to complex + SbComplexDescriptor->PciePortList = SbPortDescriptor; + } + } + } + // Mark descriptor as SB link + SbPortDescriptor->Port.MiscControls.SbLink = 0x1; + return ResultComplexConfig; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * 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 = GnbLocateHeapBuffer (AMD_PCIE_COMPLEX_DATA_HANDLE, StdHeader); + if (*Pcie == NULL) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + PcieUpdateConfigurationData (*Pcie); + (*Pcie)->StdHeader = (PVOID) StdHeader; + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attache descriptors + * + * + * @param[in] Type Descriptor type + * @param[in,out] Base Base descriptor + * @param[in,out] New New descriptor + */ +VOID +STATIC +PcieConfigAttachDescriptors ( + IN UINT32 Type, + IN OUT PCIe_DESCRIPTOR_HEADER *Base, + IN OUT PCIe_DESCRIPTOR_HEADER *New + ) +{ + PCIe_DESCRIPTOR_HEADER *Left; + PCIe_DESCRIPTOR_HEADER *Right; + + Left = PcieConfigGetPeer (DESCRIPTOR_TERMINATE_GNB, PcieConfigGetChild (Type, Base)); + Right = PcieConfigGetChild (Type, New); + Left->Peer = (UINT16) ((UINT8 *) Right - (UINT8 *) Left); + PcieConfigResetDescriptorFlags (Left, DESCRIPTOR_TERMINATE_TOPOLOGY); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach configurations of two GNB to each other. + * + * Function will link all data structure to linked lists + * + * @param[in,out] Base Base complex descriptor + * @param[in,out] New New complex descriptor + */ +VOID +STATIC +PcieConfigAttachComplexes ( + IN OUT PCIe_COMPLEX_CONFIG *Base, + IN OUT PCIe_COMPLEX_CONFIG *New + ) +{ + // Connect Complex + Base->Header.Peer = (UINT16) ((UINT8 *) New - (UINT8 *) Base); + PcieConfigResetDescriptorFlags (Base, DESCRIPTOR_TERMINATE_TOPOLOGY); + // Connect Silicon + PcieConfigAttachDescriptors (DESCRIPTOR_SILICON, &Base->Header, &New->Header); + // Connect Wrappers + PcieConfigAttachDescriptors (DESCRIPTOR_PCIE_WRAPPER | DESCRIPTOR_DDI_WRAPPER, &Base->Header, &New->Header); + // Connect Engines + PcieConfigAttachDescriptors (DESCRIPTOR_PCIE_ENGINE | DESCRIPTOR_DDI_ENGINE, &Base->Header, &New->Header); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Update configuration data + * + * Puprouse of this structure to update config data that base on programming of + * other silicon compoments. For instance PCI address of GNB and PCIe ports + * can change by AGESA or external agent + * + * + * @param[in,out] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Configuration data successfully update + * @retval AGESA_FATAL Failt to update configuration + */ +AGESA_STATUS +PcieUpdateConfigurationData ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + PCIe_ENGINE_CONFIG *Engine; + PCI_ADDR NewAddress; + // Update silicon configuration + Silicon = PcieConfigGetChildSilicon (Pcie); + while (Silicon != NULL) { + NewAddress = GnbGetPciAddress (PcieConfigGetParentComplex (Silicon)->SocketId, Silicon->SiliconId, GnbLibGetHeader (Pcie)); + if (Silicon->Address.AddressValue != NewAddress.AddressValue) { + Silicon->Address.AddressValue = NewAddress.AddressValue; + Engine = PcieConfigGetChildEngine (Silicon); + while (Engine != NULL) { + if (PcieConfigIsPcieEngine (Engine)) { + Engine->Type.Port.Address.Address.Bus = Silicon->Address.Address.Bus; + } + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (Engine, DESCRIPTOR_TERMINATE_GNB); + } + } + Silicon = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (Silicon, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h new file mode 100755 index 0000000000..42cefa9097 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h @@ -0,0 +1,57 @@ +/* $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: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIECONFIGDATA_H_ +#define _PCIECONFIGDATA_H_ + + +AGESA_STATUS +PcieLocateConfigurationData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT PCIe_PLATFORM_CONFIG **Pcie + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c new file mode 100755 index 0000000000..2eb4eea46d --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c @@ -0,0 +1,720 @@ +/* $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: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "PcieMapTopology.h" +#include "PcieInputParser.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIECONFIGLIB_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * get Master Lane of PCIe port engine + * + * + * + * @param[in] Engine Pointer to engine descriptor + * @retval Master Engine Lane Number + */ +UINT8 +PcieConfigGetPcieEngineMasterLane ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT8 MasterLane; + ASSERT (PcieConfigIsPcieEngine (Engine)); + if (Engine->EngineData.StartLane <= Engine->EngineData.EndLane) { + MasterLane = (UINT8) Engine->Type.Port.StartCoreLane; + } else { + MasterLane = (UINT8) Engine->Type.Port.EndCoreLane; + } + return MasterLane; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of core lanes + * + * + * + * @param[in] Engine Pointer to engine descriptor + * @retval Number of core lane + */ +UINT8 +PcieConfigGetNumberOfCoreLane ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + if (Engine->Type.Port.StartCoreLane >= UNUSED_LANE_ID || Engine->Type.Port.EndCoreLane >= UNUSED_LANE_ID) { + return 0; + } + return (UINT8) (Engine->Type.Port.EndCoreLane - Engine->Type.Port.StartCoreLane + 1); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable engine + * + * + * + * @param[in] Engine Pointer to engine config descriptor + */ +VOID +PcieConfigDisableEngine ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + if (PcieConfigIsSbPcieEngine (Engine)) { + return; + } + PcieConfigResetDescriptorFlags (Engine, DESCRIPTOR_ALLOCATED); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable all engines on wrapper + * + * + * + * @param[in] EngineTypeMask Engine type bitmap. + * @param[in] Wrapper Pointer to wrapper config descriptor + */ +VOID +PcieConfigDisableAllEngines ( + IN UINTN EngineTypeMask, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if ((EngineList->EngineData.EngineType & EngineTypeMask) != 0) { + PcieConfigDisableEngine (EngineList); + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get engine PHY lanes bitmap + * + * + * + * @param[in] Engine Pointer to engine config descriptor + */ +UINT32 +PcieConfigGetEnginePhyLaneBitMap ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitMap; + LaneBitMap = 0; + if (PcieLibIsEngineAllocated (Engine)) { + LaneBitMap = ((1 << PcieConfigGetNumberOfPhyLane (Engine)) - 1) << (PcieLibGetLoPhyLane (Engine) - PcieConfigGetParentWrapper (Engine)->StartPhyLane); + } + return LaneBitMap; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of phy lanes + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @retval Number of Phy lane + */ +UINT8 +PcieConfigGetNumberOfPhyLane ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + if (Engine->EngineData.StartLane >= UNUSED_LANE_ID || Engine->EngineData.StartLane >= UNUSED_LANE_ID) { + return 0; + } + if (Engine->EngineData.StartLane > Engine->EngineData.EndLane) { + return (UINT8) (Engine->EngineData.StartLane - Engine->EngineData.EndLane + 1); + } else { + return (UINT8) (Engine->EngineData.EndLane - Engine->EngineData.StartLane + 1); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get port configuration signature for given wrapper and core + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] CoreId Core ID + * @retval Configuration Signature + */ +UINT64 +PcieConfigGetConfigurationSignature ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId + ) +{ + UINT64 ConfigurationSignature; + PCIe_ENGINE_CONFIG *EngineList; + ConfigurationSignature = 0; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (EngineList->Type.Port.CoreId == CoreId) { + ConfigurationSignature = (ConfigurationSignature << 8) | PcieConfigGetNumberOfCoreLane (EngineList); + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + return ConfigurationSignature; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check Port Status + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] PortStatus Check if status asserted for port + * @retval TRUE if status asserted + */ +BOOLEAN +PcieConfigCheckPortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT32 PortStatus + ) +{ + return (Engine->InitStatus & PortStatus) == 0 ? FALSE : TRUE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set/Reset port status + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] SetStatus SetStatus + * @param[in] ResetStatus ResetStatus + * + */ +UINT32 +PcieConfigUpdatePortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT32 SetStatus, + IN UINT32 ResetStatus + ) +{ + Engine->InitStatus |= SetStatus; + Engine->InitStatus &= (~ResetStatus); + return Engine->InitStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute callback on all descriptor of specific type + * + * + * @param[in] DescriptorFlags Descriptor flags + * @param[in] TerminateFlags terminate flags + * @param[in] Callback Pointer to callback function + * @param[in, out] Buffer Pointer to buffer to pass information to callback + * @param[in] Pcie Pointer to global PCIe configuration + */ + +AGESA_STATUS +PcieConfigRunProcForAllDescriptors ( + IN UINT32 InDescriptorFlags, + IN UINT32 OutDescriptorFlags, + IN UINT32 TerminationFlags, + IN PCIe_RUN_ON_DESCRIPTOR_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_DESCRIPTOR_HEADER *Descriptor; + + AgesaStatus = AGESA_SUCCESS; + Descriptor = PcieConfigGetChild (InDescriptorFlags & DESCRIPTOR_ALL_TYPES, &Pcie->Header); + while (Descriptor != NULL) { + if ((InDescriptorFlags & Descriptor->DescriptorFlags) != 0 && (OutDescriptorFlags && Descriptor->DescriptorFlags) == 0) { + Status = Callback (Descriptor, Buffer, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + Descriptor = (PCIe_DESCRIPTOR_HEADER *) PcieConfigGetNextTopologyDescriptor (Descriptor, TerminationFlags); + } + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute callback on all wrappers in topology + * + * + * @param[in] DescriptorFlags Wrapper Flags + * @param[in] Callback Pointer to callback function + * @param[in, out] Buffer Pointer to buffer to pass information to callback + * @param[in] Pcie Pointer to global PCIe configuration + */ + +AGESA_STATUS +PcieConfigRunProcForAllWrappers ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_WRAPPER_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_WRAPPER_CONFIG *Wrapper; + + AgesaStatus = AGESA_SUCCESS; + Wrapper = (PCIe_WRAPPER_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_WRAPPERS, &Pcie->Header); + while (Wrapper != NULL) { + if (!(PcieLibIsVirtualDesciptor (Wrapper) && (DescriptorFlags & DESCRIPTOR_VIRTUAL) == 0)) { + if ((DescriptorFlags & DESCRIPTOR_ALL_WRAPPERS & Wrapper->Header.DescriptorFlags) != 0) { + Status = Callback (Wrapper, Buffer, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + } + Wrapper = (PCIe_WRAPPER_CONFIG *) PcieConfigGetNextTopologyDescriptor (Wrapper, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute callback on all engine in topology + * + * + * @param[in] DescriptorFlags Engine flags. + * @param[in] Callback Pointer to callback function + * @param[in, out] Buffer Pointer to buffer to pass information to callback + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieConfigRunProcForAllEngines ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_ENGINE_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + + PCIe_ENGINE_CONFIG *Engine; + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_ENGINES, &Pcie->Header); + while (Engine != NULL) { + if (!(PcieLibIsVirtualDesciptor (Engine) && (DescriptorFlags & DESCRIPTOR_VIRTUAL) == 0)) { + if (!((DescriptorFlags & DESCRIPTOR_ALLOCATED) != 0 && !PcieLibIsEngineAllocated (Engine))) { + if ((Engine->Header.DescriptorFlags & DESCRIPTOR_ALL_ENGINES & DescriptorFlags) != 0) { + Callback (Engine, Buffer, Pcie); + } + } + } + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (Engine, DESCRIPTOR_TERMINATE_TOPOLOGY); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get parent descriptor of specific type + * + * + * @param[in] Type Descriptor type + * @param[in] Descriptor Pointer to buffer to pass information to callback + */ +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetParent ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ) +{ + while ((Descriptor->DescriptorFlags & Type) == 0) { + if (Descriptor->Parent != 0) { + Descriptor = (PCIe_DESCRIPTOR_HEADER *) ((UINT8 *) Descriptor - Descriptor->Parent); + } else { + return NULL; + } + } + return Descriptor; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get child descriptor of specific type + * + * + * @param[in] Type Descriptor type + * @param[in] Descriptor Pointer to buffer to pass information to callback + */ +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetChild ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ) +{ + while ((Descriptor->DescriptorFlags & Type) == 0) { + if (Descriptor->Child != 0) { + Descriptor = (PCIe_DESCRIPTOR_HEADER *) ((UINT8 *) Descriptor + Descriptor->Child); + } else { + return NULL; + } + } + return Descriptor; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get peer descriptor of specific type + * + * + * @param[in] Type Descriptor type + * @param[in] Descriptor Pointer to buffer to pass information to callback + */ +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetPeer ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ) +{ + while ((Descriptor->DescriptorFlags & Type) == 0) { + if (Descriptor->Peer != 0) { + Descriptor = (PCIe_DESCRIPTOR_HEADER *) ((UINT8 *) Descriptor + Descriptor->Peer); + } else { + return NULL; + } + } + return Descriptor; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump engine configuration + * + * + * @param[in] EngineList Engine Configuration + */ +VOID +PcieConfigEngineDebugDump ( + IN PCIe_ENGINE_CONFIG *EngineList + ) +{ + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", EngineList->Header.DescriptorFlags); + 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 + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Scrath - %d\n", EngineList->Scratch); + IDS_HDT_CONSOLE (PCIE_MISC, " Init Status - 0x%08x\n", EngineList->InitStatus); + 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, " Requested PCI Dev Number - %d\n",EngineList->Type.Port.PortData.DeviceNumber); + IDS_HDT_CONSOLE (PCIE_MISC, " Requested PCI Func Number - %d\n",EngineList->Type.Port.PortData.FunctionNumber); + 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, " Misc Control - %d\n", EngineList->Type.Port.PortData.MiscControls); + 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 == HotplugDisabled) ? "Disabled" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugBasic) ? "Basic" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugServer) ? "Server" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugEnhanced) ? "Enhanced" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugInboard) ? "Inboard" : "Unknown")))) + ); + ASSERT (EngineList->Type.Port.PortData.LinkHotplug < MaxHotplug); + IDS_HDT_CONSOLE (PCIE_MISC, " ASPM - %s\n", + (EngineList->Type.Port.PortData.LinkAspm == AspmDisabled) ? "Disabled" : ( + (EngineList->Type.Port.PortData.LinkAspm == AspmL0s) ? "L0s" : ( + (EngineList->Type.Port.PortData.LinkAspm == AspmL1) ? "L1" : ( + (EngineList->Type.Port.PortData.LinkAspm == AspmL0sL1) ? "L0s & L1" : "Unknown"))) + ); + ASSERT (EngineList->Type.Port.PortData.LinkAspm < MaxAspm); + 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" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeSingleLinkDviI) ? "Single Link DVI-I" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeCrt) ? "CRT" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeAutoDetect) ? "Autodetect" : "Unknown"))))))))))) + ); + ASSERT (EngineList->Type.Ddi.DdiData.ConnectorType < MaxConnectorType); + IDS_HDT_CONSOLE (PCIE_MISC, " Aux - Aux%d\n", EngineList->Type.Ddi.DdiData.AuxIndex + 1); + ASSERT (EngineList->Type.Ddi.DdiData.AuxIndex < MaxAux); + IDS_HDT_CONSOLE (PCIE_MISC, " Hdp - Hdp%d\n", EngineList->Type.Ddi.DdiData.HdpIndex + 1); + ASSERT (EngineList->Type.Ddi.DdiData.HdpIndex < MaxHdp); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump wrapper configuration + * + * + * @param[in] WrapperList Wrapper Configuration + */ +VOID +PcieConfigWrapperDebugDump ( + IN PCIe_WRAPPER_CONFIG *WrapperList + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config -------->\n", + PcieFmDebugGetWrapperNameString (WrapperList) + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", WrapperList->Header.DescriptorFlags); + 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 = PcieConfigGetChildEngine (WrapperList); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + PcieConfigEngineDebugDump (EngineList); + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump configuration to debug out + * + * + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieConfigDebugDump ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *SiliconList; + PCIe_WRAPPER_CONFIG *WrapperList; + PCIe_COMPLEX_CONFIG *ComplexList; + ComplexList = (PCIe_COMPLEX_CONFIG *) PcieConfigGetChild (DESCRIPTOR_COMPLEX, &Pcie->Header); + 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 + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Training Algorythm - %s\n", + (Pcie->TrainingAlgorithm == PcieTrainingStandard) ? "PcieTrainingStandard" : ( + (Pcie->TrainingAlgorithm == PcieTrainingDistributed) ? "PcieTrainingDistributed" : "Unknown") + ); + while (ComplexList != NULL) { + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Complex Config Start ---------->\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", ComplexList->Header.DescriptorFlags); + IDS_HDT_CONSOLE (PCIE_MISC, " Socket ID - %d\n", ComplexList->SocketId); + SiliconList = PcieConfigGetChildSilicon (ComplexList); + while (SiliconList != NULL) { + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Silicon Config Start -------->\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", SiliconList->Header.DescriptorFlags); + IDS_HDT_CONSOLE (PCIE_MISC, " Silicon ID - %d\n", SiliconList->SiliconId); + IDS_HDT_CONSOLE (PCIE_MISC, " Host PCI Address - %d:%d:%d\n", + SiliconList->Address.Address.Bus, + SiliconList->Address.Address.Device, + SiliconList->Address.Address.Function + ); + WrapperList = PcieConfigGetChildWrapper (SiliconList); + while (WrapperList != NULL) { + PcieConfigWrapperDebugDump (WrapperList); + WrapperList = PcieLibGetNextDescriptor (WrapperList); + } + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Silicon Config End ---------->\n"); + SiliconList = PcieLibGetNextDescriptor (SiliconList); + } + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Complex Config End ------------>\n"); + ComplexList = PcieLibGetNextDescriptor (ComplexList); + } + IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config End-------------->\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump input configuration to debug out + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieUserConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor + ) +{ + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + PCIe_COMPLEX_DESCRIPTOR *CurrentComplexDescriptor; + UINTN ComplexIndex; + UINTN Index; + UINTN NumberOfEngines; + UINTN NumberOfComplexes; + + IDS_HDT_CONSOLE (PCIE_MISC, "<---------- PCIe User Config Start------------->\n"); + + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (ComplexDescriptor); + for (ComplexIndex = 0; ComplexIndex < NumberOfComplexes; ++ComplexIndex) { + CurrentComplexDescriptor = PcieInputParserGetComplexDescriptor (ComplexDescriptor, ComplexIndex); + NumberOfEngines = PcieInputParserGetNumberOfEngines (CurrentComplexDescriptor); + IDS_HDT_CONSOLE (PCIE_MISC, " ComplexDescriptor SocketId - %d\n NumberOfEngines - %d\n", + ComplexDescriptor->SocketId, + NumberOfEngines + ); + + for (Index = 0; Index < NumberOfEngines; Index++) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); + IDS_HDT_CONSOLE (PCIE_MISC, " Engine Type - %s\n", + (EngineDescriptor->EngineData.EngineType == PciePortEngine) ? "PCIe Port" : ( + (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) ? "DDI Link" : ( + (EngineDescriptor->EngineData.EngineType == PcieUnusedEngine) ? "Unused" : "Invalid")) + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Start Phy Lane - %d\n End Phy Lane - %d\n", + EngineDescriptor->EngineData.StartLane, + EngineDescriptor->EngineData.EndLane + ); + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + IDS_HDT_CONSOLE (PCIE_MISC, " PortPresent - %d\n ChannelType - %d\n DeviceNumber - %d\n FunctionNumber - %d\n LinkSpeedCapability - %d\n LinkAspm - %d\n LinkHotplug - %d\n ResetId - %d\n SB link - %d\n" , + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.PortPresent, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.ChannelType, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.DeviceNumber, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.FunctionNumber, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkSpeedCapability, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkAspm, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkHotplug, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.ResetId, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.MiscControls.SbLink + ); + } + if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + IDS_HDT_CONSOLE (PCIE_MISC, " ConnectorType - %d\n AuxIndex - %d\n HdpIndex - %d\n" , + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.ConnectorType, + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.AuxIndex, + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.HdpIndex + ); + } + } + } + IDS_HDT_CONSOLE (PCIE_MISC, "<---------- PCIe User Config End-------------->\n"); +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h new file mode 100755 index 0000000000..e04d4ca0e7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h @@ -0,0 +1,202 @@ +/* $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: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIECONFIGLIB_H_ +#define _PCIECONFIGLIB_H_ + +typedef VOID (*PCIe_RUN_ON_ENGINE_CALLBACK) ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +typedef AGESA_STATUS (*PCIe_RUN_ON_WRAPPER_CALLBACK) ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +typedef AGESA_STATUS (*PCIe_RUN_ON_DESCRIPTOR_CALLBACK) ( + IN PCIe_DESCRIPTOR_HEADER *Descriptor, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT8 +PcieConfigGetPcieEngineMasterLane ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT8 +PcieConfigGetNumberOfCoreLane ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +VOID +PcieConfigDisableAllEngines ( + IN UINTN EngineTypeMask, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PcieConfigDisableEngine ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +PcieConfigGetEnginePhyLaneBitMap ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT8 +PcieConfigGetNumberOfPhyLane ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT64 +PcieConfigGetConfigurationSignature ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId + ); + +BOOLEAN +PcieConfigCheckPortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT32 PortStatus + ); + +UINT32 +PcieConfigUpdatePortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT32 SetStatus, + IN UINT32 ResetStatus + ); + +VOID +PcieConfigRunProcForAllEngines ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_ENGINE_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieConfigRunProcForAllWrappers ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_WRAPPER_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieConfigRunProcForAllDescriptors ( + IN UINT32 InDescriptorFlags, + IN UINT32 OutDescriptorFlags, + IN UINT32 TerminationFlags, + IN PCIe_RUN_ON_DESCRIPTOR_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetParent ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ); + +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetChild ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ); + +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetPeer ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ); + +VOID +PcieConfigDebugDump ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieConfigWrapperDebugDump ( + IN PCIe_WRAPPER_CONFIG *WrapperList + ); + +VOID +PcieConfigEngineDebugDump ( + IN PCIe_ENGINE_CONFIG *EngineList + ); + +VOID +PcieUserConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor + ); + +#define PcieConfigGetParentWrapper(Descriptor) ((PCIe_WRAPPER_CONFIG *) PcieConfigGetParent (DESCRIPTOR_ALL_WRAPPERS, &((Descriptor)->Header))) +#define PcieConfigGetParentSilicon(Descriptor) ((PCIe_SILICON_CONFIG *) PcieConfigGetParent (DESCRIPTOR_SILICON, &((Descriptor)->Header))) +#define PcieConfigGetParentComplex(Descriptor) ((PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &((Descriptor)->Header))) +#define PcieConfigGetPlatform(Descriptor) ((PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &((Descriptor)->Header))) +#define PcieConfigGetChildWrapper(Descriptor) ((PCIe_WRAPPER_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_WRAPPERS, &((Descriptor)->Header))) +#define PcieConfigGetChildEngine(Descriptor) ((PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_ENGINES, &((Descriptor)->Header))) +#define PcieConfigGetChildSilicon(Descriptor) ((PCIe_SILICON_CONFIG *) PcieConfigGetChild (DESCRIPTOR_SILICON, &((Descriptor)->Header))) +#define PcieConfigGetNextDescriptor(Descriptor) (Descriptor != NULL ? ((((Descriptor->Header.DescriptorFlags & DESCRIPTOR_TERMINATE_LIST) != 0) ? NULL : (++Descriptor))) : NULL) +#define PcieConfigIsPcieEngine(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_PCIE_ENGINE) != 0) : (1==0)) +#define PcieConfigIsDdiEngine(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_DDI_ENGINE) != 0) : (1==0)) +#define PcieConfigIsPcieWrapper(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_PCIE_WRAPPER) != 0) : (1==0)) +#define PcieConfigIsSbPcieEngine(Engine) ((BOOLEAN) (Engine->Type.Port.PortData.MiscControls.SbLink)) +#define PcieConfigIsDdiWrapper(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_DDI_WRAPPER) != 0) : (1==0)) +#define PcieConfigIsEngineAllocated(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_ALLOCATED) != 0) : (1==0)) +#define PcieConfigIsVirtualDesciptor(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_VIRTUAL) != 0) : (1==0)) +#define PcieConfigSetDescriptorFlags(Descriptor, SetDescriptorFlags) (Descriptor)->Header.DescriptorFlags |= SetDescriptorFlags +#define PcieConfigResetDescriptorFlags(Descriptor, ResetDescriptorFlags) ((PCIe_DESCRIPTOR_HEADER *) Descriptor)->DescriptorFlags &= (~(ResetDescriptorFlags)) +#define PcieInputParsetGetNextDescriptor(Descriptor) (Descriptor != NULL ? ((((Descriptor->Flags & DESCRIPTOR_TERMINATE_LIST) != 0) ? NULL : (++Descriptor))) : NULL) +#define PcieConfigGetNextTopologyDescriptor(Descriptor, Termination) (((((PCIe_DESCRIPTOR_HEADER *) Descriptor)->DescriptorFlags & Termination) != 0) ? NULL : ((UINT8 *) Descriptor + ((PCIe_DESCRIPTOR_HEADER *) Descriptor)->Peer)) + +#endif + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c new file mode 100755 index 0000000000..c6d9d47807 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c @@ -0,0 +1,256 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to parse PCIe input configuration data + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "PcieConfigLib.h" +#include "PcieInputParser.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIEINPUTPARSER_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 + *---------------------------------------------------------------------------------------- + */ +UINTN +PcieInputParserGetLengthOfDdiEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of complexes in platform topology configuration + * + * + * + * @param[in] ComplexList First complex configuration in complex configuration array + * @retval Number of Complexes + * + */ +UINTN +PcieInputParserGetNumberOfComplexes ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList + ) +{ + UINTN Result; + Result = 0; + if (ComplexList != NULL) { + while (ComplexList != NULL) { + Result++; + ComplexList = PcieInputParsetGetNextDescriptor (ComplexList); + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of PCIe engines in given complex + * + * + * + * @param[in] Complex Complex configuration + * @retval Number of Engines + */ +UINTN +PcieInputParserGetLengthOfPcieEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ) +{ + UINTN Result; + PCIe_PORT_DESCRIPTOR *PciePortList; + Result = 0; + if (Complex != NULL) { + PciePortList = Complex->PciePortList; + while (PciePortList != NULL) { + Result++; + PciePortList = PcieInputParsetGetNextDescriptor (PciePortList); + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of DDI engines in given complex + * + * + * + * @param[in] Complex Complex configuration + * @retval Number of Engines + */ +UINTN +PcieInputParserGetLengthOfDdiEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ) +{ + UINTN Result; + PCIe_DDI_DESCRIPTOR *DdiLinkList; + Result = 0; + if (Complex != NULL) { + DdiLinkList = Complex->DdiLinkList; + while (DdiLinkList != NULL) { + Result++; + DdiLinkList = PcieInputParsetGetNextDescriptor (DdiLinkList); + } + } + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of engines in given complex + * + * + * + * @param[in] Complex Complex configuration header + * @retval Number of Engines + */ +UINTN +PcieInputParserGetNumberOfEngines ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ) +{ + UINTN Result; + + Result = PcieInputParserGetLengthOfDdiEnginesList (Complex) + + PcieInputParserGetLengthOfPcieEnginesList (Complex); + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Complex descriptor by index from given Platform configuration + * + * + * + * @param[in] ComplexList Platform topology configuration + * @param[in] Index Complex descriptor Index + * @retval Pointer to Complex Descriptor + */ +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINTN Index + ) +{ + ASSERT (Index < (PcieInputParserGetNumberOfComplexes (ComplexList))); + return &ComplexList[Index]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Complex descriptor by index from given Platform configuration + * + * + * + * @param[in] ComplexList Platform topology configuration + * @param[in] Index Complex descriptor Index + * @retval Pointer to Complex Descriptor + */ +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptorOfSocket ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINT32 SocketId + ) +{ + PCIe_COMPLEX_DESCRIPTOR *Result; + Result = NULL; + while (ComplexList != NULL) { + if (ComplexList->SocketId == SocketId ) { + Result = ComplexList; + break; + } + ComplexList = PcieInputParsetGetNextDescriptor (ComplexList); + } + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Engine descriptor from given complex by index + * + * + * + * @param[in] Complex Complex descriptor + * @param[in] Index Engine descriptor index + * @retval Pointer to Engine Descriptor + */ +PCIe_ENGINE_DESCRIPTOR* +PcieInputParserGetEngineDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex, + IN UINTN Index + ) +{ + UINTN PcieListlength; + ASSERT (Index < (PcieInputParserGetNumberOfEngines (Complex))); + PcieListlength = PcieInputParserGetLengthOfPcieEnginesList (Complex); + if (Index < PcieListlength) { + return (PCIe_ENGINE_DESCRIPTOR*) &((Complex->PciePortList)[Index]); + } else { + return (PCIe_ENGINE_DESCRIPTOR*) &((Complex->DdiLinkList)[Index - PcieListlength]); + } +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h new file mode 100755 index 0000000000..6bc6699694 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h @@ -0,0 +1,83 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to parse PCIe input configuration data + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEINPUTPARSER_H_ +#define _PCIEINPUTPARSER_H_ + + +UINTN +PcieInputParserGetNumberOfComplexes ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList + ); + +UINTN +PcieInputParserGetNumberOfEngines ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); + + +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINTN Index + ); + +PCIe_ENGINE_DESCRIPTOR* +PcieInputParserGetEngineDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex, + IN UINTN Index + ); + +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptorOfSocket ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINT32 SocketId + ); + +UINTN +PcieInputParserGetLengthOfPcieEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); +#endif + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c new file mode 100755 index 0000000000..8894c1f55d --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c @@ -0,0 +1,658 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to map user define topology to processor configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GeneralServices.h" +#include "PcieInputParser.h" +#include "PcieMapTopology.h" +#include "GnbPcieConfig.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIEMAPTOPOLOGY_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 + *---------------------------------------------------------------------------------------- + */ + + +AGESA_STATUS +STATIC +PcieMapPortsPciAddresses ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieMapTopologyOnWrapper ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieMapInitializeEngineData ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +PcieCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +VOID +PcieComplexConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +PcieIsDescriptorLinkWidthValid ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ); + +BOOLEAN +PcieCheckLanesMatch ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +AGESA_STATUS +PcieEnginesToWrapper ( + IN PCIE_ENGINE_TYPE EngineType, + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +BOOLEAN +PcieCheckDescriptorMapsToWrapper ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PcieAllocateEngine ( + IN UINT8 DescriptorIndex, + IN PCIe_ENGINE_CONFIG *Engine + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Complex Pointer to complex descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +PcieMapTopologyOnComplex ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_COMPLEX_CONFIG *Complex, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + PCIe_WRAPPER_CONFIG *Wrapper; + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Enter\n"); + Silicon = PcieConfigGetChildSilicon (Complex); + while (Silicon != NULL) { + Wrapper = PcieConfigGetChildWrapper (Silicon); + while (Wrapper != NULL) { + Status = PcieMapTopologyOnWrapper (ComplexDescriptor, Wrapper, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + PcieConfigDisableAllEngines (PciePortEngine | PcieDdiEngine, Wrapper); + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to map topology on %s Wrapper\n", + PcieFmDebugGetWrapperNameString (Wrapper) + ); + ASSERT (FALSE); + } + Wrapper = PcieLibGetNextDescriptor (Wrapper); + } + Status = PcieMapPortsPciAddresses (Silicon, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + Silicon = PcieLibGetNextDescriptor (Silicon); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Exit [%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] EngineType Engine type + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ +AGESA_STATUS +PcieEnginesToWrapper ( + IN PCIE_ENGINE_TYPE EngineType, + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + AGESA_STATUS Status; + PCIe_ENGINE_CONFIG *EngineList; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + UINT8 ConfigurationId; + UINT8 Allocations; + UINTN Index; + UINTN NumberOfDescriptors; + + ConfigurationId = 0; + Allocations = 0; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Enter\n"); + NumberOfDescriptors = PcieInputParserGetNumberOfEngines (ComplexDescriptor); + do { + Status = PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId++); + + if (Status == AGESA_SUCCESS) { + Allocations = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); + if (EngineDescriptor->EngineData.EngineType == EngineType) { + // Step 1, belongs to wrapper check. + if (PcieCheckDescriptorMapsToWrapper (EngineDescriptor, Wrapper)) { + ++Allocations; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (!PcieLibIsEngineAllocated (EngineList)) { + // Step 2.user descriptor less or equal to link width of engine + if (PcieCheckLanesMatch (EngineDescriptor, EngineList)) { + // Step 3, Check if link width is correct.x1, x2, x4, x8, x16. + if (!PcieIsDescriptorLinkWidthValid (EngineDescriptor)) { + PcieConfigDisableEngine (EngineList); + return AGESA_ERROR; + } + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + // Step 4, Family specifc, port device number match engine device + if (PcieCheckPortPciDeviceMapping ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { + //Step 5, Family specifc, lanes can be muxed. + if (PcieFmCheckPortPcieLaneCanBeMuxed ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { + PcieAllocateEngine ((UINT8) Index, EngineList); + --Allocations; + break; + } + } + } else { + PcieAllocateEngine ((UINT8) Index, EngineList); + --Allocations; + break; + } + } + }//end if PcieLibIsEngineAllocated + EngineList = PcieLibGetNextDescriptor (EngineList); + } + }//end if PcieCheckDescriptorMapsToWrapper + }// end if EngineType + }//end for + } + } while (Status == AGESA_SUCCESS && Allocations != 0); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Exit [%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * + * + * @param[in] EngineDescriptor Pointer to used define engine descriptor + * @param[in] Wrapper Pointer to PCIe_WRAPPER_CONFIG + * @retval TRUE Belongs to wrapper + * @retval FALSE Not belongs to wrapper + */ +BOOLEAN +PcieCheckDescriptorMapsToWrapper ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + Result = TRUE; + + if (!(DescriptorLoLane >= Wrapper->StartPhyLane && DescriptorHiLane <= Wrapper->EndPhyLane)) { + // Lanes of descriptor does not belongs to wrapper + Result = FALSE; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Engine to be allocated. + * + * + * @param[in] DescriptorIndex UINT8 index + * @param[in] Engine Pointer to engine config + */ +VOID +PcieAllocateEngine ( + IN UINT8 DescriptorIndex, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + PcieConfigSetDescriptorFlags (Engine, DESCRIPTOR_ALLOCATED); + Engine->Scratch = DescriptorIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * PCIE port + * + * + * 1 Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * 2 Check if link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) + * 3 Check if link width is correct. Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 + * 4 Check if user port device number (PCIe_PORT_DESCRIPTOR) match engine port device number (PCIe_ENGINE_CONFIG) + * 5 Check if lane can be muxed + * + * + * DDI Link + * + * 1 Check if lane from user port descriptor (PCIe_DDI_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * 2 Check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) + * + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in,out] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ +AGESA_STATUS +PcieMapTopologyOnWrapper ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_ENGINE_CONFIG *EngineList; + UINT32 WrapperPhyLaneBitMap; + + AgesaStatus = AGESA_SUCCESS; + if (PcieLibIsPcieWrapper (Wrapper)) { + Status = PcieEnginesToWrapper (PciePortEngine, ComplexDescriptor, Wrapper); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + // If we can not map topology on wrapper we can not enable any engines. + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_PCIE_TOPOLOGY_CONFIGURATION, + Wrapper->WrapId, + Wrapper->StartPhyLane, + Wrapper->EndPhyLane, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableAllEngines (PciePortEngine, Wrapper); + } + } + if (PcieLibIsDdiWrapper (Wrapper)) { + Status = PcieEnginesToWrapper (PcieDdiEngine, ComplexDescriptor, Wrapper); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + // If we can not map topology on wrapper we can not enable any engines. + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_DDI_TOPOLOGY_CONFIGURATION, + Wrapper->WrapId, + Wrapper->StartPhyLane, + Wrapper->EndPhyLane, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableAllEngines (PcieDdiEngine, Wrapper); + } + } + // Copy engine data + PcieMapInitializeEngineData (ComplexDescriptor, Wrapper, Pcie); + + EngineList = PcieConfigGetChildEngine (Wrapper); + // Verify if we oversubscribe lanes and PHY link width + WrapperPhyLaneBitMap = 0; + while (EngineList != NULL) { + UINT32 EnginePhyLaneBitMap; + if (PcieLibIsEngineAllocated (EngineList)) { + EnginePhyLaneBitMap = PcieConfigGetEnginePhyLaneBitMap (EngineList); + if ((WrapperPhyLaneBitMap & EnginePhyLaneBitMap) != 0) { + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Lanes double subscribe lanes [Engine Lanes %d..%d]\n", + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane + ); + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_LANES_CONFIGURATION, + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableEngine (EngineList); + Status = AGESA_ERROR; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } else { + WrapperPhyLaneBitMap |= EnginePhyLaneBitMap; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize engine data + * + * + * + * @param[in] ComplexDescriptor Pointer to user defined complex descriptor + * @param[in,out] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieMapInitializeEngineData ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + if (EngineList->Scratch != 0xFF) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, EngineList->Scratch); + LibAmdMemCopy (&EngineList->EngineData, &EngineDescriptor->EngineData, sizeof (EngineDescriptor->EngineData), GnbLibGetHeader (Pcie)); + if (PcieLibIsDdiEngine (EngineList)) { + LibAmdMemCopy (&EngineList->Type.Ddi, &((PCIe_DDI_DESCRIPTOR*) EngineDescriptor)->Ddi, sizeof (PCIe_DDI_DATA), GnbLibGetHeader (Pcie)); + EngineList->Type.Ddi.DisplayPriorityIndex = (UINT8) EngineList->Scratch; + } else if (PcieLibIsPcieEngine (EngineList)) { + LibAmdMemCopy (&EngineList->Type.Port, &((PCIe_PORT_DESCRIPTOR*) EngineDescriptor)->Port, sizeof (PCIe_PORT_DATA), GnbLibGetHeader (Pcie)); + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate PCI addresses for all PCIe engines on silicon + * + * + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + + if ((PortDescriptor->Port.DeviceNumber == Engine->Type.Port.NativeDevNumber && + PortDescriptor->Port.FunctionNumber == Engine->Type.Port.NativeFunNumber) || + (PortDescriptor->Port.DeviceNumber == 0 && PortDescriptor->Port.FunctionNumber == 0)) { + Result = TRUE; + } else { + Result = PcieFmCheckPortPciDeviceMapping (PortDescriptor, Engine); + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate PCI addresses for all PCIe engines on silicon + * + * + * + * @param[in] Silicon Pointer to silicon configurration + * @param[in] Pcie Pointer PCIe configuration + * @retval AGESA_ERROR Fail to allocate PCI device address + * @retval AGESA_SUCCESS Successfully allocate PCI address for all PCIe ports + */ + +AGESA_STATUS +STATIC +PcieMapPortsPciAddresses ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + PCIe_WRAPPER_CONFIG *WrapperList; + PCIe_ENGINE_CONFIG *EngineList; + AgesaStatus = AGESA_SUCCESS; + WrapperList = PcieConfigGetChildWrapper (Silicon); + while (WrapperList != NULL) { + EngineList = PcieConfigGetChildEngine (WrapperList); + while (EngineList != NULL) { + if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { + Status = PcieFmMapPortPciAddress (EngineList); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + EngineList->Type.Port.Address.AddressValue = MAKE_SBDFO ( + 0, + Silicon->Address.Address.Bus, + EngineList->Type.Port.PortData.DeviceNumber, + EngineList->Type.Port.PortData.FunctionNumber, + 0 + ); + } else { + EngineList->Type.Port.PortData.PortPresent = OFF; + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to allocate PCI address for PCIe port\n" + ); + //Report error + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_PCIE_PORT_CONFIGURATION, + EngineList->Type.Port.PortData.DeviceNumber, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + WrapperList = PcieLibGetNextDescriptor (WrapperList); + } + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * If link width from user descriptor less or equal to link width of engine + * + * + * @param[in] EngineDescriptor Pointer to used define engine descriptor + * @param[in] Engine Pointer to engine config + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckLanesMatch ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + Result = FALSE; + + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + // + // If link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) + // + if (DescriptorNumberOfLanes <= PcieConfigGetNumberOfCoreLane (Engine)) { + Result = TRUE; + } + } else if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + // + //For Ddi, check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) + // + if ((Engine->EngineData.StartLane == DescriptorLoLane) && (Engine->EngineData.EndLane == DescriptorHiLane)) { + Result = TRUE; + } + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 + * + * + * @param[in] EngineDescriptor A pointer of PCIe_ENGINE_DESCRIPTOR + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieIsDescriptorLinkWidthValid ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + Result = FALSE; + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + if (DescriptorNumberOfLanes == 1 || DescriptorNumberOfLanes == 2 || DescriptorNumberOfLanes == 4 || + DescriptorNumberOfLanes == 8 || DescriptorNumberOfLanes == 16) { + Result = TRUE; + } + } else if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + if (DescriptorNumberOfLanes == 4 || DescriptorNumberOfLanes == 8 || DescriptorNumberOfLanes == 7) { + Result = TRUE; + } + } + + GNB_DEBUG_CODE ( + if (!Result) { + IDS_HDT_CONSOLE (PCIE_MISC, " Invalid Link width [Engine Lanes %d..%d]\n", + DescriptorLoLane, + DescriptorHiLane + ); + } + ); + + return Result; +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h new file mode 100755 index 0000000000..0673ecc477 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h @@ -0,0 +1,57 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to map user define topology to processor configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEMAPTOPOLOGY_H_ +#define _PCIEMAPTOPOLOGY_H_ + +AGESA_STATUS +PcieMapTopologyOnComplex ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_COMPLEX_CONFIG *Complex, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h new file mode 100755 index 0000000000..d91f34a4a2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Init Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 47656 $ @e \$Date: 2011-02-25 02:39:38 +0800 (Fri, 25 Feb 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEINITLIBV1_H_ +#define _PCIEINITLIBV1_H_ + +#include "PciePifServices.h" +#include "PciePortRegAcc.h" +#include "PciePowerMgmt.h" +#include "PcieTimer.h" +#include "PcieTopologyServices.h" +#include "PcieUtilityLib.h" +#include "PcieWrapperRegAcc.h" +#include "PcieAspmExitLatency.h" +#include "PcieSiliconServices.h" +#include "PciePortServices.h" +#include "PcieAspm.h" +#include "PciePhyServices.h" +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspm.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspm.c new file mode 100755 index 0000000000..19b6055180 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspm.c @@ -0,0 +1,350 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link ASPM + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "OptionGnb.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "PcieAspmBlackList.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEASPM_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; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + PCIE_ASPM_TYPE Aspm; + PCI_ADDR DownstreamPort; +} PCIE_ASPM_DATA; + +/*---------------------------------------------------------------------------------------- + * 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 +PcieAspmEnableOnDevice ( + IN PCI_ADDR Device, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +SCAN_STATUS +PcieAspmCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +VOID +PcieAspmEnableOnLink ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +PCIE_ASPM_TYPE +PcieAspmGetPmCapability ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable PCIE Advance state power management + * + * + * + * @param[in] DownstreamPort PCI Address of the downstream port + * @param[in] Aspm ASPM type + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +VOID +PcieLinkAspmEnable ( + IN PCI_ADDR DownstreamPort, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIE_ASPM_DATA PcieAspmData; + PcieAspmData.Aspm = Aspm; + PcieAspmData.ScanData.StdHeader = StdHeader; + PcieAspmData.ScanData.GnbScanCallback = PcieAspmCallback; + GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieAspmData.ScanData); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +PcieAspmCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + PCIE_ASPM_DATA *PcieAspmData; + PCIE_DEVICE_TYPE DeviceType; + ScanStatus = SCAN_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, " PcieAspmCallback for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + PcieAspmData = (PCIE_ASPM_DATA *) ScanData; + ScanStatus = SCAN_SUCCESS; + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + PcieAspmData->DownstreamPort = Device; + //PcieExitLatencyData->LinkCount++; + GnbLibPciRMW (Device.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffffull, 0x0, ScanData->StdHeader); + GnbLibPciScanSecondaryBus (Device, &PcieAspmData->ScanData); + //PcieExitLatencyData->LinkCount--; + break; + case PcieDeviceUpstreamPort: + PcieAspmEnableOnLink ( + PcieAspmData->DownstreamPort, + Device, + PcieAspmData->Aspm, + ScanData->StdHeader + ); + GnbLibPciRMW (Device.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffffull, 0x0, ScanData->StdHeader); + GnbLibPciScanSecondaryBus (Device, &PcieAspmData->ScanData); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + PcieAspmEnableOnLink ( + PcieAspmData->DownstreamPort, + Device, + PcieAspmData->Aspm, + ScanData->StdHeader + ); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + default: + break; + } + return ScanStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set ASMP State on PCIe device function + * + * + * + * @param[in] Function PCI address of function. + * @param[in] Aspm Aspm capability to enable + * @param[in] StdHeader Standard configuration header + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmEnableOnFunction ( + IN PCI_ADDR Function, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + PcieCapPtr = GnbLibFindPciCapability (Function.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRMW ( + Function.AddressValue | (PcieCapPtr + PCIE_LINK_CTRL_REGISTER) , + AccessS3SaveWidth8, + ~(UINT32)(BIT0 & BIT1), + Aspm, + StdHeader + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set ASMP State on all function of PCI device + * + * + * + * @param[in] Device PCI address of device. + * @param[in] Aspm Aspm capability to enable + * @param[in] StdHeader Standard configuration header + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmEnableOnDevice ( + IN PCI_ADDR Device, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxFunc; + UINT8 CurrentFunc; + MaxFunc = GnbLibPciIsMultiFunctionDevice (Device.AddressValue, StdHeader) ? 7 : 0; + for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) { + Device.Address.Function = CurrentFunc; + if (GnbLibPciIsDevicePresent (Device.AddressValue, StdHeader)) { + PcieAspmEnableOnFunction (Device, Aspm, StdHeader); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable ASPM on link + * + * + * + * @param[in] Downstream PCI Address of downstrteam port + * @param[in] Upstream PCI Address of upstream port + * @param[in] Aspm Aspm capability to enable + * @param[in] StdHeader Standard configuration header + */ + +VOID +PcieAspmEnableOnLink ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_LINK_ASPM LinkAsmp; + PCIE_ASPM_TYPE DownstreamCap; + PCIE_ASPM_TYPE UpstreamCap; + LinkAsmp.DownstreamPort = Downstream; + DownstreamCap = PcieAspmGetPmCapability (Downstream, StdHeader); + LinkAsmp.UpstreamPort = Upstream; + UpstreamCap = PcieAspmGetPmCapability (Upstream, StdHeader); + LinkAsmp.DownstreamAspm = DownstreamCap & UpstreamCap & Aspm & AspmL1; + LinkAsmp.UpstreamAspm = LinkAsmp.DownstreamAspm; + LinkAsmp.RequestedAspm = Aspm; + if ((UpstreamCap & Aspm & AspmL0s) != 0) { + LinkAsmp.UpstreamAspm |= AspmL0s; + } + if ((DownstreamCap & Aspm & AspmL0s) != 0) { + LinkAsmp.DownstreamAspm |= AspmL0s; + } + if (GnbBuildOptions.PcieAspmBlackListEnable == 1) { + PcieAspmBlackListFeature (&LinkAsmp, StdHeader); + } + //AgesaPcieLinkAspm (&LinkAsmp, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, " Set ASPM [%d] for Device = %d:%d:%d\n", + (LinkAsmp.UpstreamAspm) , + LinkAsmp.UpstreamPort.Address.Bus, + LinkAsmp.UpstreamPort.Address.Device, + LinkAsmp.UpstreamPort.Address.Function + ); + IDS_HDT_CONSOLE (GNB_TRACE, " Set ASPM [%d] for Device = %d:%d:%d\n", + (LinkAsmp.DownstreamAspm) , + LinkAsmp.DownstreamPort.Address.Bus, + LinkAsmp.DownstreamPort.Address.Device, + LinkAsmp.DownstreamPort.Address.Function + ); + PcieAspmEnableOnDevice (Upstream, LinkAsmp.UpstreamAspm, StdHeader); + PcieAspmEnableOnFunction (Downstream, LinkAsmp.DownstreamAspm, StdHeader); +} + + + +/**----------------------------------------------------------------------------------------*/ +/** + * Port/Endpoint ASMP capability + * + * + * + * @param[in] Device PCI address of downstream port + * @param[in] StdHeader Standard configuration header + * + * @retval PCIE_ASPM_TYPE + */ + /*----------------------------------------------------------------------------------------*/ +PCIE_ASPM_TYPE +PcieAspmGetPmCapability ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + UINT32 Value; + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr == 0) { + return 0; + } + GnbLibPciRead ( + Device.AddressValue | (PcieCapPtr + PCIE_LINK_CAP_REGISTER), + AccessWidth32, + &Value, + StdHeader + ); + return (Value >> 10) & 3; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspm.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspm.h new file mode 100755 index 0000000000..e24acd1b12 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspm.h @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link ASPM + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 47656 $ @e \$Date: 2011-02-25 02:39:38 +0800 (Fri, 25 Feb 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEASPM_H_ +#define _PCIEASPM_H_ + +VOID +PcieLinkAspmEnable ( + IN PCI_ADDR DownstreamPort, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieAspmEnableOnFunction ( + IN PCI_ADDR Function, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c new file mode 100755 index 0000000000..25664fbe21 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c @@ -0,0 +1,141 @@ +/** + * @file + * + * PCIe link ASPM Black List + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "PcieAspmBlackList.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEASPMBLACKLIST_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 + *---------------------------------------------------------------------------------------- + */ + + +UINT16 AspmBrDeviceTable[] = { + 0x1002, 0x9441, (UINT16) ~(AspmL1 | AspmL0s), + 0x10B5, 0xFFFF, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0402, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0193, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0422, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0292, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x00F9, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0141, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0092, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D0, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D1, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D2, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D3, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D5, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D7, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D8, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01DC, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01DE, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01DF, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x016A, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0392, (UINT16) ~(AspmL1 | AspmL0s), + 0x168C, 0xFFFF, (UINT16) ~(AspmL0s), + 0x1B4B, 0x91A3, (UINT16) ~(AspmL0s), + 0x1B4B, 0x9123, (UINT16) ~(AspmL0s) +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Pcie ASPM Black List + * + * + * + * @param[in] LinkAsmp PCie ASPM black list + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PcieAspmBlackListFeature ( + IN PCIe_LINK_ASPM *LinkAsmp, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 UpstreamDeviceId; + UINT32 DownstreamDeviceId; + UINTN i; + GnbLibPciRead (LinkAsmp->UpstreamPort.AddressValue, AccessWidth32, &UpstreamDeviceId, StdHeader); + GnbLibPciRead (LinkAsmp->DownstreamPort.AddressValue, AccessWidth32, &DownstreamDeviceId, StdHeader); + for (i = 0; i < (sizeof (AspmBrDeviceTable) / sizeof (UINT16)); i = i + 3) { + UINT32 DeviceId; + UINT32 VendorId; + VendorId = AspmBrDeviceTable[i]; + DeviceId = AspmBrDeviceTable[i + 1]; + if (VendorId == (UINT16)UpstreamDeviceId || VendorId == (UINT16)DownstreamDeviceId ) { + if (DeviceId == 0xFFFF || DeviceId == (UpstreamDeviceId >> 16) || DeviceId == (DownstreamDeviceId >> 16)) { + LinkAsmp->UpstreamAspm &= AspmBrDeviceTable[i + 2]; + LinkAsmp->DownstreamAspm &= AspmBrDeviceTable[i + 2]; + } + } + } + if ((UINT16)UpstreamDeviceId == 0x168c) { + // Atheros (Ignore dev capability enable L1 if requested) + LinkAsmp->UpstreamAspm = LinkAsmp->RequestedAspm & AspmL1; + LinkAsmp->DownstreamAspm = LinkAsmp->UpstreamAspm; + GnbLibPciRMW (LinkAsmp->UpstreamPort.AddressValue | 0x70C, AccessS3SaveWidth32, 0x0, 0x0F003F01, StdHeader); + } + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h new file mode 100755 index 0000000000..c7f87a37f5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h @@ -0,0 +1,55 @@ +/** + * @file + * + * PCIe ASPM Black List + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEASPMBLACKLIST_H_ +#define _PCIEASPMBLACKLIST_H_ + +///PCIe ASPM Black List + +AGESA_STATUS +PcieAspmBlackListFeature ( + IN PCIe_LINK_ASPM *LinkAsmp, + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.c new file mode 100755 index 0000000000..bef1142e3e --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.c @@ -0,0 +1,191 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to calculate PCIe topology segment maximum exit latency + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEASPMEXITLATENCY_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 + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + PCIe_ASPM_LATENCY_INFO *AspmLatencyInfo; + PCI_ADDR DownstreamPort; + UINT8 LinkCount; +} PCIE_EXIT_LATENCY_DATA; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +SCAN_STATUS +PcieAspmGetMaxExitLatencyCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Determine ASPM L-state maximum exit latency for PCIe segment + * + * Scan through all link in segment to determine maxim exit latency requirement by EPs. + * + * @param[in] DownstreamPort PCI address of PCIe port + * @param[out] AspmLatencyInfo Latency info + * @param[in] StdHeader Standard configuration header + * + */ + +VOID +PcieAspmGetMaxExitLatency ( + IN PCI_ADDR DownstreamPort, + OUT PCIe_ASPM_LATENCY_INFO *AspmLatencyInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIE_EXIT_LATENCY_DATA PcieExitLatencyData; + PcieExitLatencyData.AspmLatencyInfo = AspmLatencyInfo; + PcieExitLatencyData.ScanData.StdHeader = StdHeader; + PcieExitLatencyData.LinkCount = 0; + PcieExitLatencyData.ScanData.GnbScanCallback = PcieAspmGetMaxExitLatencyCallback; + GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieExitLatencyData.ScanData); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +PcieAspmGetMaxExitLatencyCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + PCIE_EXIT_LATENCY_DATA *PcieExitLatencyData; + PCIE_DEVICE_TYPE DeviceType; + UINT32 Value; + UINT8 PcieCapPtr; + UINT8 L1AcceptableLatency; + + PcieExitLatencyData = (PCIE_EXIT_LATENCY_DATA*) ScanData; + ScanStatus = SCAN_SUCCESS; + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, " PcieAspmGetMaxExitLatencyCallback for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + PcieExitLatencyData->DownstreamPort = Device; + PcieExitLatencyData->LinkCount++; + GnbLibPciScanSecondaryBus (Device, &PcieExitLatencyData->ScanData); + PcieExitLatencyData->LinkCount--; + break; + case PcieDeviceUpstreamPort: + GnbLibPciScanSecondaryBus (Device, &PcieExitLatencyData->ScanData); + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, ScanData->StdHeader); + ASSERT (PcieCapPtr != 0); + GnbLibPciRead ( + Device.AddressValue | (PcieCapPtr + PCIE_LINK_CAP_REGISTER), + AccessWidth32, + &Value, + ScanData->StdHeader + ); + if ((Value & PCIE_ASPM_L1_SUPPORT_CAP) != 0) { + GnbLibPciRead ( + Device.AddressValue | (PcieCapPtr + PCIE_DEVICE_CAP_REGISTER), + AccessWidth32, + &Value, + ScanData->StdHeader + ); + L1AcceptableLatency = (UINT8) (1 << ((Value >> 9) & 0x7)); + if (PcieExitLatencyData->LinkCount > 1) { + L1AcceptableLatency = L1AcceptableLatency + PcieExitLatencyData->LinkCount; + } + if (PcieExitLatencyData->AspmLatencyInfo->MaxL1ExitLatency < L1AcceptableLatency) { + PcieExitLatencyData->AspmLatencyInfo->MaxL1ExitLatency = L1AcceptableLatency; + } + IDS_HDT_CONSOLE (PCIE_MISC, " Device max exit latency L1 - %d us\n", + L1AcceptableLatency + ); + } + break; + default: + break; + } + return SCAN_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h new file mode 100755 index 0000000000..bdfa864bd4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to calculate PCIe topology segment maximum exit latency + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEASPMEXITLATENCY_H_ +#define _PCIEASPMEXITLATENCY_H_ + +VOID +PcieAspmGetMaxExitLatency ( + IN PCI_ADDR DownstreamPort, + OUT PCIe_ASPM_LATENCY_INFO *AspmLatencyInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.c new file mode 100755 index 0000000000..884f076677 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.c @@ -0,0 +1,310 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPHYSERVICES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define MAX_NUM_PHYs 2 +#define MAX_NUM_LANE_PER_PHY 8 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +// Required init values +INT8 ReqdInitValLo [] = { 42, 64, 0, 42, 64, 77}; +INT8 ReqdInitValHi [] = { 42, 64, 0, 42, 64, 77}; + + +//Channel Type: LowLoss / HighLoss / Mob0db / Mob3db / Ext6db / Ext8db +INT8 DeemphasisSel [] = { 1, 0, 1, 1, 0, 0}; +INT8 DeemphGen1Nom [] = { 42, 42, 0, 0, 42, 42}; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * PHY lane ganging + * + * + * + * @param[out] Wrapper Pointer to internal configuration data area + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePhyApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT8 GangMatrix [MAX_NUM_PHYs][MAX_NUM_LANE_PER_PHY]; + UINT8 MasterMatrix [MAX_NUM_PHYs][MAX_NUM_LANE_PER_PHY]; + UINT16 LoPhylane; + UINT16 HiPhylane; + UINT8 Phy; + UINT16 Lane; + UINT16 PhyLinkWidth; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyApplyGanging Enter\n"); + LibAmdMemFill (GangMatrix, 0, sizeof (GangMatrix), GnbLibGetHeader (Pcie)); + LibAmdMemFill (MasterMatrix, 0, sizeof (MasterMatrix), GnbLibGetHeader (Pcie)); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + HiPhylane = PcieLibGetHiPhyLane (EngineList) - Wrapper->StartPhyLane; + LoPhylane = PcieLibGetLoPhyLane (EngineList) - Wrapper->StartPhyLane; + PhyLinkWidth = HiPhylane - LoPhylane + 1; + + if (PhyLinkWidth >= 8) { + for (Lane = LoPhylane; Lane <= HiPhylane; Lane++) { + ((UINT8 *) GangMatrix)[Lane] = 1; + } + } else { + if (PhyLinkWidth > 0 && PhyLinkWidth < 4) { + for (Lane = (LoPhylane / 4) * 4; Lane < (((LoPhylane / 4) * 4) + 4) ; Lane++) { + ((UINT8 *) MasterMatrix)[Lane] = 1; + } + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + for (Phy = 0; Phy < Wrapper->NumberOfPIFs; Phy++) { + for (Lane = 0; Lane < MAX_NUM_LANE_PER_PHY; Lane++) { + D0F0xE4_PHY_6005_STRUCT D0F0xE4_PHY_6005; + D0F0xE4_PHY_6005.Value = PcieRegisterRead ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, Phy, D0F0xE4_PHY_6005_ADDRESS + Lane * 0x80), + Pcie + ); + D0F0xE4_PHY_6005.Field.GangedModeEn = GangMatrix [Phy][Lane]; + D0F0xE4_PHY_6005.Field.IsOwnMstr = MasterMatrix [Phy][Lane]; + PcieRegisterWrite ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, Phy, D0F0xE4_PHY_6005_ADDRESS + Lane * 0x80), + D0F0xE4_PHY_6005.Value, + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyApplyGanging Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Point "virtual" PLL clock picker away from PCIe + * + * + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePhyAvertClockPickers ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 DdiLanes; + UINT8 Nibble; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyAvertClockPickers Enter\n"); + DdiLanes = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_DDI_PHY_NATIVE, 0, Wrapper); + for (Nibble = 0; Nibble < 4; Nibble++) { + if (DdiLanes & (0xf << (Nibble * 4))) { + PcieRegisterRMW ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PHY_0009_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PHY_0009_PCIePllSel_MASK, + 0x0 << D0F0xE4_PHY_0009_PCIePllSel_OFFSET, + FALSE, + Pcie + ); + PcieRegisterRMW ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PHY_000B_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PHY_000B_MargPktSbiEn_MASK | D0F0xE4_PHY_000B_PcieModeSbiEn_MASK, + (0x0 << D0F0xE4_PHY_000B_MargPktSbiEn_OFFSET) | (0x0 << D0F0xE4_PHY_000B_PcieModeSbiEn_OFFSET), + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyAvertClockPickers Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set PHY channel characteristic + * + * + * + * @param[in] Engine Pointer to engine configuration + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePhyChannelCharacteristic ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_WRAPPER_CONFIG *Wrapper; + UINT16 StartLane; + UINT16 EndLane; + UINT16 Lane; + UINT8 ChannelType; + + Wrapper = PcieConfigGetParentWrapper (Engine); + ChannelType = Engine->Type.Port.PortData.ChannelType; + StartLane = MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) - Wrapper->StartPhyLane; + EndLane = MAX (Engine->EngineData.StartLane, Engine->EngineData.EndLane) - Wrapper->StartPhyLane; + + PcieRegisterRMW ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0803_ADDRESS + (Engine->Type.Port.PortId) * 0x100), + D0F0xE4_WRAP_0903_StrapBifDeemphasisSel_MASK, + DeemphasisSel[ChannelType] << D0F0xE4_WRAP_0903_StrapBifDeemphasisSel_OFFSET, + FALSE, + Pcie + ); + for (Lane = StartLane; Lane <= EndLane; Lane++) { + UINT16 PhyLane; + UINT16 Phy; + if (Lane < MAX_NUM_LANE_PER_PHY ) { + Phy = 0; + PhyLane = Lane; + } else { + Phy = 1; + PhyLane = Lane - MAX_NUM_LANE_PER_PHY; + } + PcieRegisterRMW ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, Phy, D0F0xE4_PHY_6006_ADDRESS + PhyLane * 0x80), + D0F0xE4_PHY_6006_DeemphGen1Nom_MASK, + DeemphGen1Nom[ChannelType] << D0F0xE4_PHY_6006_DeemphGen1Nom_OFFSET, + FALSE, + Pcie + ); + PcieRegisterRMW ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, Phy, D0F0xE4_PHY_6006_ADDRESS + PhyLane * 0x80), + 0x00FF000, + ReqdInitValLo[ChannelType] << 16, + FALSE, + Pcie + ); + PcieRegisterRMW ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, Phy, D0F0xE4_PHY_6006_ADDRESS + PhyLane * 0x80), + 0xFF000000, + ReqdInitValHi[ChannelType] << 24, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * DCC recalibration + * + * + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] Pcie Pointer to global PCIe configuration + */ + +AGESA_STATUS +PciePhyForceDccRecalibration ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Phy; + UINT8 PhyLane; + for (Phy = 0; Phy < Wrapper->NumberOfPIFs; Phy++) { + for (PhyLane = 0; PhyLane < MAX_NUM_LANE_PER_PHY; PhyLane++) { + PcieRegisterWriteField ( + Wrapper, + PHY_SPACE (Wrapper->WrapId, Phy, D0F0xE4_PHY_4001_ADDRESS + PhyLane * 0x80), + D0F0xE4_PHY_4001_ForceDccRecalc_OFFSET, + D0F0xE4_PHY_4001_ForceDccRecalc_WIDTH, + 0x1, + FALSE, + Pcie + ); + } + } + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h new file mode 100755 index 0000000000..b07437b8fd --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEPHYSERVICES_H_ +#define _PCIEPHYSERVICES_H_ + +VOID +PciePhyApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyAvertClockPickers ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyChannelCharacteristic ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PciePhyForceDccRecalibration ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c new file mode 100755 index 0000000000..358dbe7dff --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c @@ -0,0 +1,627 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPIFSERVICES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define PIF_GANG_0to1 0x1 +#define PIF_GANG_2to3 (0x1 << 1) +#define PIF_GANG_4to5 (0x1 << 2) +#define PIF_GANG_6to7 (0x1 << 3) +#define PIF_GANG_0to3 (0x1 << 4) +#define PIF_GANG_4to7 (0x1 << 8) +#define PIF_GANG_0to7 (0x1 << 9) +#define PIF_GANG_ALL (0x1 << 25) + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Apply PIF ganging for all lanes for given wrapper + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + + +VOID +PciePifApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 LaneBitmap; + UINT8 Pif; + D0F0xE4_PIF_0011_STRUCT D0F0xE4_PIF_0011[2]; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifApplyGanging Enter\n"); + LibAmdMemFill (&D0F0xE4_PIF_0011, 0, sizeof (D0F0xE4_PIF_0011), GnbLibGetHeader (Pcie)); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + LaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, EngineList); + switch (LaneBitmap) { + case 0x0003: + D0F0xE4_PIF_0011[0].Field.X2Lane10 = 0x1; + break; + case 0x000c: + D0F0xE4_PIF_0011[0].Field.X2Lane32 = 0x1; + break; + case 0x0030: + D0F0xE4_PIF_0011[0].Field.X2Lane54 = 0x1; + break; + case 0x00c0: + D0F0xE4_PIF_0011[0].Field.X2Lane76 = 0x1; + break; + case 0x000f: + D0F0xE4_PIF_0011[0].Field.X4Lane30 = 0x1; + break; + case 0x00f0: + D0F0xE4_PIF_0011[0].Field.X4Lane74 = 0x1; + break; + case 0x00ff: + D0F0xE4_PIF_0011[0].Field.X8Lane70 = 0x1; + break; + case 0x0300: + D0F0xE4_PIF_0011[1].Field.X2Lane10 = 1; + break; + case 0x0c00: + D0F0xE4_PIF_0011[1].Field.X2Lane32 = 0x1; + break; + case 0x3000: + D0F0xE4_PIF_0011[1].Field.X2Lane54 = 0x1; + break; + case 0xc000: + D0F0xE4_PIF_0011[1].Field.X2Lane76 = 0x1; + break; + case 0x0f00: + D0F0xE4_PIF_0011[1].Field.X4Lane30 = 0x1; + break; + case 0xf000: + D0F0xE4_PIF_0011[1].Field.X4Lane74 = 0x1; + break; + case 0xff00: + D0F0xE4_PIF_0011[1].Field.X8Lane70 = 0x1; + break; + case 0xffff: + D0F0xE4_PIF_0011[0].Field.MultiPif = 0x1; + D0F0xE4_PIF_0011[1].Field.MultiPif = 0x1; + break; + default: + break; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0011_ADDRESS), + D0F0xE4_PIF_0011[Pif].Value, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifApplyGanging Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL powerdown + * + * + * @param[in] LaneBitmap Power down PLL for these lanes + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllPowerDown ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + UINT16 NibbleBitmap; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllPowerDown Enter\n"); + for (Nibble = 0; Nibble < 4; Nibble++) { + NibbleBitmap = (0xF << (Nibble * 4)); + if ((LaneBitmap & NibbleBitmap) == NibbleBitmap) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateOff; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllPowerDown Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL init for DDI + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllInitForDdi ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + UINT32 LaneBitmap; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllInitForDdi Enter\n"); + LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_DDI_PHY_NATIVE, 0, Wrapper); + for (Nibble = 0; Nibble < 4; Nibble++) { + if (LaneBitmap & (0xF << (Nibble * 4))) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x2; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PIF_0012.Value, + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllInitForDdi Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll for on PIF to indicate action completion + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePollPifForCompeletion ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + UINT8 Pif; + D0F0xE4_PIF_0015_STRUCT D0F0xE4_PIF_0015; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + do { + D0F0xE4_PIF_0015.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0015_ADDRESS), + Pcie + ); + if (TIMESTAMPS_DELTA (TimeStamp, PcieTimerGetTimeStamp (Pcie)) > 100) { + break; + } + } while ((D0F0xE4_PIF_0015.Value & 0xff) != 0xff); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable fifo reset + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + + +VOID +PciePifDisableFifoReset ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_RxDetectFifoResetMode_OFFSET, + D0F0xE4_PIF_0010_RxDetectFifoResetMode_WIDTH, + 0, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program LS2 exit time + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePifSetLs2ExitTime ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetLs2ExitTime Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_Ls2ExitTime_OFFSET, + D0F0xE4_PIF_0010_Ls2ExitTime_WIDTH, + 0x0, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetLs2ExitTime Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set PLL mode for L1 + * + * + * @param[in] LaneBitmap Power down PLL for these lanes + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifSetPllModeForL1 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + for (Nibble = 0; Nibble < 4; Nibble++) { + if (LaneBitmap & (0xF << (Nibble * 4))) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + Pcie + ); + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x1; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program receiver detection power mode + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePifSetRxDetectPowerMode ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetRxDetectPowerMode Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_RxDetectTxPwrMode_OFFSET, + D0F0xE4_PIF_0010_RxDetectTxPwrMode_WIDTH, + 0x1, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetRxDetectPowerMode Enter\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Pll ramp up time + * + * + * + * @param[in] Rampup Ramp up time + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePifSetPllRampTime ( + IN PCIE_PLL_RAMPUP_TIME Rampup, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + D0F0xE4_PIF_0013_STRUCT D0F0xE4_PIF_0013; + D0F0xE4_PIF_0010_STRUCT D0F0xE4_PIF_0010; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetPllRampTime Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + Pcie + ); + D0F0xE4_PIF_0013.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + Pcie + ); + D0F0xE4_PIF_0010.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + Pcie + ); + if (Rampup == NormalRampup) { + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x1; + D0F0xE4_PIF_0013.Field.PllRampUpTime = 0x1; + D0F0xE4_PIF_0010.Field.Ls2ExitTime = 0x0; + } else { + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x3; + D0F0xE4_PIF_0013.Field.PllRampUpTime = 0x3; + D0F0xE4_PIF_0010.Field.Ls2ExitTime = 0x6; + } + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012.Value, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + D0F0xE4_PIF_0013.Value, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010.Value, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetPllRampTime Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down PIFs + * + * + * + * @param[in] Control Power up or Power down control + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePifPllPowerControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + UINT8 PllPowerStateInOff; + PllPowerStateInOff = (Control == PowerDownPifs) ? PifPowerStateOff : PifPowerStateL0; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012_PllPowerStateInOff_OFFSET, + D0F0xE4_PIF_0012_PllPowerStateInOff_WIDTH, + PllPowerStateInOff, + FALSE, + Pcie + ); + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + D0F0xE4_PIF_0013_PllPowerStateInOff_OFFSET, + D0F0xE4_PIF_0013_PllPowerStateInOff_WIDTH, + PllPowerStateInOff, + FALSE, + Pcie + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down PIFs + * + * + * + * @param[in] Control Power up/Down control + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePifFullPowerStateControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + D0F0xE4_PIF_0013_STRUCT D0F0xE4_PIF_0013; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + Pcie + ); + D0F0xE4_PIF_0013.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + Pcie + ); + if (Control == PowerDownPifs) { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.RxPowerStateInRxs2 = PifPowerStateOff; + } else { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateL0; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateL0; + D0F0xE4_PIF_0013.Field.PllPowerStateInOff = PifPowerStateLS2; + D0F0xE4_PIF_0013.Field.PllPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0013.Field.TxPowerStateInTxs2 = PifPowerStateL0; + D0F0xE4_PIF_0013.Field.RxPowerStateInRxs2 = PifPowerStateL0; + } + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012.Value, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + D0F0xE4_PIF_0013.Value, + FALSE, + Pcie + ); + } +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h new file mode 100755 index 0000000000..4e59d1a9cb --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h @@ -0,0 +1,120 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEPIFSERVICES_H_ +#define _PCIEPIFSERVICES_H_ + +VOID +PciePifApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllPowerDown ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllInitForDdi ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePollPifForCompeletion ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifDisableFifoReset ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetLs2ExitTime ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetPllModeForL1 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetRxDetectPowerMode ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetPllRampTime ( + IN PCIE_PLL_RAMPUP_TIME Rampup, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllPowerControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifFullPowerStateControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c new file mode 100755 index 0000000000..d13bf142db --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c @@ -0,0 +1,230 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe port indirect register + * space. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "PciePortRegAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPORTREGACC_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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe port indirect register. + * + * Support for unify register access through index/data pair on PCIe port + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] Pcie Pointer to internal configuration data area + * @retval Register Value + */ + +UINT32 +PciePortRegisterRead ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + GnbLibPciWrite (Engine->Type.Port.Address.AddressValue | 0xE0, AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciRead (Engine->Type.Port.Address.AddressValue | 0xE4, AccessWidth32, &Value, GnbLibGetHeader (Pcie)); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe Port Indirect register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] Value New register value + * @param[in] S3Save Save for S3 flag + * @param[in] Pcie Pointer to internal configuration data area + */ +VOID +PciePortRegisterWrite ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + ASSERT (S3Save == TRUE || S3Save == FALSE); + + IDS_HDT_CONSOLE (PCIE_PORTREG_TRACE, " *WR PCIEIND_P (%d:%d:%d):0x%04x = 0x%08x\n", + Engine->Type.Port.Address.Address.Bus, + Engine->Type.Port.Address.Address.Device, + Engine->Type.Port.Address.Address.Function, + Address, + Value + ); + GnbLibPciWrite (Engine->Type.Port.Address.AddressValue | 0xE0, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciWrite (Engine->Type.Port.Address.AddressValue | 0xE4, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Value, GnbLibGetHeader (Pcie)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe Port Indirect register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] S3Save Save for S3 flag + * @param[in] Value New register value + * @param[in] Pcie Pointer to internal configuration data area + */ + +VOID +PciePortRegisterWriteField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Data; + UINT32 Mask; + Data = PciePortRegisterRead (Engine, Address, Pcie); + Mask = (1 << FieldWidth) - 1; + Value &= Mask; + Data &= (~(Mask << FieldOffset)); + PciePortRegisterWrite (Engine, Address, Data | (Value << FieldOffset), S3Save, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe Port Indirect register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Pcie Pointer to internal configuration data area + * @retval Register Field Value. + */ + +UINT32 +PciePortRegisterReadField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PciePortRegisterRead (Engine, Address, Pcie); + Value = (Value >> FieldOffset) & ((1 << FieldWidth) - 1); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCIe port register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] AndMask Value & (~AndMask) + * @param[in] OrMask Value | OrMask + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePortRegisterRMW ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PciePortRegisterRead (Engine, Address, Pcie); + Value = (Value & (~AndMask)) | OrMask; + PciePortRegisterWrite (Engine, Address, Value, S3Save, Pcie); +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h new file mode 100755 index 0000000000..169a7353be --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h @@ -0,0 +1,94 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe port indirect register space. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEPORTREGACC_H_ +#define _PCIEPORTREGACC_H_ + +UINT32 +PciePortRegisterRead ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterWrite ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterWriteField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PciePortRegisterReadField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterRMW ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c new file mode 100755 index 0000000000..7eb5459b09 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c @@ -0,0 +1,511 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPORTSERVICES_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Set completion timeout + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieCompletionTimeout ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x80_ADDRESS, + AccessWidth32, + 0xffffffff, + 0x6 << DxF0x80_CplTimeoutValue_OFFSET, + GnbLibGetHeader (Pcie) + ); + if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + PciePortRegisterWriteField ( + Engine, + DxF0xE4_x20_ADDRESS, + DxF0xE4_x20_TxFlushTlpDis_OFFSET, + DxF0xE4_x20_TxFlushTlpDis_WIDTH, + 0x0, + TRUE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init hotplug port + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkInitHotplug ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + DxF0xE4_xB5_STRUCT DxF0xE4_xB5; + if ((Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced) || (Engine->Type.Port.PortData.LinkHotplug == HotplugInboard)) { + DxF0xE4_xB5.Value = PciePortRegisterRead (Engine, DxF0xE4_xB5_ADDRESS, Pcie); + DxF0xE4_xB5.Field.LcEhpRxPhyCmd = 0x3; + DxF0xE4_xB5.Field.LcEhpTxPhyCmd = 0x3; + DxF0xE4_xB5.Field.LcEnhancedHotPlugEn = 0x1; + PciePortRegisterWrite ( + Engine, + DxF0xE4_xB5_ADDRESS, + DxF0xE4_xB5.Value, + TRUE, + Pcie + ); + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (Engine), + CORE_SPACE (Engine->Type.Port.CoreId, 0x10), + 1, + 3, + 0x5, + TRUE, + Pcie + ); + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (Engine), + WRAP_SPACE (PcieConfigGetParentWrapper (Engine)->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + D0F0xE4_WRAP_8011_RcvrDetClkEnable_OFFSET, + D0F0xE4_WRAP_8011_RcvrDetClkEnable_WIDTH, + 0x1, + TRUE, + Pcie + ); + } + if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x6C_ADDRESS, + AccessS3SaveWidth32, + 0xffffffff, + 1 << DxF0x6C_HotplugCapable_OFFSET, + GnbLibGetHeader (Pcie) + ); + PciePortRegisterWriteField ( + Engine, + DxF0xE4_x20_ADDRESS, + DxF0xE4_x20_TxFlushTlpDis_OFFSET, + DxF0xE4_x20_TxFlushTlpDis_WIDTH, + 0x0, + TRUE, + Pcie + ); + PciePortRegisterWriteField ( + Engine, + DxF0xE4_x70_ADDRESS, + DxF0xE4_x70_RxRcbCplTimeoutMode_OFFSET, + DxF0xE4_x70_RxRcbCplTimeoutMode_WIDTH, + 0x1, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set misc slot capability + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkSetSlotCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x58_ADDRESS, + AccessWidth32, + 0xffffffff, + 1 << DxF0x58_SlotImplemented_OFFSET, + GnbLibGetHeader (Pcie) + ); + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x3C_ADDRESS, + AccessWidth32, + 0xffffffff, + 1 << DxF0x3C_IntPin_OFFSET, + GnbLibGetHeader (Pcie) + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Safe mode to force link advertize Gen1 only capability in TS + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkSafeMode ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + //Engine->Type.Port.PortData.LinkSpeedCapability = PcieGen1; + PcieSetLinkSpeedCap (PcieGen1, Engine, Pcie); + PciePortRegisterRMW ( + Engine, + DxF0xE4_xA2_ADDRESS, + DxF0xE4_xA2_LcUpconfigureDis_MASK, + (1 << DxF0xE4_xA2_LcUpconfigureDis_OFFSET), + FALSE, + Pcie + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set current link speed + * + * + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieSetLinkWidthCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PciePortRegisterRMW ( + Engine, + DxF0xE4_xA2_ADDRESS, + DxF0xE4_xA2_LcUpconfigureDis_MASK, + 0, + FALSE, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set current link speed + * + * + * @param[in] LinkSpeedCapability Link Speed Capability + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieSetLinkSpeedCap ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + DxF0xE4_xA4_STRUCT DxF0xE4_xA4; + DxF0xE4_xC0_STRUCT DxF0xE4_xC0; + DxF0x88_STRUCT DxF0x88; + GnbLibPciRead ( + Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, + AccessWidth32, + &DxF0x88.Value, + GnbLibGetHeader (Pcie) + ); + DxF0xE4_xA4.Value = PciePortRegisterRead ( + Engine, + DxF0xE4_xA4_ADDRESS, + Pcie + ); + DxF0xE4_xC0.Value = PciePortRegisterRead ( + Engine, + DxF0xE4_xC0_ADDRESS, + Pcie + ); + + switch (LinkSpeedCapability) { + case PcieGen2: + DxF0xE4_xA4.Field.LcGen2EnStrap = 0x1; + DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x1; + DxF0xE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x0; + DxF0x88.Field.TargetLinkSpeed = 0x2; + DxF0x88.Field.HwAutonomousSpeedDisable = 0x0; + break; + case PcieGen1: + DxF0xE4_xA4.Field.LcGen2EnStrap = 0x0; + DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x0; + DxF0xE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x1; + DxF0x88.Field.TargetLinkSpeed = 0x1; + DxF0x88.Field.HwAutonomousSpeedDisable = 0x1; + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (Engine), + WRAP_SPACE (PcieConfigGetParentWrapper (Engine)->WrapId, D0F0xE4_WRAP_0803_ADDRESS + 0x100 * Engine->Type.Port.PortId), + D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_OFFSET, + D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_WIDTH, + 0, + FALSE, + Pcie + ); + break; + default: + ASSERT (FALSE); + break; + } + PciePortRegisterWrite ( + Engine, + DxF0xE4_xA4_ADDRESS, + DxF0xE4_xA4.Value, + FALSE, + Pcie + ); + PciePortRegisterWrite ( + Engine, + DxF0xE4_xC0_ADDRESS, + DxF0xE4_xC0.Value, + FALSE, + Pcie + ); + GnbLibPciWrite ( + Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, + AccessWidth32, + &DxF0x88.Value, + GnbLibGetHeader (Pcie) + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Force compliance + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieForceCompliance ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (Engine->Type.Port.PortData.LinkSpeedCapability >= PcieGen2) { + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, + AccessWidth32, + 0xffffffff, + 0x1 << DxF0x88_EnterCompliance_OFFSET, + GnbLibGetHeader (Pcie) + ); + } else if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGen1) { + PciePortRegisterWriteField ( + Engine, + DxF0xE4_xC0_ADDRESS, + DxF0xE4_xC0_StrapForceCompliance_OFFSET, + DxF0xE4_xC0_StrapForceCompliance_WIDTH, + 0x1, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set slo power limit + * + * + * + * @param[in] Engine Pointer to engine configuration + * @param[in] Pcie Pointer to PCIe configuration + */ + + +VOID +PcieEnableSlotPowerLimit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + ASSERT (Engine->EngineData.EngineType == PciePortEngine); + if (PcieLibIsEngineAllocated (Engine) && Engine->Type.Port.PortData.PortPresent != PortDisabled && !PcieConfigIsSbPcieEngine (Engine)) { + IDS_HDT_CONSOLE (PCIE_MISC, " Enable Slot Power Limit for Port % d\n", Engine->Type.Port.Address.Address.Device); + GnbLibPciIndirectRMW ( + MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), + (D0F0x64_x51_ADDRESS + (Engine->Type.Port.Address.Address.Device - 2) * 2) | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0xffffffff, + 1 << D0F0x64_x51_SetPowEn_OFFSET, + GnbLibGetHeader (Pcie) + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable ASPM + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieEnableAspm ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (Engine->Type.Port.PortData.LinkAspm != AspmDisabled) { + if (PcieConfigIsSbPcieEngine (Engine)) { + SbPcieLinkAspmControl (Engine, Pcie); + } else { + PcieLinkAspmEnable ( + Engine->Type.Port.Address, + Engine->Type.Port.PortData.LinkAspm, + GnbLibGetHeader (Pcie) + ); + } + } +} + + +UINT8 L1State = 0x1b; +/*----------------------------------------------------------------------------------------*/ +/** + * Poll for link to get into L1 + * + * + * + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePollLinkForL1Entry ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[8]; + do { + PcieUtilGetLinkHwStateHistory (Engine, &LinkHwStateHistory[0], sizeof (LinkHwStateHistory), Pcie); + } while (!PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), &L1State, sizeof (L1State))); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll for link to get into L1 + * + * + * + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePollLinkForL0Exit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[4]; + do { + PcieUtilGetLinkHwStateHistory (Engine, &LinkHwStateHistory[0], sizeof (LinkHwStateHistory), Pcie); + } while (LinkHwStateHistory[0] != 0x10); +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h new file mode 100755 index 0000000000..582ba18efe --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h @@ -0,0 +1,118 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEPORTSERVICES_H_ +#define _PCIEPORTSERVICES_H_ + + +VOID +PcieSetLinkSpeedCap ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetLinkWidthCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkSafeMode ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieCompletionTimeout ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkSetSlotCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkInitHotplug ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieForceCompliance ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieEnableSlotPowerLimit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieEnableAspm ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePollLinkForL1Entry ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePollLinkForL0Exit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.c new file mode 100755 index 0000000000..d66d6afbe7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.c @@ -0,0 +1,391 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Power saving features/services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPOWERMGMT_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down unused lanes and plls + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePwrPowerDownUnusedLanes ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 UnusedLanes; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanes Enter\n"); + if (Wrapper->Features.PowerOffUnusedLanes != 0) { + UnusedLanes = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE, Wrapper); + PcieTopologyLaneControl ( + DisableLanes, + UnusedLanes, + Wrapper, + Pcie + ); + } + if (Wrapper->Features.PowerOffUnusedPlls != 0) { + UnusedLanes = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_PHY_NATIVE_ALL, LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE | LANE_TYPE_DDI_PHY_NATIVE_ACTIVE, Wrapper); + PciePifPllPowerDown ( + UnusedLanes, + Wrapper, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanes Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Lane bitmam to enable PLL power down in L1 + * + * + * @param[in] PllPowerUpLatency Pointer to wrapper config descriptor + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Lane bitmap for which PLL can be powered down in L1 + */ + +UINT32 +PcieLanesToPowerDownPllInL1 ( + IN UINT8 PllPowerUpLatency, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LaneGroupExitLatency [4]; + UINT32 LaneBitmapForPllOffInL1; + PCIe_ENGINE_CONFIG *EngineList; + UINTN Index; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieLanesToPowerDownPllInL1 Enter\n"); + LaneBitmapForPllOffInL1 = 0; + if (PcieUtilGetWrapperLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE | LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG, 0, Wrapper) != 0) { + if (Wrapper->Features.PllOffInL1 != 0) { + LibAmdMemFill (&LaneGroupExitLatency[0], 0xFF, sizeof (LaneGroupExitLatency), GnbLibGetHeader (Pcie)); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + PCIe_ASPM_LATENCY_INFO LinkLatencyInfo; + UINT32 ActiveLanesBitmap; + UINT32 HotplugLanesBitmap; + if (EngineList->EngineData.EngineType == PciePortEngine) { + LinkLatencyInfo.MaxL1ExitLatency = 0; + LinkLatencyInfo.MaxL0sExitLatency = 0; + ActiveLanesBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE, 0, EngineList); + HotplugLanesBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG, 0, EngineList); + if (ActiveLanesBitmap != 0 && HotplugLanesBitmap == 0 && !PcieConfigIsSbPcieEngine (EngineList)) { + PcieAspmGetMaxExitLatency (EngineList->Type.Port.Address, &LinkLatencyInfo, GnbLibGetHeader (Pcie)); + } + if (HotplugLanesBitmap != 0 || PcieConfigIsSbPcieEngine (EngineList)) { + LinkLatencyInfo.MaxL1ExitLatency = 0xff; + } + IDS_HDT_CONSOLE (GNB_TRACE, " Engine %d Active Lanes 0x%x, Hotplug Lanes 0x%x\n", EngineList->Type.Port.NativeDevNumber, ActiveLanesBitmap, HotplugLanesBitmap); + for (Index = 0; Index < 4; Index++) { + if ((ActiveLanesBitmap & (0xF << (Index * 4))) != 0) { + if (LaneGroupExitLatency [Index] > LinkLatencyInfo.MaxL1ExitLatency) { + IDS_HDT_CONSOLE (GNB_TRACE, " Index %d Latency %d\n", Index, LinkLatencyInfo.MaxL1ExitLatency); + LaneGroupExitLatency [Index] = LinkLatencyInfo.MaxL1ExitLatency; + } + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + LaneBitmapForPllOffInL1 = 0; + for (Index = 0; Index < 4; Index++) { + IDS_HDT_CONSOLE (GNB_TRACE, " Index %d Final Latency %d\n", Index, LaneGroupExitLatency[Index]); + if (LaneGroupExitLatency[Index] > PllPowerUpLatency) { + LaneBitmapForPllOffInL1 |= (0xF << (Index * 4)); + } + } + } + } + IDS_HDT_CONSOLE (GNB_TRACE, " Lane bitmap %04x\n", LaneBitmapForPllOffInL1); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieLanesToPowerDownPllInL1 Exit\n"); + return LaneBitmapForPllOffInL1; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Auto-Power Down electrical Idle detector + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePwrAutoPowerDownElectricalIdleDetector ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrAutoPowerDownElectricalIdleDetector Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_EiDetCycleMode_OFFSET, + D0F0xE4_PIF_0010_EiDetCycleMode_WIDTH, + 0x0, + TRUE, + Pcie + ); + + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_EiCycleOffTime_OFFSET, + D0F0xE4_PIF_0010_EiCycleOffTime_WIDTH, + 0x2, + TRUE, + Pcie + ); + + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_EiDetCycleMode_OFFSET, + D0F0xE4_PIF_0010_EiDetCycleMode_WIDTH, + 0x1, + TRUE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrAutoPowerDownElectricalIdleDetector Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Clock gating + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePwrClockGating ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8011_STRUCT D0F0xE4_WRAP_8011; + D0F0xE4_WRAP_8012_STRUCT D0F0xE4_WRAP_8012; + D0F0xE4_WRAP_8014_STRUCT D0F0xE4_WRAP_8014; + D0F0xE4_WRAP_8015_STRUCT D0F0xE4_WRAP_8015; + D0F0xE4_WRAP_8016_STRUCT D0F0xE4_WRAP_8016; + UINT8 CoreId; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrClockGating Enter\n"); + D0F0xE4_WRAP_8014.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8014_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8015.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8015_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8012.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8012_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8011.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + Pcie + ); + + if (Wrapper->Features.ClkGating == 0x1) { + D0F0xE4_WRAP_8014.Field.TxclkPermGateEnable = 0x1; + D0F0xE4_WRAP_8014.Field.TxclkPrbsGateEnable = 0x1; + + D0F0xE4_WRAP_8014.Field.PcieGatePifA1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifB1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifC1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifD1xEnable = 0x1; + + D0F0xE4_WRAP_8014.Field.PcieGatePifA2p5xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifB2p5xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifC2p5xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifD2p5xEnable = 0x1; + + + D0F0xE4_WRAP_8011.Field.TxclkDynGateEnable = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkRegsGateEnable = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkLcntGateEnable = 0x1; + D0F0xE4_WRAP_8011.Field.RcvrDetClkEnable = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkPermGateEven = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkDynGateLatency = 0x3f; + D0F0xE4_WRAP_8011.Field.TxclkRegsGateLatency = 0x3f; + D0F0xE4_WRAP_8011.Field.TxclkPermGateLatency = 0x3f; + + D0F0xE4_WRAP_8012.Field.Pif2p5xIdleResumeLatency = 0x7; + D0F0xE4_WRAP_8012.Field.Pif2p5xIdleGateEnable = 0x1; + D0F0xE4_WRAP_8012.Field.Pif2p5xIdleGateLatency = 0x1; + D0F0xE4_WRAP_8012.Field.Pif1xIdleResumeLatency = 0x7; + D0F0xE4_WRAP_8012.Field.Pif1xIdleGateEnable = 0x1; + D0F0xE4_WRAP_8012.Field.Pif1xIdleGateLatency = 0x1; + + D0F0xE4_WRAP_8015.Field.RefclkBphyGateEnable = 0x1; + D0F0xE4_WRAP_8015.Field.RefclkBphyGateLatency = 0x0; + D0F0xE4_WRAP_8015.Field.RefclkRegsGateEnable = 0x1; + D0F0xE4_WRAP_8015.Field.RefclkRegsGateLatency = 0x3f; + + D0F0xE4_WRAP_8014.Field.DdiGateDigAEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGateDigBEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifA1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifB1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifC1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifD1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifA2p5xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifB2p5xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifC2p5xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.DdiGatePifD2p5xEnable = 0x1; + } + if (Wrapper->Features.TxclkGatingPllPowerDown == 0x1) { + D0F0xE4_WRAP_8014.Field.TxclkPermGateOnlyWhenPllPwrDn = 0x1; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8014_ADDRESS), + D0F0xE4_WRAP_8014.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8015_ADDRESS), + D0F0xE4_WRAP_8015.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8012_ADDRESS), + D0F0xE4_WRAP_8012.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + D0F0xE4_WRAP_8011.Value, + TRUE, + Pcie + ); + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + PcieRegisterWriteField ( + Wrapper, + CORE_SPACE (CoreId, D0F0xE4_CORE_0011_ADDRESS), + D0F0xE4_CORE_0011_DynClkLatency_OFFSET, + D0F0xE4_CORE_0011_DynClkLatency_WIDTH, + 0xf, + TRUE, + Pcie + ); + } + if (Wrapper->Features.LclkGating == 0x1) { + D0F0xE4_WRAP_8016.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8016_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8016.Field.LclkDynGateEnable = 0x1; + D0F0xE4_WRAP_8016.Field.LclkGateFree = 0x1; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8016_ADDRESS), + D0F0xE4_WRAP_8016.Value, + TRUE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrClockGating Exit\n"); +} + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h new file mode 100755 index 0000000000..429edcdf18 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h @@ -0,0 +1,74 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Power saving features/services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEPOWERSAVINGFEATURES_H_ +#define _PCIEPOWERSAVINGFEATURES_H_ + + +VOID +PciePwrPowerDownUnusedLanes ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieLanesToPowerDownPllInL1 ( + IN UINT8 PllPowerUpLatency, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrAutoPowerDownElectricalIdleDetector ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrClockGating ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.c new file mode 100755 index 0000000000..5c55dbbc4a --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.c @@ -0,0 +1,254 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific PCIe complex initialization services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIESILICONSERVICES_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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Gen1 voltage Index + * + * + * + * + * @param[in] StdHeader Standard configuration header + */ +UINT8 +PcieSiliconGetGen1VoltageIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + UINT8 Gen1VidIndex; + UINT8 SclkVidArray[4]; + GnbLibPciRead ( + MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), + AccessWidth32, + &SclkVidArray[0], + StdHeader + ); + Gen1VidIndex = 0; + for (Index = 0; Index < 4; Index++) { + if (SclkVidArray[Index] > SclkVidArray[Gen1VidIndex]) { + Gen1VidIndex = Index; + } + } + return Gen1VidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Request Pcie voltage change + * + * + * + * @param[in] VidIndex The request VID index + * @param[in] StdHeader Standard configuration header + */ +VOID +PcieSiliconRequestVoltage ( + IN UINT8 VidIndex, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + D0F0x64_x6A_STRUCT D0F0x64_x6A; + D0F0x64_x6B_STRUCT D0F0x64_x6B; + + //Enable voltage client + GnbLibPciIndirectRead ( + MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), + D0F0x64_x6A_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + &D0F0x64_x6A.Value, + StdHeader + ); + + D0F0x64_x6A.Field.VoltageChangeEn = 0x1; + + GnbLibPciIndirectWrite ( + MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), + D0F0x64_x6A_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + &D0F0x64_x6A.Value, + StdHeader + ); + + D0F0x64_x6A.Field.VoltageLevel = VidIndex; + D0F0x64_x6A.Field.VoltageChangeReq = !D0F0x64_x6A.Field.VoltageChangeReq; + + GnbLibPciIndirectWrite ( + MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), + D0F0x64_x6A_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + &D0F0x64_x6A.Value, + StdHeader + ); + do { + GnbLibPciIndirectRead ( + MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), + D0F0x64_x6B_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + &D0F0x64_x6B.Value, + StdHeader + ); + } while (D0F0x64_x6A.Field.VoltageChangeReq != D0F0x64_x6B.Field.VoltageChangeAck); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Unhide all ports + * + * + * + * @param[in] Silicon Pointer to silicon configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieSiliconUnHidePorts ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x0C_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + ~(UINT32)(BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7), + 0x0, + GnbLibGetHeader (Pcie) + ); + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x00_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + ~(UINT32)BIT6, + BIT6, + GnbLibGetHeader (Pcie) + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Hide unused ports + * + * + * + * @param[in] Silicon Pointer to silicon configuration data area + * @param[in] Pcie Pointer to data area up to 256 byte + */ + +VOID +PcieSiliconHidePorts ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0x64_x0C_STRUCT D0F0x64_x0C; + PCIe_WRAPPER_CONFIG *WrapperList; + D0F0x64_x0C.Value = 0; + WrapperList = PcieConfigGetChildWrapper (Silicon); + while (WrapperList != NULL) { + PCIe_ENGINE_CONFIG *EngineList; + EngineList = PcieConfigGetChildEngine (WrapperList); + while (EngineList != NULL) { + if (EngineList->EngineData.EngineType == PciePortEngine) { + if (!PcieConfigCheckPortStatus (EngineList, INIT_STATUS_PCIE_TRAINING_SUCCESS) && + ((EngineList->Type.Port.PortData.LinkHotplug == HotplugDisabled) || (EngineList->Type.Port.PortData.LinkHotplug == HotplugInboard)) && + !PcieConfigIsSbPcieEngine (EngineList)) { + D0F0x64_x0C.Value |= 1 << EngineList->Type.Port.NativeDevNumber; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + WrapperList = PcieLibGetNextDescriptor (WrapperList); + } + + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x0C_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + ~(UINT32)(BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7), + D0F0x64_x0C.Value, + GnbLibGetHeader (Pcie) + ); + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x00_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + ~(UINT32)BIT6, + 0x0, + GnbLibGetHeader (Pcie) + ); +} + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h new file mode 100755 index 0000000000..a937dbed2d --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h @@ -0,0 +1,72 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Complex Services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIESILICONSERVICES_H_ +#define _PCIESILICONSERVICES_H_ + +UINT8 +PcieSiliconGetGen1VoltageIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieSiliconRequestVoltage ( + IN UINT8 VidIndex, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieSiliconUnHidePorts ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSiliconHidePorts ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSmuLib.esl b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSmuLib.esl new file mode 100755 index 0000000000..18709ed55e --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSmuLib.esl @@ -0,0 +1,248 @@ +/** + * @file + * + * ALIB PSPP Pcie Smu Lib V1 + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49911 $ @e \$Date: 2011-03-30 17:43:29 +0800 (Wed, 30 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + /*----------------------------------------------------------------------------------------*/ + /** + * SMU indirect register read + * + * Arg0 - Smu register offset + * + */ + Method (procNbSmuIndirectRegisterRead, 1, NotSerialized) { + Store (procIndirectRegisterRead (0x0, 0x60, 0xCD), Local0) + // Access 32 bit width + Increment (Arg0) + // Reverse ReqToggle + Or (And (Local0, 0xFEFFFFFF), And (Not (And (Local0, 0x01000000)), 0x01000000),Local0) + // Assign Address and ReqType = 0 + Or (And (Local0, 0xFD00FFFF), ShiftLeft (Arg0, 16), Local0) + + procIndirectRegisterWrite (0x0, 0x60, 0xCD, Local0) + + Store (procIndirectRegisterRead (0x0, 0x60, 0xCE), Local0) + return (Local0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * SMU indirect register Write + * + * Arg0 - Smu register offset + * Arg1 - Value + * Arg2 - Width, 0 = 16, 1 = 32 + * + */ + Method (procNbSmuIndirectRegisterWrite, 3, NotSerialized) { + Store (procIndirectRegisterRead (0x0, 0x60, 0xCD), Local0) + // Get low 16 bit value + Store (And (Arg1, 0xFFFF), Local1) + // Reverse ReqToggle + Or (And (Local0, 0xFEFFFFFF), And (Not (And (Local0, 0x01000000)), 0x01000000),Local0) + // Assign Address + Or (And (Local0, 0xFD000000), ShiftLeft (Arg0, 16), Local0) + // ReqType = 1 + Or (Local0, 0x02000000, Local0) + // Assign Low 16 bit value + Or (Local0, Local1, Local0) + + procIndirectRegisterWrite (0x0, 0x60, 0xCD, Local0) + + if (LEqual (Arg2, 1)) { + // Get high 16 bit value + Store (ShiftRight (Arg1, 16), Local1) + // Reverse ReqToggle + Or (And (Local0, 0xFEFFFFFF), And (Not (And (Local0, 0x01000000)), 0x01000000),Local0) + // Assign Address + Or (And (Local0, 0xFF000000), ShiftLeft (Add (Arg0, 1), 16), Local0) + // Assign High 16 bit value + Or (Local0, Local1, Local0) + + procIndirectRegisterWrite (0x0, 0x60, 0xCD, Local0) + } + + } + + /*----------------------------------------------------------------------------------------*/ + /** + * SMU Service request + * + * Arg0 - Smu service id + * Arg1 - Flags - Poll Ack = 1, Poll down = 2 + * + */ + Method (procNbSmuServiceRequest, 2, NotSerialized) { + Store ("NbSmuServiceRequest Enter", Debug) + Store ("Request id =", Debug) + Store (Arg0, Debug) + + Or (ShiftLeft (Arg0, 3), 0x1, Local0) + procNbSmuIndirectRegisterWrite (0x3, Local0, 1) + + if (LAnd (Arg1, 1)) { + while (LNotEqual (AND(procNbSmuIndirectRegisterRead (0x3), 0x2), 0x2)) { + Store ("--Wait Ack--", Debug) + } + } + if (LAnd (Arg1, 2)) { + while (LNotEqual (AND(procNbSmuIndirectRegisterRead (0x3), 0x4), 0x4)) { + Store ("--Wait Done--", Debug) + } + } + // Clear IRQ register + procNbSmuIndirectRegisterWrite (0x3, 0, 1) + Store ("NbSmuServiceRequest Exit", Debug) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Write RCU register + * + * Arg0 - Register Address + * Arg1 - Register Data + * + */ + Method (procSmuRcuWrite, 2, NotSerialized) { + procNbSmuIndirectRegisterWrite (0xB, Arg0, 0) + procNbSmuIndirectRegisterWrite (0x5, Arg1, 1) + + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Read RCU register + * + * Arg0 - Register Address + * Retval - RCU register value + */ + Method (procSmuRcuRead, 1, NotSerialized) { + procNbSmuIndirectRegisterWrite (0xB, Arg0, 0) + Store (procNbSmuIndirectRegisterRead (0x5), Local0) + return (Local0) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * SMU SRBM Register Read + * + * Arg0 - FCR register address + * + */ + Method (procNbSmuSrbmRegisterRead, 1, NotSerialized) { + //SMUx0B_x8600 + Store (Or (And (Arg0, 0xFF), 0x01865000), Local0) + //SMUx0B_x8604 + Store (Or (And (Arg0, 0xFFFFFF00), 4), Local1) + //SMUx0B_x8608 + Store (Or (ShiftLeft (3, 30), ShiftLeft (1, 18)), Local2) + //Write SMU RCU + procSmuRcuWrite (0x8600, Local0) + procSmuRcuWrite (0x8604, Local1) + procSmuRcuWrite (0x8608, Local2) + // ServiceId + if (LEqual (ShiftRight (Arg0, 16), 0xFE00)) { + procNbSmuServiceRequest (0xD, 0x3) + } + if (LEqual (ShiftRight (Arg0, 16), 0xFE30)) { + procNbSmuServiceRequest (0xB, 0x3) + } + return (procSmuRcuRead(0x8650)) + } + + + /*----------------------------------------------------------------------------------------*/ + /** + * SMU SRBM Register Write + * + * Arg0 - FCR register address + * Arg1 - Value + * + */ + Method (procNbSmuSrbmRegisterWrite, 2, NotSerialized) { + //SMUx0B_x8600 + Store (Or (And (Arg0, 0xFF), 0x01865000), Local0) + //SMUx0B_x8604 + Store (Or (And (Arg0, 0xFFFFFF00), 4), Local1) + //SMUx0B_x8608 + Store (Or (ShiftLeft (3, 30), ShiftLeft (1, 18)), Local2) + Or (Local2, ShiftLeft (1, 16), Local2) + //Write SMU RCU + procSmuRcuWrite (0x8600, Local0) + procSmuRcuWrite (0x8604, Local1) + procSmuRcuWrite (0x8608, Local2) + //Write Data + procSmuRcuWrite (0x8650, Arg1) + // ServiceId + procNbSmuServiceRequest (0xB, 0x3) + } + + /*----------------------------------------------------------------------------------------*/ + /** + * Request VID + * + * Arg0 - VID index + * Arg1 - 0 = do not wait intil voltage is set + * 1 = wait until voltage is set + */ + Method (procPcieSetVoltage, 2, Serialized) { + Store ("PcieSetVoltage Enter", Debug) + Store (procIndirectRegisterRead (0x0, 0x60, 0xEA), Local1) + //Enable voltage change + Or (Local1, 0x2, Local1) + procIndirectRegisterWrite (0x0, 0x60, 0xEA, Local1) + //Clear voltage index + And (Local1, Not (ShiftLeft (0x3, 3)), Local1) + + Store (Concatenate (" Voltage Index:", ToHexString (Arg0), Local6), Debug) + //Set new voltage index + Or (Local1, ShiftLeft (Arg0, 3), Local1) + //Togle request + And (Not (Local1), 0x4, Local2) + Or (And (Local1, Not (0x4)), Local2, Local1) + procIndirectRegisterWrite (0x0, 0x60, 0xEA, Local1) + if (LNotEqual (Arg1, 0)) { + while (LNotEqual (ShiftLeft(Local1, 0x2), Local2)) { + And (procIndirectRegisterRead (0x0, 0x60, 0xEB), 0x1, Local1) + } + } + Store ("PcieSetVoltage Exit", Debug) + } diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c new file mode 100755 index 0000000000..1519e5a727 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c @@ -0,0 +1,100 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe timer access procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIETIMER_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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCIe timer timestamp + * + * + * + * @param[in] Pcie Pointer to internal configuration data area + * @retval Time stamp value + */ + +UINT32 +PcieTimerGetTimeStamp ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_80F0_STRUCT D0F0xE4_WRAP_80F0; + D0F0xE4_WRAP_80F0.Value = PcieRegisterRead ( + (PCIe_WRAPPER_CONFIG *) PcieConfigGetChild (DESCRIPTOR_PCIE_WRAPPER, &Pcie->Header), + WRAP_SPACE (0, D0F0xE4_WRAP_80F0_ADDRESS), + Pcie + ); + return D0F0xE4_WRAP_80F0.Value; +}
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h new file mode 100755 index 0000000000..f636295b5f --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe timer access procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIETIMER_H_ +#define _PCIETIMER_H_ + +UINT32 +PcieTimerGetTimeStamp ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#define TIMESTAMPS_DELTA(Time2, Time1) ((Time2 > Time1) ? (Time2 - Time1) : (0xffffffffull - Time1 + Time2)) + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c new file mode 100755 index 0000000000..370a82511d --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c @@ -0,0 +1,724 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe topology initialization service procedures. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 52794 $ @e \$Date: 2011-05-12 05:52:37 +0800 (Thu, 12 May 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIETOPOLOGYSERVICES_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 + *---------------------------------------------------------------------------------------- + */ +UINT8 +PcieTopologyLocateMuxIndex ( + IN OUT UINT8 *LaneMuxSelectorArrayPtr, + IN UINT8 LaneMuxValue + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Prepare for reconfiguration + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyPrepareForReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; + UINT8 CoreId; + if (PcieLibIsPcieWrapper (Wrapper)) { + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + PcieRegisterWriteField ( + Wrapper, + CORE_SPACE (CoreId, D0F0xE4_CORE_0011_ADDRESS), + D0F0xE4_CORE_0011_DynClkLatency_OFFSET, + D0F0xE4_CORE_0011_DynClkLatency_WIDTH, + 0xf, + FALSE, + Pcie + ); + } + + D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x0; + D0F0xE4_WRAP_8062.Field.BlockOnIdle = 0x0; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + } +} + + +UINT8 LaneMuxSelectorTable[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +/*----------------------------------------------------------------------------------------*/ +/** + * 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 + */ +UINT8 +PcieTopologyLocateMuxIndex ( + IN OUT UINT8 *LaneMuxSelectorArrayPtr, + IN UINT8 LaneMuxValue + ) +{ + UINT8 Index; + for (Index = 0; Index < sizeof (LaneMuxSelectorTable); 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 + */ + +VOID +PcieTopologyApplyLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT8 CurrentPhyLane; + UINT8 CurrentCoreLane; + UINT8 CoreLaneIndex; + UINT8 PhyLaneIndex; + UINT8 NumberOfPhyLane; + UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; + UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; + UINT8 Index; + UINT32 TxMaxSelectorValue; + UINT32 RxMaxSelectorValue; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Enter\n"); + if (PcieLibIsPcieWrapper (Wrapper)) { + EngineList = PcieConfigGetChildEngine (Wrapper); + LibAmdMemCopy ( + &TxLaneMuxSelectorArray[0], + &LaneMuxSelectorTable[0], + sizeof (LaneMuxSelectorTable), + GnbLibGetHeader (Pcie) + ); + LibAmdMemCopy ( + &RxLaneMuxSelectorArray[0], + &LaneMuxSelectorTable[0], + sizeof (LaneMuxSelectorTable), + GnbLibGetHeader (Pcie) + ); + while (EngineList != NULL) { + if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { + CurrentPhyLane = (UINT8) PcieLibGetLoPhyLane (EngineList) - Wrapper->StartPhyLane; + NumberOfPhyLane = (UINT8) PcieConfigGetNumberOfPhyLane (EngineList); + CurrentCoreLane = (UINT8) EngineList->Type.Port.StartCoreLane; + if (PcieUtilIsLinkReversed (FALSE, EngineList, Pcie)) { + CurrentCoreLane = CurrentCoreLane + PcieConfigGetNumberOfCoreLane (EngineList) - NumberOfPhyLane; + } + for (Index = 0; Index < NumberOfPhyLane; Index = Index + 2 ) { + CoreLaneIndex = (CurrentCoreLane + Index) / 2; + PhyLaneIndex = (CurrentPhyLane + Index) / 2; + + if (RxLaneMuxSelectorArray [CoreLaneIndex] != PhyLaneIndex) { + RxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (RxLaneMuxSelectorArray, PhyLaneIndex)] = RxLaneMuxSelectorArray [CoreLaneIndex]; + RxLaneMuxSelectorArray [CoreLaneIndex] = PhyLaneIndex; + } + if (TxLaneMuxSelectorArray [PhyLaneIndex] != CoreLaneIndex) { + TxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (TxLaneMuxSelectorArray, CoreLaneIndex)] = TxLaneMuxSelectorArray [PhyLaneIndex]; + TxLaneMuxSelectorArray [PhyLaneIndex] = CoreLaneIndex; + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + RxMaxSelectorValue = 0; + TxMaxSelectorValue = 0; + for (Index = 0; Index < sizeof (LaneMuxSelectorTable); Index++) { + RxMaxSelectorValue |= (RxLaneMuxSelectorArray[Index] << (Index * 4)); + TxMaxSelectorValue |= (TxLaneMuxSelectorArray[Index] << (Index * 4)); + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS), + TxMaxSelectorValue, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8022_ADDRESS), + RxMaxSelectorValue, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Select master PLL + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieTopologySelectMasterPll ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT16 MasterLane; + UINT16 MasterHotplugLane; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); + MasterLane = 0xFFFF; + MasterHotplugLane = 0xFFFF; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieConfigIsEngineAllocated (EngineList) && PcieConfigIsPcieEngine (EngineList)) { + if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + MasterHotplugLane = PcieConfigGetPcieEngineMasterLane (EngineList); + } else { + MasterLane = PcieConfigGetPcieEngineMasterLane (EngineList); + 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 + ); + + if ( MasterLane <= 3 ) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; + } else if (MasterLane <= 7) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; + } else if (MasterLane <= 11) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; + } else { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x1; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + D0F0xE4_WRAP_8013.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute/clean up reconfiguration + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyExecuteReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; + D0F0xE4_WRAP_8060_STRUCT D0F0xE4_WRAP_8060; + + if (PcieLibIsPcieWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfig Enter\n"); + + PcieTopologyInitSrbmReset (FALSE, Wrapper, Pcie); + + D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8060.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8060_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + D0F0xE4_WRAP_8060.Field.Reconfigure = 0x1; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8060_ADDRESS), + D0F0xE4_WRAP_8060.Value, + FALSE, + Pcie + ); + do { + D0F0xE4_WRAP_8060.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8060_ADDRESS), + Pcie + ); + + } while (D0F0xE4_WRAP_8060.Field.Reconfigure == 1); + 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 + ); + PcieTopologyInitSrbmReset (TRUE, Wrapper, Pcie); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfig Exit\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable lane reversal + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologySetLinkReversal ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Enter\n"); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + if (PcieLibIsPcieEngine (EngineList)) { + if (EngineList->EngineData.StartLane > EngineList->EngineData.EndLane) { + PciePortRegisterWriteField ( + EngineList, + DxF0xE4_xC1_ADDRESS, + DxF0xE4_xC1_StrapReverseLanes_OFFSET, + DxF0xE4_xC1_StrapReverseLanes_WIDTH, + 0x1, + FALSE, + Pcie + ); + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Reduce link width + * + * + * @param[in] LinkWidth Link width + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyReduceLinkWidth ( + IN UINT8 LinkWidth, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_WRAPPER_CONFIG *Wrapper; + UINT32 LinkReversed; + UINT8 DeltaLinkWidthBitmap; + UINT32 LanesToDisable; + Wrapper = PcieConfigGetParentWrapper (Engine); + LinkReversed = PcieUtilIsLinkReversed (TRUE, Engine, Pcie); + + DeltaLinkWidthBitmap = (1 << (PcieConfigGetNumberOfCoreLane (Engine) - LinkWidth)) - 1; + LanesToDisable = (DeltaLinkWidthBitmap << ((LinkReversed == 1) ? Engine->Type.Port.StartCoreLane : (Engine->Type.Port.StartCoreLane + LinkWidth))); + + PcieTopologyLaneControl ( + DisableLanes, + LanesToDisable, + Wrapper, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Lanes enable/disable control + * + * @param[in] Control Lane control action + * @param[in] LaneBitMap Core lanes bitmap + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyLaneControl ( + IN LANE_CONTROL Control, + IN UINT32 LaneBitMap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8023_STRUCT D0F0xE4_WRAP_8023; + D0F0xE4_WRAP_8023.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8023_ADDRESS), + Pcie + ); + + if (Control == EnableLanes) { + D0F0xE4_WRAP_8023.Value |= LaneBitMap; + } else if (Control == DisableLanes) { + D0F0xE4_WRAP_8023.Value &= (~LaneBitMap); + } + D0F0xE4_WRAP_8023.Value &= ((1 << Wrapper->NumberOfLanes) - 1); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8023_ADDRESS), + D0F0xE4_WRAP_8023.Value, + TRUE, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init SRBM reset + * + * @param[in] SrbmResetEnable SRBM reset enable flag. + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyInitSrbmReset ( + IN BOOLEAN SrbmResetEnable, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 pcireg; + UINT32 regmask = 0x7030;; + pcireg = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x8063), + Pcie + ); + if (SrbmResetEnable) { + pcireg |= regmask; + } else { + pcireg &= ~(regmask); + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x8063), + pcireg, + FALSE, + Pcie + ); + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set core configuration according to PCIe port topology + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +PcieTopologySetCoreConfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CoreId; + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + if (PcieLibIsPcieWrapper (Wrapper)) { + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + UINT64 ConfigurationSignature; + UINT8 NewConfigurationValue; + ConfigurationSignature = PcieConfigGetConfigurationSignature (Wrapper, CoreId); + Status = PcieFmGetCoreConfigurationValue (Wrapper, CoreId, ConfigurationSignature, &NewConfigurationValue); + if (Status == AGESA_SUCCESS) { + IDS_HDT_CONSOLE (PCIE_MISC, " Core Configuration: Wrapper [%s], CoreID [%d] - %s\n", + PcieFmDebugGetWrapperNameString (Wrapper), + CoreId, + PcieFmDebugGetCoreConfigurationString (Wrapper, NewConfigurationValue) + ); + PcieRegisterWriteField ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0080_ADDRESS), + D0F0xE4_WRAP_0080_StrapBifLinkConfig_OFFSET, + D0F0xE4_WRAP_0080_StrapBifLinkConfig_WIDTH, + NewConfigurationValue, + FALSE, + Pcie + ); + } else { + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Core Configuration : Wrapper [%s], Signature [0x%x, 0x%x]\n", + PcieFmDebugGetWrapperNameString (Wrapper), + ((UINT32*)&ConfigurationSignature)[1], + ((UINT32*)&ConfigurationSignature)[0] + ); + PcieConfigDisableAllEngines (PciePortEngine | PcieDdiEngine, Wrapper); + } + } + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Relinquish control to DDI for specific lanes + * + * + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieSetDdiOwnPhy ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8040_STRUCT D0F0xE4_WRAP_8040; + UINT32 LaneBitmap; + + if (PcieLibIsDdiWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmSetDdiOwnPhy Enter\n"); + LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_DDI_PHY_NATIVE, 0, Wrapper); + D0F0xE4_WRAP_8040.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8040_ADDRESS), + Pcie + ); + if ((LaneBitmap & BIT0) != 0) { + D0F0xE4_WRAP_8040.Field.OwnPhyA = 0x1; + } + if ((LaneBitmap & BIT4) != 0) { + D0F0xE4_WRAP_8040.Field.OwnPhyB = 0x1; + } + if ((LaneBitmap & BIT8) != 0) { + D0F0xE4_WRAP_8040.Field.OwnPhyC = 0x1; + } + if ((LaneBitmap & BIT12) != 0) { + D0F0xE4_WRAP_8040.Field.OwnPhyD = 0x1; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8040_ADDRESS), + D0F0xE4_WRAP_8040.Value, + FALSE, + Pcie + ); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmSetDdiOwnPhy Exit\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set TX control for PCIe lanes + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieWrapSetTxS1CtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8025_STRUCT D0F0xE4_WRAP_8025; + UINT32 LaneBitmap; + UINTN Index; + D0F0xE4_WRAP_8025.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + Pcie + ); + Index = 0; + LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_SB_CORE_CONFIG, Wrapper); + while (LaneBitmap != 0) { + if ((LaneBitmap & 0xf) != 0) { + D0F0xE4_WRAP_8025.Value &= (~(0xff << (Index * 8))); + D0F0xE4_WRAP_8025.Value |= (((0x03 << 3) | 0x1) << (Index * 8)); + } + LaneBitmap >>= 4; + ++Index; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + D0F0xE4_WRAP_8025.Value, + FALSE, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set TX control for lane muxes + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieWrapSetTxOffCtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + 0x1f1f1f1f, + FALSE, + Pcie + ); +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h new file mode 100755 index 0000000000..a2ac1c1d33 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h @@ -0,0 +1,133 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe topology initialization service procedures. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIETOPOLOGYSERVICES_H_ +#define _PCIETOPOLOGYSERVICES_H_ + +/// Lane Control +typedef enum { + EnableLanes, ///< Enable Lanes + DisableLanes ///< Disable Lanes +} LANE_CONTROL; + +VOID +PcieTopologyPrepareForReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieTopologySetCoreConfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyApplyLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySelectMasterPll ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyExecuteReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySetLinkReversal ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +VOID +PcieTopologyReduceLinkWidth ( + IN UINT8 LinkWidth, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyLaneControl ( + IN LANE_CONTROL Control, + IN UINT32 LaneBitMap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyInitSrbmReset ( + IN BOOLEAN SrbmResetEnable, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetDdiOwnPhy ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieWrapSetTxS1CtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieWrapSetTxOffCtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c new file mode 100755 index 0000000000..fd37187fdd --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c @@ -0,0 +1,648 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe utility. Various supporting functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 49532 $ @e \$Date: 2011-03-25 02:54:43 +0800 (Fri, 25 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEUTILITYLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +/// Lane type +typedef enum { + LaneTypeCore, ///< Core Lane + LaneTypePhy, ///< Package Phy Lane + LaneTypeNativePhy ///< Native Phy Lane +} LANE_TYPE; + +/// Lane Property +typedef enum { + LanePropertyConfig, ///< Configuration + LanePropertyActive, ///< Active + LanePropertyAllocated ///< Allocated +} LANE_PROPERTY; + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +typedef struct { + UINT32 Flags; + PCIE_LINK_SPEED_CAP LinkSpeedCapability; +} PCIE_GLOBAL_GEN_CAP_WORKSPACE; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +UINT32 +PcieUtilGetPcieEngineLaneBitMap ( + IN LANE_TYPE LaneType, + IN LANE_PROPERTY LaneProperty, + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +PcieUtilGetDdiEngineLaneBitMap ( + IN LANE_TYPE LaneType, + IN LANE_PROPERTY LaneProperty, + IN PCIe_ENGINE_CONFIG *Engine + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Get link state history from HW state machine + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[out] History Buffer to save history + * @param[in] Length Buffer length + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieUtilGetLinkHwStateHistory ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT UINT8 *History, + IN UINT8 Length, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 ReadLength; + UINT32 LocalHistory [6]; + UINT16 Index; + ASSERT (Length <= 16); + ASSERT (Length > 0); + if (Length > 6*4) { + Length = 6*4; + } + ReadLength = (Length + 3) / 4; + for (Index = 0; Index < ReadLength; Index++) { + LocalHistory[Index] = PciePortRegisterRead ( + Engine, + DxF0xE4_xA5_ADDRESS + Index, + Pcie + ); + } + LibAmdMemCopy (History, LocalHistory, Length, GnbLibGetHeader (Pcie)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Search array for specific pattern + * + * + * @param[in] Buf1 Pointer to source buffer which will be subject of search + * @param[in] Buf1Length Length of the source buffer + * @param[in] Buf2 Pointer to pattern buffer + * @param[in] Buf2Length Length of the pattern buffer + * @retval TRUE Pattern found + * @retval TRUE Pattern not found + */ + +BOOLEAN +PcieUtilSearchArray ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ) +{ + UINT8 *CurrentBuf1Ptr; + CurrentBuf1Ptr = Buf1; + while (CurrentBuf1Ptr < (Buf1 + Buf1Length - Buf2Length)) { + UINT8 *SourceBufPtr; + UINT8 *PatternBufPtr; + UINTN PatternBufLength; + SourceBufPtr = CurrentBuf1Ptr; + PatternBufPtr = Buf2; + PatternBufLength = Buf2Length; + while ((*SourceBufPtr++ == *PatternBufPtr++) && (PatternBufLength-- != 0)); + if (PatternBufLength == 0) { + return TRUE; + } + CurrentBuf1Ptr++; + } + return FALSE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if link reversed + * + * + * @param[in] HwLinkState Check for HW auto link reversal + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to PCIe config descriptor + * @retval TRUE if link reversed + */ +BOOLEAN +PcieUtilIsLinkReversed ( + IN BOOLEAN HwLinkState, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 LinkReversal; + + LinkReversal = (Engine->EngineData.StartLane > Engine->EngineData.EndLane) ? 1 : 0; + if (HwLinkState) { + DxF0xE4_x50_STRUCT DxF0xE4_x50; + DxF0xE4_x50.Value = PciePortRegisterRead ( + Engine, + DxF0xE4_x50_ADDRESS, + Pcie + ); + LinkReversal ^= DxF0xE4_x50.Field.PortLaneReversal; + } + return ((LinkReversal & BIT0) != 0) ? TRUE : FALSE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get link width detected during training + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Link width + */ +UINT8 +PcieUtilGetLinkWidth ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkWidth; + DxF0xE4_xA2_STRUCT DxF0xE4_xA2; + DxF0xE4_xA2.Value = PciePortRegisterRead ( + Engine, + DxF0xE4_xA2_ADDRESS, + Pcie + ); + switch (DxF0xE4_xA2.Field.LcLinkWidthRd) { + case 0x6: + LinkWidth = 16; + break; + case 0x5: + LinkWidth = 12; + break; + case 0x4: + LinkWidth = 8; + break; + case 0x3: + LinkWidth = 4; + break; + case 0x2: + LinkWidth = 2; + break; + case 0x1: + LinkWidth = 1; + break; + default: + LinkWidth = 0; + } + return LinkWidth; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of PCIE engine lane of requested type + * + * + * @param[in] LaneType Lane type + * @param[in] LaneProperty Lane Property + * @param[in] Engine Pointer to engine config descriptor + * @retval Lane bitmap + */ + +UINT32 +PcieUtilGetPcieEngineLaneBitMap ( + IN LANE_TYPE LaneType, + IN LANE_PROPERTY LaneProperty, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitmap; + UINT8 Width; + UINT16 Offset; + UINT16 LoPhylane; + UINT16 HiPhylane; + PCIe_PLATFORM_CONFIG *Pcie; + + Width = 0; + Offset = 0; + LaneBitmap = 0; + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Engine->Header); + + if (PcieConfigIsPcieEngine (Engine)) { + if (LaneType == LaneTypeCore && LaneProperty == LanePropertyConfig) { + Width = PcieConfigGetNumberOfCoreLane (Engine); + Offset = Engine->Type.Port.StartCoreLane; + LaneBitmap = ((1 << Width) - 1) << Offset; + } else if (PcieConfigIsEngineAllocated (Engine)) { + if (LaneType == LaneTypeNativePhy) { + LaneBitmap = PcieUtilGetPcieEngineLaneBitMap (LaneTypePhy, LaneProperty, Engine); + LaneBitmap = PcieFmGetNativePhyLaneBitmap (LaneBitmap, Engine); + } else { + if (LaneType == LaneTypeCore) { + if (LaneProperty == LanePropertyActive) { + Width = PcieUtilGetLinkWidth (Engine, Pcie); + Offset = PcieUtilIsLinkReversed (TRUE, Engine, Pcie) ? (Engine->Type.Port.EndCoreLane - Width + 1) : Engine->Type.Port.StartCoreLane; + } else if (LaneProperty == LanePropertyAllocated) { + Width = PcieConfigGetNumberOfPhyLane (Engine); + Offset = PcieUtilIsLinkReversed (FALSE, Engine, Pcie) ? (Engine->Type.Port.EndCoreLane - Width + 1) : Engine->Type.Port.StartCoreLane; + } + } + if (LaneType == LaneTypePhy) { + LoPhylane = PcieLibGetLoPhyLane (Engine); + HiPhylane = PcieLibGetHiPhyLane (Engine); + if (LaneProperty == LanePropertyActive) { + Width = PcieUtilGetLinkWidth (Engine, Pcie); + Offset = (PcieUtilIsLinkReversed (TRUE, Engine, Pcie) ? (HiPhylane - Width + 1) : LoPhylane) - PcieConfigGetParentWrapper (Engine)->StartPhyLane; + } else if (LaneProperty == LanePropertyAllocated) { + Width = PcieConfigGetNumberOfPhyLane (Engine); + Offset = LoPhylane - PcieConfigGetParentWrapper (Engine)->StartPhyLane; + } + } + LaneBitmap = ((1 << Width) - 1) << Offset; + } + } + } + return LaneBitmap; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of PCIE engine lane of requested type + * + * + * @param[in] LaneType Lane type + * @param[in] LaneProperty Lane Property + * @param[in] Engine Pointer to engine config descriptor + * @retval Lane bitmap + */ + +UINT32 +PcieUtilGetDdiEngineLaneBitMap ( + IN LANE_TYPE LaneType, + IN LANE_PROPERTY LaneProperty, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitmap; + UINT8 Width; + UINT16 Offset; + Width = 0; + Offset = 0; + LaneBitmap = 0; + if (PcieConfigIsDdiEngine (Engine)) { + if (PcieConfigIsEngineAllocated (Engine)) { + if (LaneType == LaneTypePhy && ((LaneProperty == LanePropertyActive && (Engine->InitStatus & INIT_STATUS_DDI_ACTIVE)) || (LaneProperty == LanePropertyAllocated))) { + Width = PcieConfigGetNumberOfPhyLane (Engine); + Offset = PcieLibGetLoPhyLane (Engine) - PcieConfigGetParentWrapper (Engine)->StartPhyLane; + LaneBitmap = ((1 << Width) - 1) << Offset; + } + if (LaneType == LaneTypeNativePhy) { + LaneBitmap = PcieUtilGetDdiEngineLaneBitMap (LaneTypePhy, LaneProperty, Engine); + LaneBitmap = PcieFmGetNativePhyLaneBitmap (LaneBitmap, Engine); + } + } + } + return LaneBitmap; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of engine lane of requested type + * + * + * @param[in] IncludeLaneType Include Lane type + * @param[in] ExcludeLaneType Exclude Lane type + * @param[in] Engine Pointer to engine config descriptor + * @retval Lane bitmap + */ + +UINT32 +PcieUtilGetEngineLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitmap; + LaneBitmap = 0; + if (IncludeLaneType & LANE_TYPE_PCIE_LANES) { + if (IncludeLaneType & LANE_TYPE_PCIE_CORE_CONFIG) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyConfig, Engine); + } + if (IncludeLaneType & LANE_TYPE_PCIE_CORE_ALLOC) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & (LANE_TYPE_PCIE_CORE_ACTIVE | LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE)) { + if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } else if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + if (IncludeLaneType & LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } else { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyActive, Engine); + } + } + } + if ((IncludeLaneType & LANE_TYPE_PCIE_SB_CORE_CONFIG) && PcieConfigIsSbPcieEngine (Engine)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyConfig, Engine); + } + if ((IncludeLaneType & LANE_TYPE_PCIE_CORE_HOTPLUG) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_PCIE_PHY) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & (LANE_TYPE_PCIE_PHY_NATIVE_ACTIVE | LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE)) { + if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } else if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + if (IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } else { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyActive, Engine); + } + } + } + if ((IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } + } + if (IncludeLaneType & LANE_TYPE_DDI_LANES) { + if (IncludeLaneType & LANE_TYPE_DDI_PHY) { + LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_DDI_PHY_NATIVE) { + LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_DDI_PHY_NATIVE_ACTIVE) { + LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypeNativePhy, LanePropertyActive, Engine); + } + } + if (ExcludeLaneType != 0) { + LaneBitmap &= (~PcieUtilGetEngineLaneBitMap (ExcludeLaneType, 0, Engine)); + } + return LaneBitmap; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of Wrapper lane of requested type + * + * + * @param[in] IncludeLaneType Include Lane type + * @param[in] ExcludeLaneType Exclude Lane type + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval Lane bitmap + */ + +UINT32 +PcieUtilGetWrapperLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 LaneBitmap; + EngineList = PcieConfigGetChildEngine (Wrapper); + LaneBitmap = 0; + if ((IncludeLaneType | ExcludeLaneType) != 0) { + if ((IncludeLaneType & LANE_TYPE_ALL) == LANE_TYPE_ALL) { + LaneBitmap = (1 << (Wrapper->EndPhyLane - Wrapper->StartPhyLane + 1)) - 1; + if (ExcludeLaneType != 0) { + LaneBitmap &= (~PcieUtilGetWrapperLaneBitMap (ExcludeLaneType, 0, Wrapper)); + } + } else { + while (EngineList != NULL) { + LaneBitmap |= PcieUtilGetEngineLaneBitMap (IncludeLaneType, ExcludeLaneType, EngineList); + EngineList = PcieLibGetNextDescriptor (EngineList); + } + } + } + return LaneBitmap; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program port register table + * + * + * + * @param[in] Table Pointer to table + * @param[in] Length number of entries + * @param[in] Engine Pointer to engine config descriptor + * @param[in] S3Save Save for S3 flag + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PciePortProgramRegisterTable ( + IN PCIE_PORT_REGISTER_ENTRY *Table, + IN UINTN Length, + IN PCIe_ENGINE_CONFIG *Engine, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINTN Index; + UINT32 Value; + for (Index = 0; Index < Length; Index++) { + Value = PciePortRegisterRead ( + Engine, + Table[Index].Reg, + Pcie + ); + Value &= (~Table[Index].Mask); + Value |= Table[Index].Data; + PciePortRegisterWrite ( + Engine, + Table[Index].Reg, + Value, + S3Save, + Pcie + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Lock registers + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieLockRegisters ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CoreId; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieLockRegisters Enter\n"); + if (PcieLibIsPcieWrapper (Wrapper)) { + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + PcieRegisterWriteField ( + Wrapper, + CORE_SPACE (CoreId, D0F0xE4_CORE_0010_ADDRESS), + D0F0xE4_CORE_0010_HwInitWrLock_OFFSET, + D0F0xE4_CORE_0010_HwInitWrLock_WIDTH, + 0x1, + TRUE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieLockRegisters Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Training state handling + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Indicate if engine in non final state + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieUtilGlobalGenCapabilityCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_GLOBAL_GEN_CAP_WORKSPACE *GlobalGenCapability; + PCIE_LINK_SPEED_CAP LinkSpeedCapability; + PCIE_HOTPLUG_TYPE HotPlugType; + UINT32 Flags; + + Flags = PCIE_GLOBAL_GEN_CAP_ALL_PORTS; + GlobalGenCapability = (PCIE_GLOBAL_GEN_CAP_WORKSPACE*) Buffer; + LinkSpeedCapability = PcieGen1; + if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + Flags |= PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS; + } + HotPlugType = Engine->Type.Port.PortData.LinkHotplug; + if ((HotPlugType == HotplugBasic) || (HotPlugType == HotplugServer) || (HotPlugType == HotplugEnhanced)) { + Flags |= PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS; + } + if ((GlobalGenCapability->Flags & Flags) != 0) { + ASSERT ((GlobalGenCapability->Flags & (PCIE_PORT_GEN_CAP_MAX | PCIE_PORT_GEN_CAP_BOOT)) != 0); + LinkSpeedCapability = PcieFmGetLinkSpeedCap (GlobalGenCapability->Flags, Engine); + if (GlobalGenCapability->LinkSpeedCapability < LinkSpeedCapability) { + GlobalGenCapability->LinkSpeedCapability = LinkSpeedCapability; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Determine global GEN capability + * + * + * @param[in] Flags global GEN capability flags + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +PCIE_LINK_SPEED_CAP +PcieUtilGlobalGenCapability ( + IN UINT32 Flags, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_LINK_SPEED_CAP GlobalCapability; + PCIE_GLOBAL_GEN_CAP_WORKSPACE GlobalGenCap; + + GlobalGenCap.LinkSpeedCapability = PcieGen1; + GlobalGenCap.Flags = Flags; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieUtilGlobalGenCapabilityCallback, + &GlobalGenCap, + Pcie + ); + + GlobalCapability = GlobalGenCap.LinkSpeedCapability; + + return GlobalCapability; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h new file mode 100755 index 0000000000..dd24a7f473 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h @@ -0,0 +1,131 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe utility. Various supporting functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48318 $ @e \$Date: 2011-03-08 01:48:31 +0800 (Tue, 08 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEUTILLIB_H_ +#define _PCIEUTILLIB_H_ + +/// Core lanes +typedef enum { + AllCoreLanes, ///< All core lanes + AllocatedCoreLanes, ///< Allocated core lanes + ActiveCoreLanes, ///< Active core lanes + HotplugCoreLanes, ///< Hot plug core lanes + SbCoreLanes, ///< South bridge core lanes +} CORE_LANES; + +/// DDI lanes +typedef enum { + DdiAllLanes, ///< All DDI Lanes + DdiActiveLanes ///< Active DDI Lanes +} DDI_LANES; + +BOOLEAN +PcieUtilSearchArray ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ); + +VOID +PcieUtilGetLinkHwStateHistory ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT UINT8 *History, + IN UINT8 Length, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +BOOLEAN +PcieUtilIsLinkReversed ( + IN BOOLEAN HwLinkState, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +UINT8 +PcieUtilGetLinkWidth ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +UINT32 +PcieUtilGetEngineLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +PcieUtilGetWrapperLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PciePortProgramRegisterTable ( + IN PCIE_PORT_REGISTER_ENTRY *Table, + IN UINTN Length, + IN PCIe_ENGINE_CONFIG *Engine, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLockRegisters ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +PCIE_LINK_SPEED_CAP +PcieUtilGlobalGenCapability ( + IN UINT32 Flags, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c new file mode 100755 index 0000000000..b1ec39f61e --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c @@ -0,0 +1,291 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe wrapper/core/PIF/PHY indirect register spaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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. +* *************************************************************************** +* +*/ + +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEWRAPPERREGACC_FILECODE +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to Wrapper descriptor + * @param[in] Address Register address + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Register Value + */ +UINT32 +PcieRegisterRead ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + return PcieSiliconRegisterRead (PcieConfigGetParentSilicon (Wrapper), Address, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Silicon Pointer to silicon descriptor + * @param[in] Address Register address + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Register Value + */ + +UINT32 +PcieSiliconRegisterRead ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + GnbLibPciWrite (Silicon->Address.AddressValue | 0xE0, AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciRead (Silicon->Address.AddressValue | 0xE4, AccessWidth32, &Value, GnbLibGetHeader (Pcie)); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] Value New register value + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieRegisterWrite ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieSiliconRegisterWrite ( + PcieConfigGetParentSilicon (Wrapper), + Address, + Value, + S3Save, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Silicon Pointer to silicon descriptor + * @param[in] Address Register address + * @param[in] Value New register value + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieSiliconRegisterWrite ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + IDS_HDT_CONSOLE (PCIE_HOSTREG_TRACE, " *WR %s (%d:%d:%d):0x%08x = 0x%08x\n", + PcieFmDebugGetHostRegAddressSpaceString (Silicon, (UINT16) (Address >> 16)), + Silicon->Address.Address.Bus, + Silicon->Address.Address.Device, + Silicon->Address.Address.Function, + Address, + Value + ); + GnbLibPciWrite (Silicon->Address.AddressValue | 0xE0, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciWrite (Silicon->Address.AddressValue | 0xE4, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Value, GnbLibGetHeader (Pcie)); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Register field value + */ + +UINT32 +PcieRegisterReadField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PcieRegisterRead (Wrapper, Address, Pcie); + Value = (Value >> FieldOffset) & (~(0xFFFFFFFF << FieldWidth)); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Value Value to write + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + + +VOID +PcieRegisterWriteField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TempValue; + UINT32 Mask; + TempValue = PcieRegisterRead (Wrapper, Address, Pcie); + Mask = (~(0xFFFFFFFF << FieldWidth)); + Value &= Mask; + TempValue &= (~(Mask << FieldOffset)); + PcieRegisterWrite (Wrapper, Address, TempValue | (Value << FieldOffset), S3Save, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCIe register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] AndMask Value & (~AndMask) + * @param[in] OrMask Value | OrMask + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieRegisterRMW ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieSiliconRegisterRMW ( + PcieConfigGetParentSilicon (Wrapper), + Address, + AndMask, + OrMask, + S3Save, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCIe register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Silicon Pointer to silicon descriptor + * @param[in] Address Register address + * @param[in] AndMask Value & (~AndMask) + * @param[in] OrMask Value | OrMask + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieSiliconRegisterRMW ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PcieSiliconRegisterRead (Silicon, Address, Pcie); + Value = (Value & (~AndMask)) | OrMask; + PcieSiliconRegisterWrite (Silicon, Address, Value, S3Save, Pcie); +}
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h new file mode 100755 index 0000000000..7f39322fd6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h @@ -0,0 +1,127 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe wrapper/core/PIF/PHY indirect register spaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ + +#ifndef _PCIEWRAPPERREGACC_H_ +#define _PCIEWRAPPERREGACC_H_ + +//#define WRAP_SPACE(w, x) (0x01300000 | (w << 16) | (x)) +//#define CORE_SPACE(c, x) (0x00010000 | (c << 24) | (x)) +//#define PHY_SPACE(w, p, x) (0x00200000 | ((p + 1) << 24) | (w << 16) | (x)) +//#define PIF_SPACE(w, p, x) (0x00100000 | ((p + 1) << 24) | (w << 16) | (x)) +#define IMP_SPACE(x) (0x01080000 | (x)) + +UINT32 +PcieRegisterRead ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieRegisterWrite ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieRegisterReadField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieRegisterWriteField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieRegisterRMW ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieSiliconRegisterRead ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSiliconRegisterWrite ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSiliconRegisterRMW ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/GnbPcieTrainingV1.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/GnbPcieTrainingV1.h new file mode 100755 index 0000000000..8f57f3d54b --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/GnbPcieTrainingV1.h @@ -0,0 +1,51 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe training library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _GNBPCIETRAININGV1_H_ +#define _GNBPCIETRAININGV1_H_ + +#include "PcieTraining.h" +#include "PcieWorkarounds.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieTraining.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieTraining.c new file mode 100755 index 0000000000..48d59afbdd --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieTraining.c @@ -0,0 +1,864 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link training + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "GeneralServices.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "PcieWorkarounds.h" +#include "PcieTraining.h" +#include "GnbRegistersLN.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIETRAININGV1_PCIETRAINING_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 + *---------------------------------------------------------------------------------------- + */ +VOID +PcieSetResetStateOnEngines ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTrainingCheckResetDuration ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTrainingDeassertReset ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTrainingBrokenLine ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTrainingGen2Fail ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +/* + VOID +STATIC +PcieTrainingDebugDumpPortState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); +*/ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set link State + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] State State to set + * @param[in] UpdateTimeStamp Update time stamp + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieTrainingSetPortState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN UINT8 State, + IN BOOLEAN UpdateTimeStamp, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + CurrentEngine->Type.Port.State = State; + if (UpdateTimeStamp) { + TimeStamp = PcieTimerGetTimeStamp (Pcie); + CurrentEngine->Type.Port.TimeStamp = TimeStamp; + } + GNB_DEBUG_CODE ( + PcieTrainingDebugDumpPortState (CurrentEngine, Pcie) + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set state for all engines connected to same reset ID + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Pointer to Reset Id + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieSetResetStateOnEngines ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 ResetId; + ResetId = *(UINT8 *)Buffer; + if (Engine->Type.Port.PortData.ResetId == ResetId) { + PcieTrainingSetPortState (Engine, LinkStateResetDuration, TRUE, Pcie); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Assert GPIO port reset. + * + * Transition to LinkStateResetDuration state + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingAssertReset ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SLOT_RESET_INFO ResetInfo; + ResetInfo.ResetControl = AssertSlotReset; + ResetInfo.ResetId = CurrentEngine->Type.Port.PortData.ResetId; + LibAmdMemCopy (&ResetInfo.StdHeader, GnbLibGetHeader (Pcie), sizeof (AMD_CONFIG_PARAMS), GnbLibGetHeader (Pcie)); + AgesaPcieSlotResetControl (0, &ResetInfo); + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieSetResetStateOnEngines, + (VOID *)&CurrentEngine->Type.Port.PortData.ResetId, + Pcie + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check for reset duration + * + * Transition to LinkStateResetDuration state + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieTrainingCheckResetDuration ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkGpioResetAssertionTime) { + PcieTrainingSetPortState (CurrentEngine, LinkStateResetExit, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Deassert GPIO port reset. + * + * Transition to LinkStateResetDuration state + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Platform configuration + * + */ +VOID +PcieTrainingDeassertReset ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SLOT_RESET_INFO ResetInfo; + ResetInfo.ResetControl = DeassertSlotReset; + ResetInfo.ResetId = CurrentEngine->Type.Port.PortData.ResetId; + LibAmdMemCopy (&ResetInfo.StdHeader, GnbLibGetHeader (Pcie), sizeof (AMD_CONFIG_PARAMS), GnbLibGetHeader (Pcie)); + AgesaPcieSlotResetControl (0, &ResetInfo); + PcieTrainingSetPortState (CurrentEngine, LinkTrainingResetTimeout, TRUE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check for after reset deassertion timeout + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCheckResetTimeout ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkResetToTrainingTime) { + PcieTrainingSetPortState (CurrentEngine, LinkStateReleaseTraining, FALSE, Pcie); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Release training + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingRelease ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkTrainingState; + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (CurrentEngine), + WRAP_SPACE (PcieConfigGetParentWrapper (CurrentEngine)->WrapId, D0F0xE4_WRAP_0800_ADDRESS + 0x100 * CurrentEngine->Type.Port.PortId), + D0F0xE4_WRAP_0800_HoldTraining_OFFSET, + D0F0xE4_WRAP_0800_HoldTraining_WIDTH, + 0, + FALSE, + Pcie + ); + if (CurrentEngine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { + LinkTrainingState = LinkStateCompliance; + } else { + LinkTrainingState = LinkStateDetectPresence; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, TRUE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Detect presence of any EP on the link + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingDetectPresence ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[4]; + UINT32 TimeStamp; + PcieUtilGetLinkHwStateHistory (CurrentEngine, &LinkHwStateHistory[0], 4, Pcie); + if (LinkHwStateHistory[0] > 4) { + PcieTrainingSetPortState (CurrentEngine, LinkStateDetecting, TRUE, Pcie); + return; + } + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkReceiverDetectionPooling) { + PcieTrainingSetPortState (CurrentEngine, LinkStateDeviceNotPresent, FALSE, Pcie); + } +} + +UINT8 FailPattern1 [] = {0x2a, 0x6}; +UINT8 FailPattern2 [] = {0x2a, 0x9}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Detect Link State + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingDetectLinkState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[16]; + UINT32 TimeStamp; + UINT8 LinkTrainingState; + PcieUtilGetLinkHwStateHistory (CurrentEngine, &LinkHwStateHistory[0], 4, Pcie); + if (LinkHwStateHistory[0] == 0x10) { + PcieTrainingSetPortState (CurrentEngine, LinkStateL0, FALSE, Pcie); + return; + }; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkL0Pooling) { + LinkTrainingState = LinkStateTrainingFail; + PcieUtilGetLinkHwStateHistory (CurrentEngine, &LinkHwStateHistory[0], 16, Pcie); + if (LinkHwStateHistory[0] == 0x7) { + LinkTrainingState = LinkStateCompliance; + } else if (PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), FailPattern1, sizeof (FailPattern1))) { + LinkTrainingState = LinkStateBrokenLane; + } else if (PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), FailPattern2, sizeof (FailPattern2))) { + LinkTrainingState = LinkStateGen2Fail; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Broken Lane + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieTrainingBrokenLine ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CurrentLinkWidth; + UINT8 LinkTrainingState; + CurrentLinkWidth = PcieUtilGetLinkWidth (CurrentEngine, Pcie); + if (CurrentLinkWidth < PcieConfigGetNumberOfPhyLane (CurrentEngine) && CurrentLinkWidth > 0) { + CurrentEngine->InitStatus |= INIT_STATUS_PCIE_PORT_BROKEN_LANE_RECOVERY; + PcieTopologyReduceLinkWidth (CurrentLinkWidth, CurrentEngine, Pcie); + LinkTrainingState = LinkStateResetAssert; + PutEventLog ( + AGESA_WARNING, + GNB_EVENT_BROKEN_LANE_RECOVERY, + CurrentEngine->Type.Port.Address.AddressValue, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } else { + LinkTrainingState = LinkStateGen2Fail; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if link fail because device does not support Gen2 + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieTrainingGen2Fail ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkTrainingState; + if (CurrentEngine->Type.Port.PortData.MiscControls.LinkSafeMode != PcieGen1) { + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_GEN2_RECOVERY, 0); + CurrentEngine->Type.Port.PortData.MiscControls.LinkSafeMode = PcieGen1; + PcieLinkSafeMode (CurrentEngine, Pcie); + LinkTrainingState = LinkStateResetAssert; + PutEventLog ( + AGESA_WARNING, + GNB_EVENT_BROKEN_LANE_RECOVERY, + CurrentEngine->Type.Port.Address.AddressValue, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } else { + LinkTrainingState = LinkStateTrainingFail; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Link in L0 + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieCheckLinkL0 ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieTrainingSetPortState (CurrentEngine, LinkStateVcoNegotiation, TRUE, Pcie); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Check if link fail because device does not support Gen X + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCheckVcoNegotiation ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + DxF0x128_STRUCT DxF0x128; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + GnbLibPciRead (CurrentEngine->Type.Port.Address.AddressValue | DxF0x128_ADDRESS, AccessWidth32, &DxF0x128, GnbLibGetHeader (Pcie)); + if (DxF0x128.Field.VcNegotiationPending == 0) { + UINT16 NumberOfPhyLane; + NumberOfPhyLane = PcieConfigGetNumberOfPhyLane (CurrentEngine); + if (Pcie->GfxCardWorkaround == GfxWorkaroundEnable && NumberOfPhyLane >= 8) { + // Limit exposure of workaround to x8 and x16 port. + PcieTrainingSetPortState (CurrentEngine, LinkStateGfxWorkaround, TRUE, Pcie); + } else { + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingSuccess, FALSE, Pcie); + } + return; + } + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= 1000 * 1000) { + PcieTrainingSetPortState (CurrentEngine, LinkStateRetrain, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if for GFX workaround condition + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingGfxWorkaround ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + GFX_WORKAROUND_STATUS GfxWorkaroundStatus; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + + GfxWorkaroundStatus = PcieGfxCardWorkaround (CurrentEngine->Type.Port.Address, GnbLibGetHeader (Pcie)); + switch (GfxWorkaroundStatus) { + case GFX_WORKAROUND_DEVICE_NOT_READY: + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= 1000 * 2000) { + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingFail, TRUE, Pcie); + } + break; + case GFX_WORKAROUND_SUCCESS: + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingSuccess, FALSE, Pcie); + break; + case GFX_WORKAROUND_RESET_DEVICE: + if (CurrentEngine->Type.Port.GfxWrkRetryCount < 5) { + CurrentEngine->Type.Port.GfxWrkRetryCount++; + PcieTrainingSetPortState (CurrentEngine, LinkStateResetAssert, TRUE, Pcie); + } else { + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingFail, TRUE, Pcie); + } + break; + default: + ASSERT (FALSE); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Retrain link + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingRetrainLink ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PciePortRegisterWriteField ( + CurrentEngine, + DxF0xE4_xA2_ADDRESS, + DxF0xE4_xA2_LcReconfigNow_OFFSET, + DxF0xE4_xA2_LcReconfigNow_WIDTH, + 1, + FALSE, + Pcie + ); + PcieTrainingSetPortState (CurrentEngine, LinkStateDetecting, TRUE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Training fail on this port + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingFail ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_TRAINING_FAIL, 0); + PcieTrainingSetPortState (CurrentEngine, LinkStateDeviceNotPresent, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Links training success + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingSuccess ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_TRAINING_SUCCESS, 0); + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingCompleted, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Links in compliance + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCompliance ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE, 0); + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingCompleted, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCie EP not present + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingNotPresent ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if ((CurrentEngine->Type.Port.PortData.LinkHotplug == HotplugEnhanced) || (CurrentEngine->Type.Port.PortData.LinkHotplug == HotplugServer)) { + } else { + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (CurrentEngine), + WRAP_SPACE (PcieConfigGetParentWrapper (CurrentEngine)->WrapId, D0F0xE4_WRAP_0800_ADDRESS + 0x100 * CurrentEngine->Type.Port.PortId), + D0F0xE4_WRAP_0800_HoldTraining_OFFSET, + D0F0xE4_WRAP_0800_HoldTraining_WIDTH, + 1, + FALSE, + Pcie + ); + } + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingCompleted, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Final state. Port training completed. + * + * Initialization status recorded in PCIe_ENGINE_CONFIG.InitStatus + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCompleted ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Training state handling + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Indicate if engine in non final state + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingPortCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + BOOLEAN *TrainingComplete; + TrainingComplete = (BOOLEAN *) Buffer; + if (Engine->Type.Port.State < Pcie->TrainingExitState) { + *TrainingComplete = FALSE; + } else { + return; + } + switch (Engine->Type.Port.State) { + case LinkStateResetAssert: + PcieTrainingAssertReset (Engine, Pcie); + break; + case LinkStateResetDuration: + PcieTrainingCheckResetDuration (Engine, Pcie); + break; + case LinkStateResetExit: + PcieTrainingDeassertReset (Engine, Pcie); + break; + case LinkTrainingResetTimeout: + PcieTrainingCheckResetTimeout (Engine, Pcie); + break; + case LinkStateReleaseTraining: + PcieTrainingRelease (Engine, Pcie); + break; + case LinkStateDetectPresence: + PcieTrainingDetectPresence (Engine, Pcie); + break; + case LinkStateDetecting: + PcieTrainingDetectLinkState (Engine, Pcie); + break; + case LinkStateBrokenLane: + PcieTrainingBrokenLine (Engine, Pcie); + break; + case LinkStateGen2Fail: + PcieTrainingGen2Fail (Engine, Pcie); + break; + case LinkStateL0: + PcieCheckLinkL0 (Engine, Pcie); + break; + case LinkStateVcoNegotiation: + PcieTrainingCheckVcoNegotiation (Engine, Pcie); + break; + case LinkStateRetrain: + PcieTrainingRetrainLink (Engine, Pcie); + break; + case LinkStateTrainingFail: + PcieTrainingFail (Engine, Pcie); + break; + case LinkStateGfxWorkaround: + PcieTrainingGfxWorkaround (Engine, Pcie); + break; + case LinkStateTrainingSuccess: + PcieTrainingSuccess (Engine, Pcie); + break; + case LinkStateCompliance: + PcieTrainingCompliance (Engine, Pcie); + break; + case LinkStateDeviceNotPresent: + PcieTrainingNotPresent (Engine, Pcie); + break; + case LinkStateTrainingCompleted: + PcieTrainingCompleted (Engine, Pcie); + break; + default: + break; + } + +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Main link training procedure + * + * Port end up in three possible state LinkStateTrainingNotPresent/LinkStateCompliance/ + * LinkStateTrainingSuccess + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +PcieTraining ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + BOOLEAN TrainingComplete; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTraining Enter\n"); + do { + TrainingComplete = TRUE; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieTrainingPortCallback, + &TrainingComplete, + Pcie + ); + } while (!TrainingComplete); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTraining Exit [%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump port state on state transition + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +/* +VOID +STATIC +PcieTrainingDebugDumpPortState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + IDS_HDT_CONSOLE (PCIE_MISC, " Port %d:%d:%d State [%s] Time Stamp [%d]\n", + CurrentEngine->Type.Port.Address.Address.Bus, + CurrentEngine->Type.Port.Address.Address.Device, + CurrentEngine->Type.Port.Address.Address.Function, + (CurrentEngine->Type.Port.State == LinkStateTrainingFail) ? "LinkStateTrainingFail " : ( + (CurrentEngine->Type.Port.State == LinkStateTrainingSuccess) ? "LinkStateTrainingSuccess " : ( + (CurrentEngine->Type.Port.State == LinkStateCompliance) ? "LinkStateCompliance " : ( + (CurrentEngine->Type.Port.State == LinkStateDeviceNotPresent) ? "LinkStateDeviceNotPresent" : ( + (CurrentEngine->Type.Port.State == LinkStateResetAssert) ? "LinkStateResetAssert " : ( + (CurrentEngine->Type.Port.State == LinkStateResetDuration) ? "LinkStateResetDuration " : ( + (CurrentEngine->Type.Port.State == LinkStateResetDuration) ? "LinkStateResetExit " : ( + (CurrentEngine->Type.Port.State == LinkTrainingResetTimeout) ? "LinkTrainingResetTimeout " : ( + (CurrentEngine->Type.Port.State == LinkStateReleaseTraining) ? "LinkStateReleaseTraining " : ( + (CurrentEngine->Type.Port.State == LinkStateDetectPresence) ? "LinkStateDetectPresence " : ( + (CurrentEngine->Type.Port.State == LinkStateDetecting) ? "LinkStateDetecting " : ( + (CurrentEngine->Type.Port.State == LinkStateBrokenLane) ? "LinkStateBrokenLane " : ( + (CurrentEngine->Type.Port.State == LinkStateGen2Fail) ? "LinkStateGen2Fail " : ( + (CurrentEngine->Type.Port.State == LinkStateL0) ? "LinkStateL0 " : ( + (CurrentEngine->Type.Port.State == LinkStateVcoNegotiation) ? "LinkStateVcoNegotiation " : ( + (CurrentEngine->Type.Port.State == LinkStateGfxWorkaround) ? "LinkStateGfxWorkaround " : ( + (CurrentEngine->Type.Port.State == LinkStateTrainingCompleted) ? "LinkStateTrainingComplete" : ( + (CurrentEngine->Type.Port.State == LinkStateRetrain) ? "LinkStateRetrain " : ( + (CurrentEngine->Type.Port.State == LinkStateResetExit) ? "LinkStateResetExit " : "Unknown")))))))))))))))))), + CurrentEngine->Type.Port.TimeStamp + ); +} +*/ diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieTraining.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieTraining.h new file mode 100755 index 0000000000..ed6e4d8eeb --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieTraining.h @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link training + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIETRAINING_H_ +#define _PCIETRAINING_H_ + + +AGESA_STATUS +PcieTraining ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTrainingSetPortState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN UINT8 State, + IN BOOLEAN UpdateTimeStamp, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieWorkarounds.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieWorkarounds.c new file mode 100755 index 0000000000..4b2d0ab72f --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieWorkarounds.c @@ -0,0 +1,375 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various workarounds + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 48452 $ @e \$Date: 2011-03-09 12:50:44 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* +***************************************************************************** +* +* 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbRegistersLN.h" +#include "PcieWorkarounds.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIETRAININGV1_PCIEWORKAROUNDS_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +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 + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieConfigureBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieFreeBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +GFX_WORKAROUND_STATUS +PcieDeskewWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +GFX_WORKAROUND_STATUS +PcieNvWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieProgramCpuMmio ( + OUT UINT32 *SaveValues, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieRestoreCpuMmio ( + IN UINT32 *RestoreValues, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +PcieIsDeskewCardDetected ( + IN UINT16 DeviceId + ); + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * ATI RV370/RV380 card workaround + * + * + * + * @param[in] Port PCI addreses of the port + * @param[in] StdHeader Standard configuration header + * @retval GFX_WORKAROUND_STATUS Return the GFX Card Workaround status + */ +GFX_WORKAROUND_STATUS +PcieGfxCardWorkaround ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GFX_WORKAROUND_STATUS Status; + UINT16 DeviceId; + UINT16 VendorId; + UINT8 DevClassCode; + UINT32 SaveValueData[2]; + PCI_ADDR Ep; + + Status = GFX_WORKAROUND_SUCCESS; + + Ep.AddressValue = MAKE_SBDFO (0, Port.Address.Bus + Port.Address.Device, 0, 0, 0); + if (PcieConfigureBridgeResources (Port, StdHeader) == AGESA_SUCCESS) { + GnbLibPciRead (Ep.AddressValue | 0x00, AccessWidth16, &DeviceId, StdHeader); + Status = GFX_WORKAROUND_DEVICE_NOT_READY; + if (DeviceId != 0xffff) { + GnbLibPciRead (Ep.AddressValue | 0x02, AccessWidth16, &VendorId, StdHeader); + if (VendorId != 0xffff) { + GnbLibPciRead (Ep.AddressValue | 0x0B, AccessWidth8, &DevClassCode, StdHeader); + Status = GFX_WORKAROUND_SUCCESS; + if (DevClassCode == 3) { + PcieProgramCpuMmio (SaveValueData, StdHeader); + if (VendorId == 0x1002 && PcieIsDeskewCardDetected (DeviceId)) { + Status = PcieDeskewWorkaround (Ep, StdHeader); + } else if (VendorId == 0x10DE) { + Status = PcieNvWorkaround (Ep, StdHeader); + } + PcieRestoreCpuMmio (SaveValueData, StdHeader); + } + } + } + PcieFreeBridgeResources (Port, StdHeader); + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * RV370/RV380 Deskew workaround + * + * + * + * @param[in] Device Pcie Address of ATI RV370/RV380 card. + * @param[in] StdHeader Standard configuration header + */ +GFX_WORKAROUND_STATUS +PcieDeskewWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN MmioBase; + UINT16 MmioData1; + UINT32 MmioData2; + + MmioBase = UserOptions.CfgTempPcieMmioBaseAddress; + if (MmioBase == 0) { + return GFX_WORKAROUND_SUCCESS; + } + GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &MmioBase, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x04, AccessWidth8 , ~(UINT32)BIT1, BIT1, StdHeader); + GnbLibMemRMW (MmioBase + 0x120, AccessWidth16, 0, 0xb700, StdHeader); + GnbLibMemRead (MmioBase + 0x120, AccessWidth16, &MmioData1, StdHeader); + if (MmioData1 == 0xb700) { + GnbLibMemRMW (MmioBase + 0x124, AccessWidth32, 0, 0x13, StdHeader); + GnbLibMemRead (MmioBase + 0x124, AccessWidth32, &MmioData2, StdHeader); + if (MmioData2 == 0x13) { + GnbLibMemRead (MmioBase + 0x12C, AccessWidth32, &MmioData2, StdHeader); + if (MmioData2 & BIT8) { + return GFX_WORKAROUND_RESET_DEVICE; + } + } + } + GnbLibPciRMW (Device.AddressValue | 0x04, AccessWidth8, ~(UINT32)BIT1, 0x0, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x18, AccessWidth32, 0x0, 0x0, StdHeader); + + return GFX_WORKAROUND_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NV43 card workaround (lost SSID) + * + * + * + * @param[in] Device Pcie Address of NV43 card. + * @param[in] StdHeader Standard configuration header + */ +GFX_WORKAROUND_STATUS +PcieNvWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 DeviceSSID; + UINTN MmioBase; + UINT32 MmioData3; + + MmioBase = UserOptions.CfgTempPcieMmioBaseAddress; + if (MmioBase == 0) { + return GFX_WORKAROUND_SUCCESS; + } + GnbLibPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, ((UINT32)MmioBase) | 1, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x2, StdHeader); + GnbLibPciRead (Device.AddressValue | 0x2c, AccessWidth32, &DeviceSSID, StdHeader); + GnbLibMemRead (MmioBase + 0x54, AccessWidth32, &MmioData3, StdHeader); + if (DeviceSSID != MmioData3) { + GnbLibPciRMW (Device.AddressValue | 0x40, AccessWidth32, 0x0, MmioData3, StdHeader); + } + GnbLibPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, 0x0, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x0, StdHeader); + return GFX_WORKAROUND_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate temporary resources for Pcie P2P bridge + * + * + * + * @param[in] Port Pci Address of Port to initialize. + * @param[in] StdHeader Standard configuration header + */ +AGESA_STATUS +PcieConfigureBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Value; + UINT32 MmioBase; + + MmioBase = UserOptions.CfgTempPcieMmioBaseAddress; + if (MmioBase == 0) { + return AGESA_WARNING; + } + Value = Port.Address.Bus + ((Port.Address.Bus + Port.Address.Device) << 8) + ((Port.Address.Bus + Port.Address.Device) << 16); + GnbLibPciWrite (Port.AddressValue | DxF0x18_ADDRESS, AccessWidth32, &Value, StdHeader); + Value = MmioBase + (MmioBase >> 16); + GnbLibPciWrite (Port.AddressValue | DxF0x20_ADDRESS, AccessWidth32, &Value, StdHeader); + Value = 0x000fff0; + GnbLibPciWrite (Port.AddressValue | DxF0x24_ADDRESS, AccessWidth32, &Value, StdHeader); + Value = 0x2; + GnbLibPciWrite (Port.AddressValue | DxF0x04_ADDRESS, AccessWidth8, &Value, StdHeader); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Free temporary resources for Pcie P2P bridge + * + * + * + * @param[in] Port Pci Address of Port to clear resource allocation. + * @param[in] StdHeader Standard configuration header + */ +VOID +PcieFreeBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Value; + + Value = 0; + GnbLibPciWrite (Port.AddressValue | DxF0x04_ADDRESS, AccessWidth8, &Value, StdHeader); + GnbLibPciWrite (Port.AddressValue | DxF0x18_ADDRESS, AccessWidth32, &Value, StdHeader); + GnbLibPciWrite (Port.AddressValue | DxF0x20_ADDRESS, AccessWidth32, &Value, StdHeader); + GnbLibPciWrite (Port.AddressValue | DxF0x24_ADDRESS, AccessWidth32, &Value, StdHeader); + +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Save CPU MMIO register + * + * + * + * @param[out] UINT32 SaveValues + * @param[in] StdHeader Standard configuration header + * + */ +VOID +PcieProgramCpuMmio ( + OUT UINT32 *SaveValues, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + //Save CPU MMIO Register + GnbLibPciRead (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xB8), AccessWidth32, SaveValues, StdHeader); + GnbLibPciRead (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xBC), AccessWidth32, SaveValues + 1, StdHeader); + + //Write Temp Pcie MMIO to CPU + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xBC), AccessWidth32, 0, (UserOptions.CfgTempPcieMmioBaseAddress >> 16) << 8, StdHeader); + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xB8), AccessWidth32, 0, ((UserOptions.CfgTempPcieMmioBaseAddress >> 16) << 8) | 0x3, StdHeader); + +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Restore CPU MMIO register + * + * + * + * @param[in] PCIe_PLATFORM_CONFIG Pcie + * @param[in] StdHeader Standard configuration header + */ +VOID +PcieRestoreCpuMmio ( + IN UINT32 *RestoreValues, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + //Restore CPU MMIO Register + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xB8), AccessWidth32, 0, *RestoreValues, StdHeader); + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xBC), AccessWidth32, 0, *(RestoreValues + 1), StdHeader); + +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if card required test for deskew workaround + * + * + * + * @param[in] DeviceId Device ID + */ + +BOOLEAN +PcieIsDeskewCardDetected ( + IN UINT16 DeviceId + ) +{ + if ((DeviceId >= 0x3150 && DeviceId <= 0x3152) || (DeviceId == 0x3154) || + (DeviceId == 0x3E50) || (DeviceId == 0x3E54) || + ((DeviceId & 0xfff8) == 0x5460) || ((DeviceId & 0xfff8) == 0x5B60)) { + return TRUE; + } + return FALSE; +} + + diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieWorkarounds.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieWorkarounds.h new file mode 100755 index 0000000000..7475be53a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieTrainingV1/PcieWorkarounds.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various workarounds + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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. +* *************************************************************************** +* +*/ +#ifndef _PCIEWORKAROUNDS_H_ +#define _PCIEWORKAROUNDS_H_ + +GFX_WORKAROUND_STATUS +PcieGfxCardWorkaround ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbIommuLib/GnbSbIommuLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbIommuLib/GnbSbIommuLib.c new file mode 100755 index 0000000000..d3f79d50a4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbIommuLib/GnbSbIommuLib.c @@ -0,0 +1,117 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39931 $ @e \$Date: 2010-10-16 18:19:16 -0700 (Sat, 16 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 "Gnb.h" +#include "GnbCommonLib.h" +#include "GnbIvrsLib.h" +#include "GnbSbLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSBIOMMULIB_GNBSBIOMMULIB_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 + *---------------------------------------------------------------------------------------- + */ + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Create IVHD entry + * + * + * @param[in] Ivhd IVHD header pointer + * @param[in] StdHeader Standard configuration header + * + */ +VOID +SbCreateIvhdEntries ( + OUT IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR Start; + PCI_ADDR End; + PCI_ADDR PciAddress; + UINT32 Value; + IDS_HDT_CONSOLE (GNB_TRACE, "SbCreateIvhdEntries Entry\n"); + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 4, 0); +// P2P alias entry + GnbLibPciRead (PciAddress.AddressValue | 0x18, AccessWidth32, &Value, StdHeader); + Start.AddressValue = MAKE_SBDFO (0, (Value >> 8) & 0xff, 0, 0, 0); + End.AddressValue = MAKE_SBDFO (0, (Value >> 16) & 0xff, 0x1f, 0x7, 0); + GnbIvhdAddDeviceAliasRangeEntry (Start, End, PciAddress, 0, Ivhd, StdHeader); + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0); +// HPET + GnbIvhdAddSpecialDeviceEntry (IvhdSpecialDeviceHpet, PciAddress, 0, 0, Ivhd, StdHeader); +// APIC + GnbIvhdAddSpecialDeviceEntry ( + IvhdSpecialDeviceIoapic, + PciAddress, + GnbLiGetIoapicId (SbGetSbIoApicBaseAddress (StdHeader), StdHeader), + 0xD7, + Ivhd, + StdHeader + ); + IDS_HDT_CONSOLE (GNB_TRACE, "SbCreateIvhdEntries Exit\n"); +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbIommuLib/GnbSbIommuLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbIommuLib/GnbSbIommuLib.h new file mode 100755 index 0000000000..24a0343895 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbIommuLib/GnbSbIommuLib.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39931 $ @e \$Date: 2010-10-16 18:19:16 -0700 (Sat, 16 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. +* *************************************************************************** +* +*/ +#ifndef _GNBSBIOMMULIB_H_ +#define _GNBSBIOMMULIB_H_ + + +VOID +SbCreateIvhdEntries ( + OUT IVRS_IVHD_ENTRY *Ivhd, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c new file mode 100755 index 0000000000..898521ae96 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c @@ -0,0 +1,132 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39931 $ @e \$Date: 2010-10-16 18:19:16 -0700 (Sat, 16 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 "Gnb.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSBLIB_GNBSBLIB_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 + *---------------------------------------------------------------------------------------- + */ + + + +/*----------------------------------------------------------------------------------------*/ +/** + *Get SB IOAPIC Base Address + * + * + * @param[in] StdHeader Standard configuration header + * @retval APIC base address + */ +UINT32 +SbGetSbIoApicBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ApicBaseAddress; + GnbLibIndirectIoBlockRead (0xCD6, 0xCD7, AccessWidth8, 0x34, 4, &ApicBaseAddress, StdHeader); + return ApicBaseAddress & 0xfffffff8; +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Get SB MMIO Base Address + * + * + * @param[in] StdHeader Standard configuration header + * @retval MMIO base address + */ +UINT32 +SbGetSbMmioBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MmioBaseAddress; + GnbLibIndirectIoBlockRead (0xCD6, 0xCD7, AccessWidth8, 0x24, 4, &MmioBaseAddress, StdHeader); + return MmioBaseAddress & 0xfffffffc; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Alink config address + * + * @param[in] StdHeader Standard configuration header + * @retval Alink base address + */ +/*----------------------------------------------------------------------------------------*/ + +UINT16 +SbGetAlinkIoAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + UINT16 AlinkPortAddress; + GnbLibIndirectIoBlockRead (0xCD6, 0xCD7, AccessWidth8, 0xE0, 2, &AlinkPortAddress, StdHeader); + return AlinkPortAddress; +} diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h new file mode 100755 index 0000000000..ab311ceebc --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h @@ -0,0 +1,78 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39931 $ @e \$Date: 2010-10-16 18:19:16 -0700 (Sat, 16 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. +* *************************************************************************** +* +*/ +#ifndef _GNBSBLIB_H_ +#define _GNBSBLIB_H_ + +#include "GnbPcie.h" + +UINT32 +SbGetSbIoApicBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +SbGetSbMmioBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT16 +SbGetAlinkIoAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +SbPcieInitAspm ( + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +SbPcieLinkAspmControl ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c new file mode 100755 index 0000000000..a2ef67515b --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c @@ -0,0 +1,142 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB-SB link procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 01:16:51 -0800 (Wed, 22 Dec 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 "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbSbLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSBLIB_GNBSBPCIE_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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable/Disable ASPM on GNB-SB link + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +AGESA_STATUS +SbPcieLinkAspmControl ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + PCIE_ASPM_TYPE Aspm; + + Aspm = Engine->Type.Port.PortData.LinkAspm; + + Status = SbPcieInitAspm (Aspm, GnbLibGetHeader (Pcie)); + if (Status != AGESA_SUCCESS) { + return AGESA_UNSUPPORTED; + } + + PcieAspmEnableOnFunction (Engine->Type.Port.Address, Aspm, GnbLibGetHeader (Pcie)); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init SB ASPM. + * Enable ASPM states on SB + * + * + * @param[in] Aspm ASPM bitmap. + * @param[in] StdHeader Standard configuration header + */ +/*----------------------------------------------------------------------------------------*/ + +AGESA_STATUS +SbPcieInitAspm ( + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 AlinkPort; + + AlinkPort = SbGetAlinkIoAddress (StdHeader); + ASSERT (AlinkPort != 0); + if (AlinkPort == 0) { + return AGESA_UNSUPPORTED; + } + GnbLibIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x40000038, StdHeader); + GnbLibIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0x0, 0xA0, StdHeader); + GnbLibIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x4000003c, StdHeader); + GnbLibIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffff00ff, 0x6900, StdHeader); + GnbLibIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x80000068, StdHeader); + GnbLibIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xfffffffc, Aspm, StdHeader); + return AGESA_SUCCESS; +} + + |