| /* $NoKeywords:$ */ |
| /** |
| * @file |
| * |
| * Config Fch Gpp controller |
| * |
| * Init Gpp Controller features. |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: AGESA |
| * @e sub-project: FCH |
| * @e \$Revision: 49753 $ @e \$Date: 2011-03-29 04:51:46 +0800 (Tue, 29 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 "FchPlatform.h" |
| #include "Ids.h" |
| #include "Filecode.h" |
| #define FILECODE PROC_FCH_PCIE_GPPENV_FILECODE |
| // |
| // Declaration of local functions |
| // |
| VOID FchGppRasInitialization (IN FCH_DATA_BLOCK* FchDataPtr); |
| VOID FchGppAerInitialization (IN FCH_DATA_BLOCK* FchDataPtr); |
| VOID PreInitGppLink (IN FCH_DATA_BLOCK* FchDataPtr); |
| UINT8 CheckGppLinkStatus (IN FCH_DATA_BLOCK* FchDataPtr); |
| VOID AfterGppLinkInit (IN FCH_DATA_BLOCK* FchDataPtr); |
| |
| // |
| //----------------------------------------------------------------------------------- |
| // Early GPP initialization sequence: |
| // |
| // 1) Set port enable bit fields by current GPP link configuration mode |
| // 2) Deassert GPP reset and pull EP out of reset - Clear GPP_RESET (abcfg:0xC0[8] = 0) |
| // 3) Loop polling for the link status of all ports |
| // 4) Misc operations after link training: |
| // - (optional) Detect GFX device |
| // - Hide empty GPP configuration spaces (Disable empty GPP ports) |
| // - (optional) Power down unused GPP ports |
| // - (optional) Configure PCIE_P2P_Int_Map (abcfg:0xC4[7:0]) |
| // 5) GPP init completed |
| // |
| // |
| // *) Gen2 vs Gen1 |
| // Gen2 mode Gen1 mode |
| // --------------------------------------------------------------- |
| // STRAP_PHY_PLL_CLKF[6:0] 7'h32 7'h19 |
| // STRAP_BIF_GEN2_EN 1 0 |
| // |
| // PCIE_PHY_PLL clock locks @ 5GHz |
| // |
| // |
| |
| /** |
| * FchInitEnvGpp - Config Gpp controller before PCI emulation |
| * |
| * - GppEarlyInit |
| * |
| * @param[in] FchDataPtr Fch configuration structure pointer. |
| * |
| */ |
| VOID |
| FchInitEnvGpp ( |
| IN VOID *FchDataPtr |
| ) |
| { |
| // |
| // GppEarlyInit |
| // |
| UINT8 FchGppMemWrImprove; |
| UINT8 FchGppLaneReversal; |
| UINT8 FchAlinkPhyPllPowerDown; |
| UINT32 AbValue; |
| FCH_DATA_BLOCK *LocalCfgPtr; |
| AMD_CONFIG_PARAMS *StdHeader; |
| |
| LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; |
| StdHeader = LocalCfgPtr->StdHeader; |
| |
| FchGppMemWrImprove = LocalCfgPtr->Gpp.GppMemWrImprove; |
| FchGppLaneReversal = (UINT8) LocalCfgPtr->Gpp.GppLaneReversal; |
| FchAlinkPhyPllPowerDown = (UINT8) LocalCfgPtr->Ab.UmiPhyPllPowerDown; |
| |
| OutPort80 (0x90, StdHeader); |
| |
| // |
| // Configure NB-FCH link PCIE PHY PLL power down for L1 |
| // |
| if ( FchAlinkPhyPllPowerDown == 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 &= ~(BIT9 + BIT4); |
| WriteAlink (FCH_AX_DATAC_REG34 | (UINT32) (AXINDC << 29), AbValue, StdHeader); |
| RwAlink (FCH_AX_INDXC_REG02 | (UINT32) (AXINDC << 29), ~(BIT8), (BIT8), StdHeader); |
| RwAlink (FCH_AX_INDXC_REG02 | (UINT32) (AXINDC << 29), ~(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 ( FchGppLaneReversal ) { |
| 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 (LocalCfgPtr->Gpp.GppFunctionEnable) { |
| ProgramGppTogglePcieReset (LocalCfgPtr->Gpp.GppToggleReset, StdHeader); |
| FchGppAerInitialization (LocalCfgPtr); |
| FchGppRasInitialization (LocalCfgPtr); |
| |
| // |
| // PreInit - Enable GPP link training |
| // |
| PreInitGppLink (LocalCfgPtr); |
| |
| // |
| // GPP Upstream Memory Write Arbitration Enhancement ABCFG 0x54[26] = 1 |
| // GPP Memory Write Max Payload Improvement RCINDC_Reg 0x10[12:10] = 0x4 |
| // |
| if ( FchGppMemWrImprove == TRUE ) { |
| RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~BIT26, (BIT26), StdHeader); |
| RwAlink (FCH_RCINDXC_REG10 | (UINT32) (RCINDXC << 29), ~(BIT12 + BIT11 + BIT10), (BIT12), StdHeader); |
| } |
| |
| if (CheckGppLinkStatus (LocalCfgPtr) && !LocalCfgPtr->Misc.S3Resume) { |
| // |
| // Toggle GPP reset (Note this affects all Hudson-2 GPP ports) |
| // |
| ProgramGppTogglePcieReset (LocalCfgPtr->Gpp.GppToggleReset, StdHeader); |
| } |
| |
| // |
| // Misc operations after link training |
| // |
| AfterGppLinkInit (LocalCfgPtr); |
| } |
| FchGppDynamicPowerSaving (LocalCfgPtr); |
| |
| OutPort80 (0x9F, StdHeader); |
| } |
| |
| /** |
| * FchGppAerInitialization - Initializing AER |
| * |
| * |
| * @param[in] FchDataPtr |
| * |
| */ |
| VOID |
| FchGppAerInitialization ( |
| IN FCH_DATA_BLOCK *FchDataPtr |
| ) |
| { |
| AMD_CONFIG_PARAMS *StdHeader; |
| |
| StdHeader = FchDataPtr->StdHeader; |
| |
| if (FchDataPtr->Gpp.PcieAer) { |
| // |
| // GPP strap configuration |
| // |
| RwAlink (FCH_ABCFG_REG310 | (UINT32) (ABCFG << 29), ~(BIT7 + BIT4), BIT28 + BIT27 + BIT26 + BIT1, StdHeader); |
| RwAlink (FCH_ABCFG_REG314 | (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), ~(BIT1), 0, StdHeader); |
| } |
| |
| } |
| |
| /** |
| * FchGppRasInitialization - Initializing RAS |
| * |
| * |
| * @param[in] FchDataPtr |
| * |
| */ |
| VOID |
| FchGppRasInitialization ( |
| IN FCH_DATA_BLOCK *FchDataPtr |
| ) |
| { |
| if (FchDataPtr->Gpp.PcieRas) { |
| RwAlink (FCH_ABCFG_REGF4 | (UINT32) (ABCFG << 29), 0xFFFFFFFF, BIT0, FchDataPtr->StdHeader); |
| } |
| } |
| |
| /** |
| * PreInitGppLink - Enable GPP link training. |
| * |
| * |
| * |
| * @param[in] FchDataPtr Fch configuration structure pointer. |
| * |
| */ |
| VOID |
| PreInitGppLink ( |
| IN FCH_DATA_BLOCK *FchDataPtr |
| ) |
| { |
| GPP_LINKMODE CfgMode; |
| UINT8 PortId; |
| UINT32 GppPortCfg; |
| UINT16 Tmp16Value; |
| FCH_GPP_PORT_CONFIG *PortCfg; |
| AMD_CONFIG_PARAMS *StdHeader; |
| |
| UINT8 PortMask[5] = { |
| 0x01, |
| 0x00, |
| 0x03, |
| 0x07, |
| 0x0F |
| }; |
| |
| // |
| // 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 = FchDataPtr->Gpp.GppLinkConfig; |
| StdHeader = FchDataPtr->StdHeader; |
| |
| 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++ ) { |
| FchDataPtr->Gpp.PortCfg[PortId].PortPresent &= (UINT8 ) (GppPortCfg >> PortId) & BIT0; |
| } |
| |
| // |
| // 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, ~(BIT1), 0, StdHeader); |
| } |
| |
| if (FchDataPtr->Misc.S3Resume) { |
| for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { |
| PortCfg = &FchDataPtr->Gpp.PortCfg[PortId]; |
| if (PortCfg->PortHotPlug == TRUE) { |
| PortCfg->PortDetected = FALSE; |
| } else { |
| if (PortCfg->PortIsGen2 == 1) { |
| FchGppForceGen1 (FchDataPtr, (UINT8) (1 << PortId)); |
| } else { |
| FchGppForceGen2 (FchDataPtr, (UINT8) (1 << PortId)); |
| } |
| } |
| } |
| } |
| |
| // |
| // Obtain original Gen2 strap value (LC_GEN2_EN_STRAP) |
| // |
| FchDataPtr->Gpp.GppGen2Strap = (UINT8) (ReadAlink (FCH_RCINDXP_REGA4 | 0 << 24, StdHeader) & BIT0); |
| } |
| |
| /** |
| * 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] FchDataPtr Fch configuration structure pointer. |
| * |
| */ |
| UINT8 |
| CheckGppLinkStatus ( |
| IN FCH_DATA_BLOCK *FchDataPtr |
| ) |
| { |
| 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 = &FchDataPtr->Gpp.PortCfg[PortId]; |
| if ( PortCfg->PortPresent == TRUE && PortCfg->PortDetected == FALSE ) { |
| PortScanMap |= 1 << PortId; |
| } |
| } |
| |
| GppHwDowngrade = (UINT8)FchDataPtr->Gpp.GppHardwareDownGrade; |
| if (GppHwDowngrade != 0) { |
| // |
| // Skip polling and always assume this port to be present |
| // |
| PortScanMap &= ~(1 << (GppHwDowngrade - 1)); |
| } |
| |
| // |
| //GPP Gen2 Speed Change |
| // if ((GPP Gen2 == enabled) and (RCINDP_Reg 0xA4[0] == 0x1)) { |
| // PCIe_Cfg 0x88[3:0] = 0x2 |
| // RCINDP_Reg 0xA2[13] = 0x0 |
| // RCINDP_Reg 0xC0[15] = 0x0 |
| // RCINDP_Reg 0xA4[29] = 0x1 |
| // } else { |
| // PCIe_Cfg 0x88[3:0] = 0x1 |
| // RCINDP_Reg 0xA4[0] = 0x0 |
| // RCINDP_Reg 0xA2[13] = 0x1 |
| // RCINDP_Reg 0xC0[15] = 0x0 |
| // RCINDP_Reg 0xA4[29] = 0x1 |
| // } |
| // |
| FchStall (5000, FchDataPtr->StdHeader); |
| if (FchDataPtr->Gpp.GppGen2 && FchDataPtr->Gpp.GppGen2Strap) { |
| FchGppForceGen2 (FchDataPtr, PortScanMap); |
| FailedPorts = GppPortPollingLtssm (FchDataPtr, PortScanMap, TRUE); |
| |
| if (FailedPorts) { |
| FchGppForceGen1 (FchDataPtr, FailedPorts); |
| FailedPorts = GppPortPollingLtssm (FchDataPtr, FailedPorts, FALSE); |
| } |
| } else { |
| FchGppForceGen1 (FchDataPtr, PortScanMap); |
| FailedPorts = GppPortPollingLtssm (FchDataPtr, PortScanMap, FALSE); |
| } |
| return FailedPorts; |
| } |
| |
| /** |
| * 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] FchDataPtr Fch configuration structure pointer. |
| * |
| */ |
| VOID |
| AfterGppLinkInit ( |
| IN FCH_DATA_BLOCK *FchDataPtr |
| ) |
| { |
| UINT32 PortId; |
| FCH_GPP_PORT_CONFIG *PortCfg; |
| UINT32 RegBusNumber; |
| UINT32 AbValue; |
| UINT32 AbIndex; |
| UINT8 Value; |
| UINT8 FchGppGen2; |
| AMD_CONFIG_PARAMS *StdHeader; |
| |
| StdHeader = FchDataPtr->StdHeader; |
| FchGppGen2 = FchDataPtr->Gpp.GppGen2; |
| |
| FchDataPtr->Gpp.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) (RCINDXP << 29) | (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, ~(BIT10 + BIT11), 0, StdHeader); |
| |
| PortCfg = &FchDataPtr->Gpp.PortCfg[PortId]; |
| // |
| // Check if there is GFX device behind each GPP port |
| // |
| if ( PortCfg->PortDetected == TRUE ) { |
| RegBusNumber = (SBTEMP_BUS << 16) + (SBTEMP_BUS << 8); |
| WritePci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x18), AccessWidth32, &RegBusNumber, StdHeader); |
| ReadPci (PCI_ADDRESS (SBTEMP_BUS, 0, 0, 0x0B), AccessWidth8, &Value, StdHeader); |
| if ( Value == 3 ) { |
| FchDataPtr->Gpp.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) (RCINDXP << 29) | (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) (RCINDXP << 29) | (PortId << 24)), ~BIT19, 0, StdHeader); |
| } |
| } |
| |
| if ( FchDataPtr->Gpp.GppUnhidePorts == FALSE ) { |
| if ((AbValue & 0xF0) == 0) { |
| 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) (RCINDXP << 29) | (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) (RCINDXP << 29) | (PortId << 24); |
| AbValue = ReadAlink (AbIndex, StdHeader) & ~BIT19; |
| WriteAlink (AbIndex, AbValue, StdHeader); |
| |
| } |
| } |
| } |
| |