aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c')
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c463
1 files changed, 463 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c
new file mode 100644
index 0000000000..61b07250a6
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c
@@ -0,0 +1,463 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * KB specific PCIe services
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 87645 $ @e \$Date: 2013-02-06 13:08:17 -0600 (Wed, 06 Feb 2013) $
+ *
+ */
+/*
+*****************************************************************************
+*
+ * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* ***************************************************************************
+*
+*/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "Ids.h"
+#include "heapManager.h"
+#include "Gnb.h"
+#include "GnbPcie.h"
+#include "GnbSbLib.h"
+#include "GnbCommonLib.h"
+#include "GnbPcieInitLibV1.h"
+#include "GnbPcieInitLibV5.h"
+#include "GnbPcieConfig.h"
+#include "GnbPcieTrainingV2.h"
+#include "GnbNbInitLibV4.h"
+#include "GnbNbInitLibV1.h"
+#include "GnbNbInitLibV5.h"
+#include "PcieComplexDataKB.h"
+#include "PcieLibKB.h"
+#include "GnbRegistersKB.h"
+#include "GnbRegisterAccKB.h"
+#include "GnbF1Table.h"
+#include "Filecode.h"
+#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIELIBKB_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
+ *----------------------------------------------------------------------------------------
+ */
+PCIE_LINK_SPEED_CAP
+PcieGetLinkSpeedCapKB (
+ IN UINT32 Flags,
+ IN PCIe_ENGINE_CONFIG *Engine
+ );
+
+UINT32
+GnbTimeStampKB (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+UINT8
+PcieMaxPayloadKB (
+ IN PCIe_ENGINE_CONFIG *Engine
+ );
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PLL powerdown
+ *
+ *
+ * @param[in] Wrapper Pointer to Wrapper config descriptor
+ * @param[in] Pcie Pointer to PICe configuration data area
+ */
+
+VOID
+PciePifPllConfigureKB (
+ IN PCIe_WRAPPER_CONFIG *Wrapper,
+ IN PCIe_PLATFORM_CONFIG *Pcie
+ )
+{
+ D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012;
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllConfigureKB Enter\n");
+ D0F0xE4_PIF_0012.Value = PcieRegisterRead (
+ Wrapper,
+ PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS),
+ Pcie
+ );
+
+ D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x0;
+
+ if (Wrapper->Features.PowerOffUnusedPlls != 0) {
+ D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff;
+ D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff;
+ } else {
+ D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateL0;
+ D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateL0;
+ }
+
+ if (Wrapper->Features.PllOffInL1 != 0) {
+ D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateLS2;
+ D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateLS2;
+ } else {
+ D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateL0;
+ D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateL0;
+ }
+
+ PcieRegisterWrite (
+ Wrapper,
+ PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS),
+ D0F0xE4_PIF_0012.Value,
+ TRUE,
+ Pcie
+ );
+ PcieRegisterWrite (
+ Wrapper,
+ PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + 1),
+ D0F0xE4_PIF_0012.Value,
+ TRUE,
+ Pcie
+ );
+ IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllConfigureKB Exit\n");
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Power down unused lanes and plls
+ *
+ *
+ * @param[in] Wrapper Pointer to wrapper config descriptor
+ * @param[in] Pcie Pointer to global PCIe configuration
+ */
+
+VOID
+PciePwrPowerDownUnusedLanesKB (
+ IN PCIe_WRAPPER_CONFIG *Wrapper,
+ IN PCIe_PLATFORM_CONFIG *Pcie
+ )
+{
+ UINT32 UnusedLanes;
+ IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanesKB Enter\n");
+ if (Wrapper->Features.PowerOffUnusedLanes != 0) {
+ UnusedLanes = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE, Wrapper);
+ PcieTopologyLaneControlV5 (
+ DisableLanes,
+ UnusedLanes,
+ Wrapper,
+ Pcie
+ );
+ }
+ IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanesKB Exit\n");
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Request boot up voltage
+ *
+ *
+ *
+ * @param[in] LinkCap Global GEN capability
+ * @param[in] Pcie Pointer to PCIe configuration data area
+ */
+VOID
+PcieSetVoltageKB (
+ IN PCIE_LINK_SPEED_CAP LinkCap,
+ IN PCIe_PLATFORM_CONFIG *Pcie
+ )
+{
+ UINT8 TargetVid;
+ UINT8 MinVidIndex;
+ UINT8 PP_FUSE_ARRAY_V2_fld32[5];
+ UINT8 Index;
+ PP_F1_ARRAY_V2 *PpF1Array;
+ UINT32 Millivolt;
+ UINT32 D0F0xBC_xC0104007;
+ UINT32 D0F0xBC_xC0104008;
+ UINT32 D0F0xBC_xC010407C;
+ UINT32 D0F0xBC_xC0107064;
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetVoltageKB Enter\n");
+ PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Pcie));
+ if (PpF1Array == NULL) {
+ GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0104007, &D0F0xBC_xC0104007, 0, GnbLibGetHeader (Pcie));
+ GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0104008, &D0F0xBC_xC0104008, 0, GnbLibGetHeader (Pcie));
+ GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC010407C, &D0F0xBC_xC010407C, 0, GnbLibGetHeader (Pcie));
+ GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0107064, &D0F0xBC_xC0107064, 0, GnbLibGetHeader (Pcie));
+ PP_FUSE_ARRAY_V2_fld32[0] = (UINT8) ((D0F0xBC_xC0104007 >> 5) & 0xFF);
+ PP_FUSE_ARRAY_V2_fld32[1] = (UINT8) ((D0F0xBC_xC0104008 >> 5) & 0xFF);
+ PP_FUSE_ARRAY_V2_fld32[2] = (UINT8) ((D0F0xBC_xC0104008 >> 13) & 0xFF);
+ PP_FUSE_ARRAY_V2_fld32[3] = (UINT8) ((D0F0xBC_xC0104008 >> 21) & 0xFF);
+ PP_FUSE_ARRAY_V2_fld32[4] = (UINT8) ((D0F0xBC_xC010407C >> 20) & 0xFF);
+ Index = (UINT8) ((D0F0xBC_xC0107064 >> 11) & 7);
+ } else {
+ PP_FUSE_ARRAY_V2_fld32[0] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[0];
+ PP_FUSE_ARRAY_V2_fld32[1] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[1];
+ PP_FUSE_ARRAY_V2_fld32[2] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[2];
+ PP_FUSE_ARRAY_V2_fld32[3] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[3];
+ PP_FUSE_ARRAY_V2_fld32[4] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[4];
+ Index = PpF1Array->PcieGen2Vid;
+ }
+ if (LinkCap > PcieGen1) {
+ ASSERT (PP_FUSE_ARRAY_V2_fld32[Index] != 0);
+ TargetVid = PP_FUSE_ARRAY_V2_fld32[Index];
+ } else {
+
+ MinVidIndex = 0;
+ for (Index = 0; Index < 5; Index++) {
+ if (PP_FUSE_ARRAY_V2_fld32[Index] > PP_FUSE_ARRAY_V2_fld32[MinVidIndex]) {
+ MinVidIndex = (UINT8) Index;
+ }
+ }
+ ASSERT (PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0);
+ TargetVid = PP_FUSE_ARRAY_V2_fld32[MinVidIndex];
+ }
+
+ IDS_HDT_CONSOLE (PCIE_MISC, " Set Voltage for Gen %d, Vid code %d\n", LinkCap, TargetVid);
+ Millivolt = GnbTranslateVidCodeToMillivoltV5 (TargetVid, GnbLibGetHeader (Pcie)) * 4 / 100;
+ GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), TYPE_SMU_MSG, SMC_MSG_VDDNB_REQUEST, &Millivolt, 0, GnbLibGetHeader (Pcie));
+ IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetVoltageKB Exit\n");
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PLL power up latency
+ *
+ *
+ * @param[in] Wrapper Pointer to Wrapper config descriptor
+ * @param[in] Pcie Pointer to PICe configuration data area
+ * @retval Pll wake up latency in us
+ */
+UINT8
+PciePifGetPllPowerUpLatencyKB (
+ IN PCIe_WRAPPER_CONFIG *Wrapper,
+ IN PCIe_PLATFORM_CONFIG *Pcie
+ )
+{
+ return 35;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get max link speed capability supported by this port
+ *
+ *
+ *
+ * @param[in] Flags See Flags PCIE_PORT_GEN_CAP_BOOT / PCIE_PORT_GEN_CAP_MAX
+ * @param[in] Engine Pointer to engine config descriptor
+ * @retval PcieGen1/PcieGen2 Max supported link gen capability
+ */
+PCIE_LINK_SPEED_CAP
+PcieGetLinkSpeedCapKB (
+ IN UINT32 Flags,
+ IN PCIe_ENGINE_CONFIG *Engine
+ )
+{
+ PCIE_LINK_SPEED_CAP LinkSpeedCapability;
+ PCIe_WRAPPER_CONFIG *Wrapper;
+ PCIe_PLATFORM_CONFIG *Pcie;
+
+ Wrapper = PcieConfigGetParentWrapper (Engine);
+ Pcie = PcieConfigGetPlatform (Wrapper);
+
+ LinkSpeedCapability = PcieGen2;
+
+ if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGenMaxSupported) {
+ Engine->Type.Port.PortData.LinkSpeedCapability = (UINT8) LinkSpeedCapability;
+ }
+ if (Pcie->PsppPolicy == PsppPowerSaving) {
+ LinkSpeedCapability = PcieGen1;
+ }
+ if (Engine->Type.Port.PortData.LinkSpeedCapability < LinkSpeedCapability) {
+ LinkSpeedCapability = Engine->Type.Port.PortData.LinkSpeedCapability;
+ }
+ if ((Flags & PCIE_PORT_GEN_CAP_BOOT) != 0) {
+
+ if (( Pcie->PsppPolicy == PsppBalanceLow ||
+ Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1)
+ && !PcieConfigIsSbPcieEngine (Engine)) {
+
+ LinkSpeedCapability = PcieGen1;
+ }
+ }
+ return LinkSpeedCapability;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Family specific time stamp function
+ *
+ *
+ * @param[in] StdHeader Standard configuration header
+ * @retval Count
+ */
+UINT32
+GnbTimeStampKB (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TimeStamp;
+
+ TimeStamp = 0;
+
+ GnbLibPciIndirectRead (
+ MAKE_SBDFO (0, 0, 0, 0, 0xE0),
+ 0x13080F0,
+ AccessWidth32,
+ &TimeStamp,
+ StdHeader
+ );
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "GnbTsKb: %08x\n", TimeStamp);
+ return TimeStamp;
+
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Limit MaxPayload to 256 for x1 ports
+ *
+ *
+ *
+ * @param[in] Engine Pointer to engine config descriptor
+ * @retval MaxPayload MaxPayloadSupport
+ */
+UINT8
+PcieMaxPayloadKB (
+ IN PCIe_ENGINE_CONFIG *Engine
+ )
+{
+ UINT8 MaxPayload;
+
+ MaxPayload = MAX_PAYLOAD_512;
+ if (Engine->EngineData.StartLane == Engine->EngineData.EndLane) {
+ MaxPayload = MAX_PAYLOAD_256;
+ }
+ IDS_HDT_CONSOLE (GNB_TRACE, "PcieMaxPayloadKB Exit with MaxPayload = %d for StartLane = %d and EndLane = %d\n", MaxPayload, Engine->EngineData.StartLane, Engine->EngineData.EndLane);
+ return MaxPayload;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Select master PLL
+ *
+ *
+ *
+ * @param[in] Wrapper Pointer to wrapper config descriptor
+ * @param[out] ConfigChanged Pointer to boolean indicator that configuration was changed
+ * @param[in] Pcie Pointer to global PCIe configuration
+ */
+
+VOID
+PcieTopologySelectMasterPllKB (
+ IN PCIe_WRAPPER_CONFIG *Wrapper,
+ OUT BOOLEAN *ConfigChanged,
+ IN PCIe_PLATFORM_CONFIG *Pcie
+ )
+{
+ PCIe_ENGINE_CONFIG *EngineList;
+ UINT16 MasterLane;
+ UINT16 MasterHotplugLane;
+ UINT16 EngineMasterLane;
+ D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013;
+ D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013_BASE;
+ IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n");
+ MasterLane = 0xFFFF;
+ MasterHotplugLane = 0xFFFF;
+ EngineList = PcieConfigGetChildEngine (Wrapper);
+ while (EngineList != NULL) {
+ if (PcieConfigIsEngineAllocated (EngineList) && EngineList->Type.Port.PortData.PortPresent != PortDisabled && PcieConfigIsPcieEngine (EngineList)) {
+ EngineMasterLane = PcieConfigGetPcieEngineMasterLane (EngineList);
+ if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) {
+ MasterHotplugLane = (EngineMasterLane < MasterHotplugLane) ? EngineMasterLane : MasterHotplugLane;
+ } else {
+ MasterLane = (EngineMasterLane < MasterLane) ? EngineMasterLane : MasterLane;
+ 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
+ );
+ D0F0xE4_WRAP_8013_BASE.Value = D0F0xE4_WRAP_8013.Value;
+
+ if (MasterLane <= 3 ) {
+ Wrapper->MasterPll = GNB_PCIE_MASTERPLL_A;
+ } else {
+ Wrapper->MasterPll = GNB_PCIE_MASTERPLL_B;
+ }
+
+ IDS_OPTION_HOOK (IDS_GNB_PCIE_MASTERPLL_SELECTION, &(Wrapper->MasterPll), GnbLibGetHeader (Pcie));
+
+ if (Wrapper->MasterPll == GNB_PCIE_MASTERPLL_A) {
+ D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1;
+ D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0;
+ } else {
+ D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0;
+ D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1;
+ }
+
+ if (ConfigChanged != NULL) {
+ *ConfigChanged = (D0F0xE4_WRAP_8013.Value == D0F0xE4_WRAP_8013_BASE.Value) ? FALSE : TRUE;
+ }
+ PcieRegisterWrite (
+ Wrapper,
+ WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS),
+ D0F0xE4_WRAP_8013.Value,
+ FALSE,
+ Pcie
+ );
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Exit\n");
+}
+