/* $NoKeywords:$ */ /** * @file * * Config and Train Fch Gpp Ports * * Init Gpp Controller features. * * @xrefitem bom "File Content Label" "Release Content" * @e project: AGESA * @e sub-project: FCH * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $ * */ /* ***************************************************************************** * * Copyright (c) 2008 - 2012, 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 "FchPlatform.h" #include "Ids.h" #include "Filecode.h" #define FILECODE PROC_FCH_PCIE_GPPPORTINIT_FILECODE // // Declaration of local functions // /** * GppPortPollingLtssmS3 - Loop polling the LTSSM for each GPP port marked in PortMap (New Algorithm S3) * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] ActivePorts A bitmap of ports which should be polled * @param[in] IsGen2 TRUE if the polling is in Gen2 mode * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * * @retval FailedPorts A bitmap of ports which failed to train * */ STATIC UINT8 GppPortPollingLtssmS3 ( IN FCH_GPP *FchGpp, IN UINT8 ActivePorts, IN BOOLEAN IsGen2, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 PortId; UINT8 FailedPorts; FCH_GPP_PORT_CONFIG *PortCfg; UINT32 AbIndex; UINT32 GppData32; UINT8 EmptyPorts; UINT8 RetryCounter; FailedPorts = 0; EmptyPorts = ActivePorts; RetryCounter = 2; while (RetryCounter-- ) { for (PortId = 0; PortId < MAX_GPP_PORTS; PortId++) { if (ActivePorts & (1 << PortId)) { PortCfg = &FchGpp->PortCfg[PortId]; if ( PortCfg->PortDetected == TRUE ) { AbIndex = FCH_RCINDXP_REGA5 | (UINT32) (PortId << 24); GppData32 = ReadAlink (AbIndex, StdHeader) & 0x3F3F3F3F; if ((UINT8) (GppData32) > 0x04) { EmptyPorts &= ~(1 << PortId); } if ((UINT8) (GppData32) == 0x10) { break; } } } } FchStall (180, StdHeader); } FailedPorts |= ActivePorts; return FailedPorts; } /** * PreInitGppLink - Enable GPP link training. * * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ STATIC VOID PreInitGppLink ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { GPP_LINKMODE CfgMode; UINT8 PortId; UINT32 GppPortCfg; UINT16 Tmp16Value; UINT8 GppS3Data; UINT8 HotPlugPorts; UINT8 PortMask[5] = { 0x01, 0x00, 0x03, 0x07, 0x0F }; HotPlugPorts = 0; // // PCIE_GPP_ENABLE (abcfg:0xC0): // // GPP_LINK_CONFIG ([3:0]) PortA PortB PortC PortD Description // ---------------------------------------------------------------------------------- // 0000 0-3 x4 Config // 0001 N/A // 0010 0-1 2-3 0 2:2 Config // 0011 0-1 2 3 2:1:1 Config // 0100 0 1 2 3 1:1:1:1 Config // // For A12 and above: // ABCFG:0xC0[12] - Port A hold training (default 1) // ABCFG:0xC0[13] - Port B hold training (default 1) // ABCFG:0xC0[14] - Port C hold training (default 1) // ABCFG:0xC0[15] - Port D hold training (default 1) // // // // Set port enable bit fields based on current GPP link configuration mode // CfgMode = FchGpp->GppLinkConfig; ASSERT (CfgMode == PortA4 || CfgMode == PortA2B2 || CfgMode == PortA2B1C1 || CfgMode == PortA1B1C1D1); GppPortCfg = (UINT32) PortMask[CfgMode]; // // Mask out non-applicable ports according to the target link configuration mode // for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { FchGpp->PortCfg[PortId].PortPresent &= (UINT8 ) (GppPortCfg >> PortId) & BIT0; if ( FchGpp->PortCfg[PortId].PortHotPlug == TRUE ) { HotPlugPorts |= ( 1 << PortId); } } // // Deassert GPP reset and pull EP out of reset - Clear GPP_RESET (abcfg:0xC0[8] = 0) // Tmp16Value = (UINT16) (~GppPortCfg << 12); GppPortCfg = (UINT32) (Tmp16Value + (GppPortCfg << 4) + CfgMode); WriteAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), GppPortCfg, StdHeader); GppPortCfg = ReadAlink (0xC0 | (UINT32) (RCINDXC << 29), StdHeader); WriteAlink (0xC0 | (UINT32) (RCINDXC << 29), GppPortCfg | 0x400, StdHeader); /// Set STRAP_F0_MSI_EN // // A-Link L1 Entry Delay Shortening // AXINDP_Reg 0xA0[7:4] = 0x3 // KR Does not need this portion of code. RwAlink (FCH_AX_INDXP_REGA0, 0xFFFFFF0F, 0x30, StdHeader); RwAlink (FCH_AX_INDXP_REGB1, 0xFFFFFFFF, BIT19, StdHeader); RwAlink (FCH_AX_INDXP_REGB1, 0xFFFFFFFF, BIT28, StdHeader); // // GPP L1 Entry Delay Shortening // RCINDP_Reg 0xA0[7:4] = 0x1 Enter L1 sooner after ACK'ing PM request. // This is done to reduce number of NAK received with L1 enabled. // for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { RwAlink (FCH_RCINDXP_REGA0 | PortId << 24, 0xFFFFFF0F, 0x10, StdHeader); // Hard System Hang running MeatGrinder Test on multiple blocks // GPP Error Reporting Configuration RwAlink (FCH_RCINDXP_REG6A | PortId << 24, (UINT32)~(BIT1), 0, StdHeader); } if (ReadFchSleepType (StdHeader) == ACPI_SLPTYP_S3) { ReadMem ( ACPI_MMIO_BASE + CMOS_RAM_BASE + 0x0D, AccessWidth8, &GppS3Data); for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { if ( GppS3Data & (1 << (PortId + 4))) { if ( GppS3Data & (1 << PortId)) { FchGppForceGen1 (FchGpp, (1 << PortId), StdHeader); } else { FchGppForceGen2 (FchGpp, (1 << PortId), StdHeader); } } } } // // Obtain original Gen2 strap value (LC_GEN2_EN_STRAP) // FchGpp->GppGen2Strap = (UINT8) (ReadAlink (FCH_RCINDXP_REGA4 | 0 << 24, StdHeader) & BIT0); FchGpp->HotPlugPortsStatus = HotPlugPorts; } /** * CheckGppLinkStatus - loop polling the link status for each GPP port * * * Return: ToggleStatus[3:0] = Port bitmap for those need to clear De-emphasis * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ STATIC UINT8 CheckGppLinkStatus ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 PortId; UINT8 PortScanMap; UINT8 GppHwDowngrade; FCH_GPP_PORT_CONFIG *PortCfg; UINT8 FailedPorts; PortScanMap = 0; FailedPorts = 0; // // Obtain a list of ports to be checked // for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { PortCfg = &FchGpp->PortCfg[PortId]; if ( PortCfg->PortPresent == TRUE && PortCfg->PortDetected == FALSE ) { PortScanMap |= 1 << PortId; } } GppHwDowngrade = (UINT8) FchGpp->GppHardwareDownGrade; if (GppHwDowngrade != 0) { // // Skip polling and always assume this port to be present // PortScanMap &= ~(1 << (GppHwDowngrade - 1)); } FchStall (5000, StdHeader); if (FchGpp->GppGen2 && FchGpp->GppGen2Strap) { AGESA_TESTPOINT (TpFchGppGen2PortPolling, StdHeader); FchGppForceGen2 (FchGpp, PortScanMap, StdHeader); FailedPorts = GppPortPollingLtssm (FchGpp, PortScanMap, TRUE, StdHeader); if (FailedPorts) { AGESA_TESTPOINT (TpFchGppGen1PortPolling, StdHeader); FchGppForceGen1 (FchGpp, FailedPorts, StdHeader); FailedPorts = GppPortPollingLtssm (FchGpp, FailedPorts, FALSE, StdHeader); } } else { AGESA_TESTPOINT (TpFchGppGen1PortPolling, StdHeader); FchGppForceGen1 (FchGpp, PortScanMap, StdHeader); FailedPorts = GppPortPollingLtssm (FchGpp, PortScanMap, FALSE, StdHeader); } return FailedPorts; } STATIC BOOLEAN FoundInfiniteCrs ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 PortId; UINT32 Value32; UINT32 RegBusNo; UINT32 FchTempBus; FCH_GPP_PORT_CONFIG *PortCfg; FchTempBus = GppGetFchTempBus (StdHeader); for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { PortCfg = &FchGpp->PortCfg[PortId]; if ( PortCfg->PortDetected == TRUE ) { RegBusNo = (FchTempBus << 16) + (FchTempBus << 8); WritePci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x18), AccessWidth32, &RegBusNo, StdHeader); ReadPci (PCI_ADDRESS (FchTempBus, 0, 0, 0x08), AccessWidth32, &Value32, StdHeader); RegBusNo = 0; WritePci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x18), AccessWidth32, &RegBusNo, StdHeader); if ( Value32 == 0xFFFFFFFF ) { return TRUE; } } } return FALSE; } /** * AfterGppLinkInit * - Search for display device behind each GPP port * - If the port is empty AND not hotplug-capable: * * Turn off link training * * (optional) Power down the port * * Hide the configuration space (Turn off the port) * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ STATIC VOID AfterGppLinkInit ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 PortId; FCH_GPP_PORT_CONFIG *PortCfg; UINT32 RegBusNumber; UINT32 FchTempBus; UINT32 AbValue; UINT32 AbIndex; UINT8 Value; FchGpp->GppFoundGfxDev = 0; AbValue = ReadAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), StdHeader); // // Link Bandwidth Notification Capability Enable //RCINDC:0xC1[0] = 1 // RwAlink (FCH_RCINDXC_REGC1, 0xFFFFFFFF, BIT0, StdHeader); for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { // // Program requester ID for every port // AbIndex = FCH_RCINDXP_REG21 | (UINT32) (PortId << 24); WriteAlink (AbIndex, (FCH_GPP_DEV << 3) + PortId, StdHeader); // // Link Bandwidth Notification Capability Enable //PCIe Cfg 0x68[10] = 0 //PCIe Cfg 0x68[11] = 0 // RwPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x68), AccessWidth16, (UINT32)~(BIT10 + BIT11), 0, StdHeader); PortCfg = &FchGpp->PortCfg[PortId]; // // Check if there is GFX device behind each GPP port // FchTempBus = GppGetFchTempBus (StdHeader); if ( PortCfg->PortDetected == TRUE ) { RegBusNumber = (FchTempBus << 16) + (FchTempBus << 8); WritePci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x18), AccessWidth32, &RegBusNumber, StdHeader); ReadPci (PCI_ADDRESS (FchTempBus, 0, 0, 0x0B), AccessWidth8, &Value, StdHeader); if ( Value == 3 ) { FchGpp->GppFoundGfxDev |= (1 << PortId); } RegBusNumber = 0; WritePci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x18), AccessWidth32, &RegBusNumber, StdHeader); } else if ( PortCfg->PortPresent == FALSE || PortCfg->PortHotPlug == FALSE ) { // // Mask off non-applicable ports // AbValue &= ~(1 << (PortId + 4)); } if ( PortCfg->PortHotPlug == TRUE ) { // // Hot Plug: PCIe Native Support // RCINDP_Reg 0x10[3] = 0x1 // PCIe_Cfg 0x5A[8] = 0x1 // PCIe_Cfg 0x6C[6] = 0x1 // RCINDP_Reg 0x20[19] = 0x0 // RwAlink ((FCH_RCINDXP_REG10 | (UINT32) (PortId << 24)), 0xFFFFFFFF, BIT3, StdHeader); RwPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x5b), AccessWidth8, 0xff, BIT0, StdHeader); RwPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x6c), AccessWidth8, 0xff, BIT6, StdHeader); RwAlink ((FCH_RCINDXP_REG20 | (UINT32) (PortId << 24)), (UINT32)~BIT19, 0, StdHeader); } } if ( FchGpp->GppUnhidePorts == FALSE ) { if ((AbValue & 0xF0) == 0) { //comment out the following line for BUG284426: GPP_RESET causes S3 resume hard hang on Pumori //AbValue = BIT8; // if all ports are empty set GPP_RESET } else if ((AbValue & 0xE0) != 0 && (AbValue & 0x10) == 0) { AbValue |= BIT4; // PortA should always be visible whenever other ports are exist } // // Update GPP_Portx_Enable (abcfg:0xC0[7:5]) // WriteAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), AbValue, StdHeader); } // // Common initialization for open GPP ports // for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { ReadPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x80), AccessWidth8, &Value, StdHeader); if (Value != 0xff) { // // Set pciCfg:PCIE_DEVICE_CNTL2[3:0] = 4'h6 (0x80[3:0]) // Value &= 0xf0; Value |= 0x06; WritePci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x80), AccessWidth8, &Value, StdHeader); // // Set PCIEIND_P:PCIE_RX_CNTL[RX_RCB_CPL_TIMEOUT_MODE] (0x70:[19]) = 1 // AbIndex = FCH_RCINDXP_REG70 | (UINT32) (PortId << 24); AbValue = ReadAlink (AbIndex, StdHeader) | BIT19; WriteAlink (AbIndex, AbValue, StdHeader); // // Set PCIEIND_P:PCIE_TX_CNTL[TX_FLUSH_TLP_DIS] (0x20:[19]) = 0 // AbIndex = FCH_RCINDXP_REG20 | (UINT32) (PortId << 24); AbValue = ReadAlink (AbIndex, StdHeader) & ~BIT19; WriteAlink (AbIndex, AbValue, StdHeader); // // Set Immediate Ack PM_Active_State_Request_L1 (0xA0:[23]) = 1 // AbIndex = FCH_RCINDXP_REGA0 | (UINT32) (PortId << 24); AbValue = ReadAlink (AbIndex, StdHeader) & ~BIT23; if ( FchGpp->GppL1ImmediateAck == 0) { AbValue |= BIT23; } WriteAlink (AbIndex, AbValue, StdHeader); } } } /** * FchGppAerInitialization - Initializing AER * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ STATIC VOID FchGppAerInitialization ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { if (FchGpp->PcieAer) { // // GPP strap configuration // RwAlink (0x310 | (UINT32) (ABCFG << 29), (UINT32)~(BIT7 + BIT4), BIT28 + BIT27 + BIT26 + BIT1, StdHeader); RwAlink (0x314 | (UINT32) (ABCFG << 29), ~(UINT32) (0xfff << 15), 0, StdHeader); // // AB strap configuration // RwAlink (FCH_ABCFG_REGF0 | (UINT32) (ABCFG << 29), 0xFFFFFFFF, BIT15 + BIT14, StdHeader); RwAlink (FCH_ABCFG_REGF4 | (UINT32) (ABCFG << 29), 0xFFFFFFFF, BIT3, StdHeader); } else { // // Hard System Hang running MeatGrinder Test on multiple blocks // GPP Error Reporting Configuration RwAlink (FCH_ABCFG_REGF0 | (UINT32) (ABCFG << 29), (UINT32)~(BIT1), 0, StdHeader); } } /** * FchGppRasInitialization - Initializing RAS * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ STATIC VOID FchGppRasInitialization ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { if (FchGpp->PcieRas) { RwAlink (FCH_ABCFG_REGF4 | (UINT32) (ABCFG << 29), 0xFFFFFFFF, BIT0, StdHeader); } } /** * FchGppPortInit - GPP port training and initialization * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ VOID FchGppPortInit ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { // // GppEarlyInit // UINT32 AbValue; UINT8 ResetCounter; UINT8 FailPorts; AGESA_TESTPOINT (TpFchGppBeforePortTraining, StdHeader); // // Configure NB-FCH link PCIE PHY PLL power down for L1 // if ( FchGpp->UmiPhyPllPowerDown == TRUE ) { // // Set PCIE_P_CNTL in Alink PCIEIND space // WriteAlink (FCH_AX_INDXC_REG30 | (UINT32) (AXINDC << 29), 0x40, StdHeader); AbValue = ReadAlink (FCH_AX_DATAC_REG34 | (UINT32) (AXINDC << 29), StdHeader); AbValue |= BIT12 + BIT3 + BIT0; AbValue &= (UINT32)~(BIT9 + BIT4); WriteAlink (FCH_AX_DATAC_REG34 | (UINT32) (AXINDC << 29), AbValue, StdHeader); RwAlink (FCH_AX_INDXC_REG02 | (UINT32) (AXINDC << 29), (UINT32)~(BIT8), (BIT8), StdHeader); RwAlink (FCH_AX_INDXC_REG02 | (UINT32) (AXINDC << 29), (UINT32)~(BIT3), (BIT3), StdHeader); } // // AXINDC_Reg 0xA4[18] = 0x1 // WriteAlink (FCH_AX_INDXP_REG38 | (UINT32) (AXINDP << 29), 0xA4, StdHeader); AbValue = ReadAlink (FCH_AX_DATAP_REG3C | (UINT32) (AXINDP << 29), StdHeader); AbValue |= BIT18; WriteAlink (FCH_AX_DATAP_REG3C | (UINT32) (AXINDP << 29), AbValue, StdHeader); // // Set ABCFG 0x031C[0] = 1 to enable lane reversal // AbValue = ReadAlink (FCH_ABCFG_REG31C | (UINT32) (ABCFG << 29), StdHeader); if ( FchGpp->GppLaneReversal == TRUE ) { WriteAlink (FCH_ABCFG_REG31C | (UINT32) (ABCFG << 29), AbValue | BIT0, StdHeader); } else { WriteAlink (FCH_ABCFG_REG31C | (UINT32) (ABCFG << 29), AbValue | 0x00, StdHeader); } // // Set abcfg:0x90[20] = 1 to enable GPP bridge multi-function // AbValue = ReadAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), StdHeader); WriteAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), AbValue | BIT20, StdHeader); // // Initialize and configure GPP // if (FchGpp->GppFunctionEnable) { if (( FchGpp->NewGppAlgorithm == FALSE ) || ( (ReadFchSleepType (StdHeader) != ACPI_SLPTYP_S3) )) { ProgramGppTogglePcieReset (FchGpp->GppToggleReset, StdHeader); } FchGppAerInitialization (FchGpp, StdHeader); FchGppRasInitialization (FchGpp, StdHeader); // // PreInit - Enable GPP link training // if (( FchGpp->NewGppAlgorithm == FALSE ) || ( (ReadFchSleepType (StdHeader) != ACPI_SLPTYP_S3) )) { PreInitGppLink (FchGpp, StdHeader); } // // GPP Upstream Memory Write Arbitration Enhancement ABCFG 0x54[26] = 1 // GPP Memory Write Max Payload Improvement RCINDC_Reg 0x10[12:10] = 0x4 // if ( FchGpp->GppMemWrImprove == TRUE ) { RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), (UINT32)~BIT26, (BIT26), StdHeader); RwAlink (FCH_RCINDXC_REG10, (UINT32)~(BIT12 + BIT11 + BIT10), (BIT12), StdHeader); } if ( FchGpp->NewGppAlgorithm == TRUE ) { if (ReadFchSleepType (StdHeader) == ACPI_SLPTYP_S3) { if ( FchGpp->HotPlugPortsStatus == 0 ) { // S3 Procedure FchStall (5000, StdHeader); FailPorts = FchGpp->FailPortsStatus; if ( FchGpp->FailPortsStatus != 0 ) { AGESA_TESTPOINT (TpFchGppGen1PortPolling, StdHeader); FchGppForceGen1 (FchGpp, FailPorts, StdHeader); } } } } else { ResetCounter = 3; while (ResetCounter--) { FailPorts = CheckGppLinkStatus (FchGpp, StdHeader); if (FoundInfiniteCrs (FchGpp, StdHeader)) { ProgramGppTogglePcieReset (TRUE, StdHeader); } else if ((FailPorts != 0) && (ReadFchSleepType (StdHeader) != ACPI_SLPTYP_S3)) { ProgramGppTogglePcieReset (FchGpp->GppToggleReset, StdHeader); } else { break; } } } // // Misc operations after link training // if ( FchGpp->NewGppAlgorithm == FALSE ) { AfterGppLinkInit (FchGpp, StdHeader); } } if ( FchGpp->NewGppAlgorithm == FALSE ) { FchGppDynamicPowerSaving (FchGpp, StdHeader); AGESA_TESTPOINT (TpFchGppAfterPortTraining, StdHeader); } } /** * FchGppPortInitS3Phase - GPP port training and initialization S3 phase for new algorithm * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ VOID FchGppPortInitS3Phase ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 ResetCounter; UINT8 FailPorts; if (FchGpp->GppFunctionEnable) { ProgramGppTogglePcieReset (FchGpp->GppToggleReset, StdHeader); PreInitGppLink (FchGpp, StdHeader); // For S3 With HotPlug port setting. if ( FchGpp->HotPlugPortsStatus != 0 ) { ResetCounter = 3; while (ResetCounter--) { FailPorts = CheckGppLinkStatus (FchGpp, StdHeader); if (FoundInfiniteCrs (FchGpp, StdHeader)) { ProgramGppTogglePcieReset (TRUE, StdHeader); } else if (FailPorts != 0) { ProgramGppTogglePcieReset (FchGpp->GppToggleReset, StdHeader); } else { break; } } AfterGppLinkInit (FchGpp, StdHeader); } } } /** * FchGppPortInitPhaseII - GPP port training and initialization phase II for new algorithm * * * @param[in] FchGpp Pointer to Fch GPP configuration structure * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS * */ VOID FchGppPortInitPhaseII ( IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 ResetCounter; UINT8 FailPorts; UINT8 HotPlugPorts; if (FchGpp->GppFunctionEnable) { // // Check Link status for the new algorithm // HotPlugPorts = 0; FailPorts = 0; // // Read previously HotPlug port status // if ( ReadFchSleepType (StdHeader) == ACPI_SLPTYP_S3) { if ( FchGpp->HotPlugPortsStatus == 0 ) { FailPorts = FchGpp->FailPortsStatus; FailPorts = GppPortPollingLtssmS3 (FchGpp, FailPorts, FALSE, StdHeader); AfterGppLinkInit (FchGpp, StdHeader); } } else { ResetCounter = 3; while (ResetCounter--) { FailPorts = CheckGppLinkStatus (FchGpp, StdHeader); if (FoundInfiniteCrs (FchGpp, StdHeader)) { ProgramGppTogglePcieReset (TRUE, StdHeader); } else if ((FailPorts != 0) && (ReadFchSleepType (StdHeader) != ACPI_SLPTYP_S3)) { // CMOS record need FchGpp->FailPortsStatus = FailPorts; ProgramGppTogglePcieReset (FchGpp->GppToggleReset, StdHeader); } else { // CMOS clear need FchGpp->FailPortsStatus = FailPorts; break; } } AfterGppLinkInit (FchGpp, StdHeader); } } FchGppDynamicPowerSaving (FchGpp, StdHeader); AGESA_TESTPOINT (TpFchGppAfterPortTraining, StdHeader); }