diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Proc/GNB/Modules/GnbPcieInitLibV1')
28 files changed, 6246 insertions, 0 deletions
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 |