| /** |
| * @file |
| * |
| * PCIe silicon specific functions library. |
| * |
| * |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: CIMx-NB |
| * @e sub-project: |
| * @e \$Revision:$ @e \$Date:$ |
| * |
| */ |
| /***************************************************************************** |
| * |
| * Copyright (C) 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. |
| * |
| * |
| ***************************************************************************/ |
| /*---------------------------------------------------------------------------------------- |
| * M O D U L E S U S E D |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| #include "NbPlatform.h" |
| #include "amdDebugOutLib.h" |
| #include "amdSbLib.h" |
| |
| /*---------------------------------------------------------------------------------------- |
| * 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 |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| UINT32 |
| PcieLibGetCoreConfiguration ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *pConfig |
| ); |
| |
| AGESA_STATUS |
| PcieLibValidateGfxConfig ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ); |
| |
| /*---------------------------------------------------------------------------------------- |
| * E X P O R T E D F U N C T I O N S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| |
| |
| CORE_INFO CoreInfoTable[] = { |
| { // GPP1_CORE_ID = 0 It is GFX Core (GPP1 Core) |
| GPP1_CORE, // Core Selector |
| (BIT2 | BIT3), // Port ID Mask. Defines what ports belongs |
| NB_MISC_REG08, |
| NB_MISC_REG28, // De-emphasis register |
| NB_MISC_REG26, // Strap control register |
| 28, // Strap bit offset |
| NB_CLK_REGF0, |
| NB_MISC_REG35, 26, // TX drive strength and offset |
| NB_MISC_REG35, 18, // TX half swing |
| NB_MISC_REG36, 24, // TX zero deemphasis |
| 0, |
| 28, |
| 23 |
| }, |
| { // GPP2_CORE_ID = 1 It is GFX2 Core (GPP2 Core) |
| GPP2_CORE, // Core Selector |
| (BIT11 | BIT12), // Port ID Mask. Defines what ports belongs |
| NB_MISC_REG08, |
| NB_MISC_REG27, // De-emphasis register |
| NB_MISC_REG26, // Strap control register |
| 29, // Strap bit offset |
| NB_CLK_REGF0, |
| NB_MISC_REG35, 28, // TX drive strength and offset |
| NB_MISC_REG35, 19, // TX half swing |
| NB_MISC_REG36, 26, // TX zero deemphasis |
| 1, |
| 29, |
| 24 |
| }, |
| { // GPP3a_CORE_ID = 2 It is GPP Core (GPP3a Core) |
| GPP3a_CORE, // Core Selector |
| (BIT4 | BIT5 | BIT6 | BIT7 | BIT9 | BIT10), // Port ID Mask. Defines what ports belongs |
| NB_MISC_REG08, |
| NB_MISC_REG28, // De-emphasis register |
| NB_MISC_REG26, // Strap control register |
| 30, // Strap bit offset |
| NB_CLK_REGF4, |
| NB_MISC_REG35, 30, // TX drive strength and offset |
| NB_MISC_REG35, 20, // TX half swing |
| NB_MISC_REG36, 28, // TX zero deemphasis |
| 2, |
| 30, |
| 25 |
| }, |
| { // GPP3b_CORE_ID = 3 It is GPP2 Core (GPP3b Core) |
| GPP3b_CORE, // Core Selector |
| (BIT13), // Port ID Mask. Defines what ports belongs |
| NB_MISC_REG2A, |
| NB_MISC_REG2D, // De-emphasis register |
| NB_MISC_REG2D, // Strap control register |
| 21, // Strap bit offset |
| NB_CLK_REGF4, |
| NB_MISC_REG2C, 4, // TX drive strength and offset |
| NB_MISC_REG2C, 2, // TX half swing |
| NB_MISC_REG2B, 10, // TX zero deemphasis |
| 3, |
| 31, |
| 26 |
| }, |
| { // SB_CORE_ID = 4 It is SB Core |
| SB_CORE, // Core Selector |
| (BIT8), // Port ID Mask. Defines what ports belongs |
| NB_MISC_REG08, |
| NB_MISC_REG6F, // De-emphasis register |
| 0x0, |
| 0x0, |
| 0x0, |
| NB_MISC_REG68, 8, // TX drive strength and offset |
| NB_MISC_REG67, 27, // TX half swing |
| NB_MISC_REG68, 20, // TX zero deemphasis |
| 0xff, |
| 0xff, |
| 0xff |
| } |
| }; |
| |
| |
| PORT_INFO pGfxPortFullA = { |
| PcieLinkWidth_x16, 0, 0 |
| }; |
| |
| PORT_INFO pGfxPortA = { |
| PcieLinkWidth_x8, 0, 96 |
| }; |
| |
| PORT_INFO pGfxPortB = { |
| PcieLinkWidth_x8, 8, 96 |
| }; |
| |
| PORT_INFO pGpp420000[] = { |
| {PcieLinkWidth_x4, 0, 56}, |
| {PcieLinkWidth_x2, 4, 28} |
| }; |
| |
| PORT_INFO pGpp411000[] = { |
| {PcieLinkWidth_x4, 0, 56}, |
| {PcieLinkWidth_x1, 4, 14}, |
| {PcieLinkWidth_x1, 5, 14} |
| }; |
| |
| PORT_INFO pGpp222000[] = { |
| {PcieLinkWidth_x2, 0, 28}, |
| {PcieLinkWidth_x2, 2, 28}, |
| {PcieLinkWidth_x2, 4, 28} |
| }; |
| |
| PORT_INFO pGpp221100[] = { |
| {PcieLinkWidth_x2, 0, 28}, |
| {PcieLinkWidth_x2, 2, 28}, |
| {PcieLinkWidth_x1, 4, 14}, |
| {PcieLinkWidth_x1, 5, 14} |
| }; |
| |
| PORT_INFO pGpp211110[] = { |
| {PcieLinkWidth_x2, 0, 28}, |
| {PcieLinkWidth_x1, 2, 14}, |
| {PcieLinkWidth_x1, 3, 14}, |
| {PcieLinkWidth_x1, 4, 14}, |
| {PcieLinkWidth_x4, 0, 0 }, //Dummy entry |
| {PcieLinkWidth_x1, 5, 14} |
| }; |
| |
| PORT_INFO pGpp111111[] = { |
| {PcieLinkWidth_x1, 0, 14}, |
| {PcieLinkWidth_x1, 1, 14}, |
| {PcieLinkWidth_x1, 2, 14}, |
| {PcieLinkWidth_x1, 3, 14}, |
| {PcieLinkWidth_x4, 0, 0 }, //Dummy entry |
| {PcieLinkWidth_x1, 4, 14}, |
| {PcieLinkWidth_x1, 5, 14} |
| }; |
| |
| GPP_CFG_INFO GppCfgInfoTable[] = { |
| {pGpp420000, 0xff50fff4}, |
| {pGpp411000, 0xf650fff4}, |
| {pGpp222000, 0xff60f5f4}, |
| {pGpp221100, 0xf760f5f4}, |
| {pGpp211110, 0xf97065f4}, |
| {pGpp111111, 0xfA907654} |
| }; |
| |
| CONST PORT_STATIC_INFO PortInfoTable[] = { |
| //Training Reversal Deemp Mapping Hotplug Offset |
| {4 , 3, 0 , 4 , 0 }, //2 |
| {5 , 4, 1 , 8 , 8 }, //3 |
| {21, 7, 2 , 12 , 0 }, //4 |
| {22, 8, 3 , 16 , 8 }, //5 |
| {23, 9, 4 , 20 , 16 }, //6 |
| {24, 10, 5 , 24 , 0xFF }, //7 |
| {20, 0, 1 , 0xFF , 0xFF }, //8 |
| {25, 11, 6 , 28 , 0xFF }, //9 |
| {26, 12, 7 , 0 , 0xFF }, //10 |
| {6 , 5, 30, 4 , 16 }, //11 |
| {7 , 6, 31, 8 , 24 }, //12 |
| {4 , 25, 5 , 12 , 24 } //13 |
| }; |
| |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Port Training Control |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] Operation Release or Hold training |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| VOID |
| PcieLibPortTrainingControl ( |
| IN PORT PortId, |
| IN PCIE_LINK_TRAINING Operation, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| CORE_INFO *pCoreInfo; |
| PORT_STATIC_INFO *pStaticPortInfo; |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); |
| pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| pCoreInfo->TrainingRegister, |
| AccessWidth32, |
| ~(1 << pStaticPortInfo->TrainingAddress), |
| (Operation == PcieLinkTrainingHold)?(1 << pStaticPortInfo->TrainingAddress):0, |
| pConfig |
| ); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get PCI address of Port. |
| * Function return pcie Address based on port mapping and core configuration. |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| PCI_ADDR |
| PcieLibGetPortPciAddress ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| PCI_ADDR Port; |
| UINT32 RemapEnable; |
| UINT32 RemapValue; |
| PORT_STATIC_INFO *pPortStaticInfo; |
| |
| RemapEnable = 0; |
| RemapValue = 0; |
| pPortStaticInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); |
| Port.AddressValue = pConfig->NbPciAddress.AddressValue; |
| |
| LibNbPciIndexRead ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| NB_MISC_REG20, |
| AccessWidth32, |
| &RemapEnable, |
| pConfig |
| ); |
| if (pPortStaticInfo->MappingAddress != 0xff && RemapEnable & BIT0) { |
| LibNbPciIndexRead ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| (PortId > 9)? NB_MISC_REG21:NB_MISC_REG20, |
| AccessWidth32, |
| &RemapValue, |
| pConfig |
| ); |
| RemapValue = (RemapValue >> pPortStaticInfo->MappingAddress) & 0xf; |
| } |
| if (RemapValue == 0) { |
| RemapValue = PortId; |
| } |
| Port.Address.Device = RemapValue; |
| return Port; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get Core register selector. |
| * Function return selector to access BIFNB register space for selected core |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| UINT32 |
| PcieLibGetCoreAddress ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| return PcieLibGetCoreInfo (CoreId, pConfig)->CoreSelector; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get Core Id |
| * Function return PCIE core ID base on Port ID |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * @retval Core ID. |
| */ |
| CORE |
| PcieLibGetCoreId ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE_INFO *pCoreInfoTable = (CORE_INFO*)FIX_PTR_ADDR (&CoreInfoTable[0], NULL); |
| CORE CoreId; |
| for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { |
| if (pCoreInfoTable[CoreId].PortIdBitMap & (1 << PortId)) { |
| break; |
| } |
| } |
| return CoreId; |
| } |
| |
| /* |
| INDIRECT_REG_ENTRY |
| STATIC |
| PcieMiscInitTable[] = { |
| { |
| NB_MISC_REG20, |
| (UINT32)~BIT1, |
| 0x0 |
| }, //enable static device remapping by default |
| { |
| NB_MISC_REG22, |
| 0xffffffff, |
| BIT27 |
| }, //[10]CMGOOD_OVERRIDE for all 5 pcie cores. |
| { |
| NB_MISC_REG6B, |
| 0xffffffff, |
| (UINT32) (0x1f << 27) |
| }, //[13][12]Turn Off Offset Cancellation |
| { |
| NB_MISC_REG37, |
| (UINT32)~(BIT11 + BIT12 + BIT13), |
| 0x0 |
| }, //[14][13]Disables Rx Clock gating in CDR |
| { |
| NB_MISC_REG67, |
| (UINT32)~(BIT26 + BIT10 + BIT11), |
| BIT11 |
| }, //[13]Disables Rx Clock gating in CDR |
| //[16]Sets Electrical Idle Threshold |
| { |
| NB_MISC_REG2C, |
| (UINT32)~(BIT10), |
| 0x0 |
| }, //[13]Disables Rx Clock gating in CDR |
| { |
| NB_MISC_REG2A, |
| (UINT32)~(BIT17 + BIT16), |
| BIT17 |
| }, //[16]Sets Electrical l Idle Threshold |
| { |
| NB_MISC_REG32, |
| (UINT32)~(0x3F << 20), |
| (UINT32) (0x2A << 20) |
| } //[17][16]Sets Electrical Idle Threshold |
| }; |
| */ |
| |
| |
| |
| UINT8 GppConfigTable[] = { |
| 0x0, 0x1, 0x2, 0xC, 0xA, 0x4, 0xB |
| }; |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Set Core Configuration. |
| * |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| VOID |
| PcieLibSetCoreConfiguration ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT32 LaneReversalValue; |
| PORT PortId; |
| PCIE_CONFIG *pPcieConfig; |
| CORE_INFO *pCoreInfo; |
| CORE CoreAddress; |
| |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetCoreConfiguration CoreId = %d Configuration = 0x%x Enter\n", CoreId, pPcieConfig->CoreConfiguration[CoreId])); |
| pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); |
| CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); |
| LaneReversalValue = 0; |
| PcieLibCoreReset (CoreId, PcieCoreResetAllAssert, pConfig); |
| PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStart, pConfig); |
| //Setup GFX/GFX2 core configuration |
| if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { |
| if (pPcieConfig->CoreConfiguration[CoreId] == GFX_CONFIG_AABB) { |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, (CoreAddress == GPP1_CORE)?BIT8:BIT9, pConfig); |
| STALL (GET_BLOCK_CONFIG_PTR (pConfig), 2000, 0); |
| } |
| if (pPcieConfig->CoreSetting[CoreId].RefClockInput == ON) { |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG6C, AccessWidth32, 0xffffffff, (CoreAddress == GPP1_CORE)?BIT9:BIT31, pConfig); |
| } |
| } |
| //Setup GPP core configuration |
| if (CoreAddress == GPP3a_CORE) { |
| UINT32 Mux; |
| UINT8 *pGppConfigTable; |
| |
| Mux = 0; |
| pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL); |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| NB_MISC_REG67, AccessWidth32, |
| 0xfffffff0, |
| (UINT32)pGppConfigTable[pPcieConfig->CoreConfiguration[CoreId]], |
| pConfig |
| ); |
| switch (pPcieConfig->CoreConfiguration[CoreId]) { |
| case GPP_CONFIG_GPP420000: |
| Mux = (pPcieConfig->PortConfiguration[6].PortReversed == ON)?0xF05BA00:0x055B000; |
| break; |
| case GPP_CONFIG_GPP411000: |
| Mux = 0x215B400; |
| break; |
| case GPP_CONFIG_GPP222000: |
| case GPP_CONFIG_GPP211110: |
| Mux = (pPcieConfig->PortConfiguration[4].PortReversed == ON)?0xFFF0AAA:0xFF0BAA0; |
| break; |
| case GPP_CONFIG_GPP221100: |
| Mux = 0x215B400; |
| break; |
| case GPP_CONFIG_GPP111111: |
| Mux = 0x2AA3554; |
| break; |
| default: |
| CIMX_ASSERT (FALSE); |
| } |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, 0xf0000000, Mux, pConfig); |
| } |
| PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStop, pConfig); |
| PcieLibCoreReset (CoreId, PcieCoreResetAllDeassert, pConfig); |
| //Setup lane reversal |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| if (PcieLibIsValidPortId (PortId, pConfig)) { |
| if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && |
| pPcieConfig->PortConfiguration[PortId].PortReversed == ON && |
| (pCoreInfo->PortIdBitMap & (1 << PortId)) != 0) { |
| PORT_STATIC_INFO *pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); |
| LaneReversalValue |= (1 << (pStaticPortInfo->ReversalAddress)); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Port reversed Port Id %d Native Id %d, Reversal Address %d \n", PortId, PcieLibNativePortId (PortId, pConfig), pStaticPortInfo->ReversalAddress)); |
| } |
| } |
| } |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| (CoreAddress == GPP3b_CORE) ? NB_MISC_REG2D : NB_MISC_REG27, |
| AccessWidth32, 0xffffffff, |
| LaneReversalValue, |
| pConfig |
| ); |
| //Setup performance mode |
| if (pPcieConfig->CoreSetting[CoreId].PerformanceMode == ON) { |
| UINT32 RegisterAddress; |
| switch (CoreAddress) { |
| case GPP1_CORE: |
| RegisterAddress = NB_MISC_REG33; |
| break; |
| case GPP2_CORE: |
| RegisterAddress = NB_MISC_REG22; |
| break; |
| default: |
| RegisterAddress = 0; |
| break; |
| } |
| if (RegisterAddress != 0) { |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress , AccessWidth32, 0xfffffC00, 0xB5, pConfig); |
| } |
| } |
| //Setup Tx Drive Strength |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| pCoreInfo->TxDriveStrengthRegister , |
| AccessWidth32, |
| ~(0x3 << pCoreInfo->TxDriveStrengthOffset), |
| pPcieConfig->CoreSetting[CoreId].TxDriveStrength << pCoreInfo->TxDriveStrengthOffset, |
| pConfig |
| ); |
| //Setup Tx half swing |
| if (pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode == ON) { |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| pCoreInfo->TxHalfSwingRegister, |
| AccessWidth32, |
| ~(0x1 << pCoreInfo->TxHalfSwingOffset), |
| 0x0, |
| pConfig |
| ); |
| // Setup half swing deemphasis |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| pCoreInfo->TxHalfSwingDeepmhasisRegister , |
| AccessWidth32, |
| ~(0x3 << pCoreInfo->TxHalfSwingDeepmhasisOffset), |
| 0x0, |
| pConfig |
| ); |
| } |
| //Finalize straps for this core |
| PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStart, pConfig); |
| PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStop, pConfig); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetCoreConfiguration Exit\n")); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get Core Configuration |
| * Function return GPPSB/GFX/GFX2 core configuration. |
| * |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| UINT32 |
| PcieLibGetCoreConfiguration ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT32 CoreConfiguration; |
| UINT32 Value; |
| CORE CoreAddress; |
| |
| CoreConfiguration = 0, |
| CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); |
| // CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibGetCoreConfiguration (Core = 0x%x) Enter\n", CoreAddress)); |
| if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { |
| LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, &Value, pConfig); |
| CoreConfiguration = (Value & ((CoreAddress == GPP1_CORE) ? BIT8:BIT9))? GFX_CONFIG_AABB:GFX_CONFIG_AAAA; |
| } else { |
| if (CoreAddress == GPP3a_CORE) { |
| UINT8 *pGppConfigTable; |
| pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL); |
| LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG67, AccessWidth32, &Value, pConfig); |
| while (pGppConfigTable[CoreConfiguration] != (Value & 0xf)) { |
| CoreConfiguration++; |
| } |
| } |
| } |
| // CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibGetCoreConfiguration (CoreConfiguration = 0x%x) Exit\n", CoreConfiguration)); |
| return CoreConfiguration; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Return link misc information (max link width, current link width, lane 0 map) |
| * |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| LINK_INFO |
| PcieLibGetPortLinkInfo ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT32 Value; |
| PCI_ADDR Port; |
| PORT_INFO *pPortInfo; |
| LINK_INFO LinkInfo = {0, 0, 0}; |
| |
| Port = PcieLibGetPortPciAddress (PortId, pConfig); |
| pPortInfo = PcieLibGetPortInfo (PortId, pConfig); |
| //Read current link width |
| LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig); |
| Value = (Value >> 4) & 0xf; |
| LinkInfo.LinkWidth = (UINT8)Value; |
| LinkInfo.MaxLinkWidth = pPortInfo->MaxLinkWidth; |
| LinkInfo.Line0Offset = pPortInfo->Line0Offset; |
| // CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d LinkWidth 0x%x MaxLinkWidth 0x%x Line0Offset %d\n", PortId, LinkInfo.LinkWidth, LinkInfo.MaxLinkWidth,LinkInfo.Line0Offset)); |
| return LinkInfo; |
| } |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Check if port in lane reversed configuration. |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| BOOLEAN |
| PcieLibIsPortReversed ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| BOOLEAN Result; |
| UINT32 Value; |
| PCIE_CONFIG *pPcieConfig; |
| PCI_ADDR Port; |
| |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| Port = PcieLibGetPortPciAddress (PortId, pConfig); |
| LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG50, AccessWidth32, &Value, pConfig); |
| if (pPcieConfig->PortConfiguration[PortId].PortReversed == ON || (Value & BIT0) != 0) { |
| Result = TRUE; |
| } else { |
| Result = FALSE; |
| } |
| return Result; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Check if core id valid for current silicon |
| * |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| BOOLEAN |
| PcieLibIsValidCoreId ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT32 CoreAddress; |
| NB_INFO NbInfo; |
| |
| CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); |
| NbInfo = LibNbGetRevisionInfo (pConfig); |
| if (CoreAddress == GPP3b_CORE) { |
| if (NbInfo.Type == NB_RD890 || NbInfo.Type == NB_SR5690) { |
| return TRUE; |
| } else { |
| return FALSE; |
| } |
| } |
| if (CoreAddress == GPP2_CORE && (NbInfo.Type == NB_RD780 || NbInfo.Type == NB_RX780 || NbInfo.Type == NB_SR5650 || NbInfo.Type == NB_990X || NbInfo.Type == NB_970)) { |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Check if port Id valid for current core configuration |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| BOOLEAN |
| PcieLibIsValidPortId ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| NB_INFO NbInfo; |
| |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| NbInfo = LibNbGetRevisionInfo (pConfig); |
| if (!PcieLibIsValidCoreId (CoreId, pConfig)) { |
| return FALSE; |
| } |
| if ((PortId == 3 || PortId == 12) && PcieLibGetCoreConfiguration (CoreId, pConfig) != GFX_CONFIG_AABB) { |
| return FALSE; |
| } |
| if (PortId == 3 && NbInfo.Type == NB_970) { |
| return FALSE; |
| } |
| if (PortId == 12 && NbInfo.Type == NB_SR5670) { |
| return FALSE; |
| } |
| if (PortId == 13 || PortId == 8) { |
| return TRUE; |
| } else { |
| return (PcieLibNativePortId (PortId, pConfig) == 0xf)?FALSE:TRUE; |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Set Link mode. Gen1/Gen2/Gen2-Advertize |
| * |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] Operation Link Mode |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| |
| VOID |
| PcieLibSetLinkMode ( |
| IN PORT PortId, |
| IN PCIE_LINK_MODE Operation, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| PCI_ADDR Port; |
| UINT8 LinkSpeed; |
| UINT32 LinkDeemphasisMask; |
| UINT32 LinkDeemphasisValue; |
| UINT32 RegA4Value; |
| UINT32 RegA2Value; |
| UINT32 RegC0Value; |
| CORE_INFO *pCoreInfo; |
| PORT_STATIC_INFO *pStaticPortInfo; |
| PCIE_CONFIG *pPcieConfig; |
| |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetLinkMode PortId %d Operation %d Enter\n", PortId, Operation)); |
| LinkSpeed = 2; |
| RegA4Value = BIT29 + BIT0; |
| RegA2Value = 0; |
| RegC0Value = 0; |
| Port = PcieLibGetPortPciAddress (PortId, pConfig); |
| pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); |
| pCoreInfo = PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig); |
| |
| LinkDeemphasisValue = pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis << pStaticPortInfo->DeemphasisAddress; |
| LinkDeemphasisMask = ~(1 << pStaticPortInfo->DeemphasisAddress); |
| |
| if (Operation == PcieLinkModeGen1 || Operation == PcieLinkModeGen2AdvertizeOnly) { |
| RegC0Value = BIT15; |
| RegA2Value = BIT13; |
| if (Operation == PcieLinkModeGen1) { |
| RegA4Value = 0; |
| LinkSpeed = 1; |
| LinkDeemphasisValue = 0; |
| } |
| } |
| |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " pCoreInfo->DeemphasisRegister %x pStaticPortInfo->DeemphasisAddress %x LinkDeemphasisMask %x, LinkDeemphasisValue %x\n", pCoreInfo->DeemphasisRegister, pStaticPortInfo->DeemphasisAddress, LinkDeemphasisMask, LinkDeemphasisValue)); |
| LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA4 , AccessWidth32, (UINT32)~(BIT0 + BIT29), RegA4Value , pConfig); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, pCoreInfo->DeemphasisRegister, AccessWidth32, LinkDeemphasisMask, LinkDeemphasisValue , pConfig); |
| LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, 0xF0, LinkSpeed, pConfig); |
| LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC0 , AccessWidth32, (UINT32)~(BIT15), RegC0Value , pConfig); |
| LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2 , AccessWidth32, (UINT32)~(BIT13), RegA2Value , pConfig); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Request PCIE reset to be executed |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| AGESA_STATUS |
| PcieLibRequestPciReset ( |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| AGESA_STATUS Status; |
| SCRATCH_1 Scratch; |
| |
| Status = AGESA_UNSUPPORTED; |
| LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); |
| if (Scratch.ResetCount == 0xf) { |
| Scratch.ResetCount = 0; |
| } |
| if (Scratch.ResetCount < 5) { |
| ++Scratch.ResetCount; |
| LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); |
| if (LibNbCallBack (PHCB_AmdGeneratePciReset, WARM_RESET , pConfig) != AGESA_SUCCESS) { |
| LibNbIoRMW (0xCF9, AccessWidth8, 0, 0x6, pConfig); |
| } |
| } |
| return Status; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Control Core Reset |
| * |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] Operation Assert/Deassert/Check core reset |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| PCI_CORE_RESET |
| PcieLibCoreReset ( |
| IN CORE CoreId, |
| IN PCI_CORE_RESET Operation, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT32 Value; |
| UINT32 CalibrationReset; |
| UINT32 GlobalReset; |
| UINT32 RegisterAddress; |
| UINT32 CoreAddress; |
| |
| RegisterAddress = NB_MISC_REG08; |
| CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); |
| switch (CoreAddress) { |
| case GPP3b_CORE: |
| RegisterAddress = NB_MISC_REG2A; // break missing and it is not an error. |
| case GPP1_CORE: |
| CalibrationReset = BIT14; |
| GlobalReset = BIT15; |
| break; |
| case GPP2_CORE: |
| CalibrationReset = BIT12; |
| GlobalReset = BIT13; |
| break; |
| case GPP3a_CORE: |
| CalibrationReset = BIT30; |
| GlobalReset = BIT31; |
| break; |
| default: |
| return PcieCoreResetAllDeassert; |
| } |
| switch (Operation) { |
| case PcieCoreResetAllDeassert: |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, ~CalibrationReset, 0x0, pConfig); |
| STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, 0); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, ~GlobalReset, 0x0, pConfig); |
| STALL (GET_BLOCK_CONFIG_PTR (pConfig), 2000, 0); |
| break; |
| case PcieCoreResetAllAssert: |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, 0xffffffff, CalibrationReset | GlobalReset, pConfig); |
| break; |
| case PcieCoreResetAllCheck: |
| LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, &Value, pConfig); |
| Operation = (Value & (CalibrationReset | GlobalReset))?PcieCoreResetAllAssert:PcieCoreResetAllDeassert; |
| break; |
| default: |
| CIMX_ASSERT (FALSE); |
| } |
| return Operation; |
| } |
| |
| UINT8 GfxLineMapTable[] = { |
| 0x00, 0x01, 0x01, 0x03, 0x0f, 0x00, 0xFF |
| }; |
| UINT8 GppLineMapTable[] = { |
| 0x00, 0x01, 0x03, 0x0F |
| }; |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Power off port lanes. |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] Width Port Link Width. |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| VOID |
| PcieLibPowerOffPortLanes ( |
| IN PORT PortId, |
| IN PCIE_LINK_WIDTH Width, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| LINK_INFO LinkInfo; |
| UINT32 PowerOffPads; |
| UINT32 CoreAddress; |
| UINT8* pLineMapTable; |
| UINT16 MaxLaneBitMap; |
| UINT16 LaneBitMap; |
| |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPowerOffPortLanes (PortId = %d, Width = %d) Enter\n", PortId, Width)); |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| LinkInfo = PcieLibGetPortLinkInfo (PortId, pConfig); |
| CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); |
| if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { |
| pLineMapTable = &GfxLineMapTable[0]; |
| LinkInfo.Line0Offset /= 2; |
| } else { |
| pLineMapTable = &GppLineMapTable[0]; |
| } |
| pLineMapTable = (UINT8*)FIX_PTR_ADDR (pLineMapTable, NULL); |
| LaneBitMap = pLineMapTable[Width]; |
| MaxLaneBitMap = pLineMapTable[LinkInfo.MaxLinkWidth]; |
| if (PcieLibIsPortReversed (PortId, pConfig)) { |
| LaneBitMap = (UINT16)LibNbBitReverse ((UINT32)LaneBitMap, LibAmdBitScanForward (MaxLaneBitMap), LibAmdBitScanReverse (MaxLaneBitMap)); |
| } |
| PowerOffPads = (MaxLaneBitMap ^ LaneBitMap) << LinkInfo.Line0Offset; |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Pads %x Exit\n", PowerOffPads)); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG65 | CoreAddress, AccessWidth32, 0xffffffff, PowerOffPads | (PowerOffPads << 8), pConfig); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPowerOffPortLanes Exit\n")); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Hide Unused Ports |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| VOID |
| PcieLibHidePorts ( |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT32 PresentPortMask; |
| UINT32 DetectedPortMask; |
| UINT32 HotplugPortMask; |
| UINT32 Value; |
| PORT PortId; |
| PCIE_CONFIG *pPcieConfig; |
| |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibHidePorts Enter\n")); |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| PresentPortMask = 0; |
| DetectedPortMask = 0; |
| HotplugPortMask = 0; |
| // Hide SB Port |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, (UINT32)~BIT6, 0, pConfig); |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) { |
| PCI_ADDR Port; |
| Port = PcieLibGetPortPciAddress (PortId, pConfig); |
| if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON ) { |
| DetectedPortMask |= 1 << Port.Address.Device; |
| } |
| if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) { |
| HotplugPortMask |= 1 << Port.Address.Device; |
| } |
| PresentPortMask |= 1 << Port.Address.Device; |
| } |
| } |
| |
| if (pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON) { |
| Value = PresentPortMask; |
| } else { |
| Value = DetectedPortMask | HotplugPortMask; |
| } |
| //CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Present Port 0x%x Visible Ports 0x%xExit\n",PresentPortMask,VisiblePortMask)); |
| Value = (~((Value & (0xFC)) + ((Value & 0x3E00) << 7))) & 0x1F00FC; |
| // Hide GFX/GFX2/GPP/GPP2 Ports |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessS3SaveWidth32, 0xffffffff, Value, pConfig); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibHidePorts Exit\n")); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * UnHide all PCIE Ports |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| VOID |
| PcieLibUnHidePorts ( |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessS3SaveWidth32, (UINT32)~0x1F00FCul, 0, pConfig); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, (UINT32)~BIT6, BIT6, pConfig); |
| } |
| |
| |
| |
| PCIE_DEFAULT_CONFIG PcieDefaultConfig = { |
| {0, 1, 0, 0}, |
| { |
| {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP1 |
| {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP2 |
| {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP3a |
| {0, 1, 1, 1, 1, 1, 0, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP3b |
| {0, 1, 0, 1, 1, 1, 0, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 0, 0, 0} //SB |
| }, |
| (BIT2 + BIT4 + BIT5 + BIT6 + BIT7 + BIT8 + BIT9 + BIT10 + BIT11 + BIT13) | (BIT3 + BIT12), |
| 0, |
| 2, |
| 0, |
| 60, |
| }; |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * AMD structures initializer for all NB. |
| * |
| * |
| * |
| * @param[in] ConfigPtr Northbridges configuration block pointer. |
| * |
| */ |
| |
| AGESA_STATUS |
| AmdPcieInitializer ( |
| IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr |
| ) |
| { |
| AGESA_STATUS Status; |
| Status = LibNbApiCall (PcieLibInitializer, ConfigPtr); |
| return Status; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Initialize default PCIE_CONFIG setting |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| AGESA_STATUS |
| PcieLibInitializer ( |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| PCIE_CONFIG *pPcieConfig; |
| PCIE_DEFAULT_CONFIG *pPcieDefaultConfig; |
| AMD_NB_CONFIG_BLOCK *ConfigPtr; |
| PORT PortId; |
| |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibInitializer Enter\n")); |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| if (pPcieConfig == NULL) { |
| return AGESA_WARNING; |
| } |
| if (pPcieConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) { |
| return AGESA_SUCCESS; |
| } |
| ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig); |
| LibAmdMemFill (pPcieConfig, 0, sizeof (PCIE_CONFIG), (AMD_CONFIG_PARAMS *)&(pPcieConfig->sHeader)); |
| pPcieConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER; |
| pPcieDefaultConfig = (PCIE_DEFAULT_CONFIG*)FIX_PTR_ADDR (&PcieDefaultConfig, NULL); |
| for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { |
| pPcieConfig->CoreSetting[CoreId] = pPcieDefaultConfig->CoreSetting[CoreId]; |
| } |
| pPcieConfig->PcieConfiguration = pPcieDefaultConfig->PcieConfiguration; |
| if (ConfigPtr->PlatformType == DesktopPlatform) { |
| pPcieConfig->PcieConfiguration.NbSbVc1 = ON; |
| } |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis3p5dB; |
| } |
| pPcieConfig->CoreConfiguration[2] = PcieLibGetCoreConfiguration (2, pConfig); |
| pPcieConfig->ReceiverDetectionPooling = pPcieDefaultConfig->ReceiverDetectionPooling; |
| pPcieConfig->ResetToTrainingDelay = pPcieDefaultConfig->ResetToTrainingDelay; |
| pPcieConfig->ExtPortConfiguration[8].PortL1ImmediateACK = ON; |
| pPcieConfig->TrainingToLinkTestDelay = pPcieDefaultConfig->TrainingToLinkTestDelay; |
| pPcieConfig->DeviceInitMaskS1 = pPcieDefaultConfig->DeviceInitMaskS1; |
| pPcieConfig->DeviceInitMaskS2 = pPcieDefaultConfig->DeviceInitMaskS2; |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibInitializer Exit\n")); |
| return AGESA_SUCCESS; |
| } |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Validate Gfx Core Configuration |
| * |
| * |
| * |
| * |
| * |
| */ |
| AGESA_STATUS |
| PcieLibValidateGfxConfig ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| PCIE_CONFIG *pPcieConfig; |
| |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibValidateGfxConfig Enter\n")); |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreConfiguration[%d] = \n", CoreId)); |
| if (pPcieConfig->CoreConfiguration[CoreId] == 0x0) { |
| pPcieConfig->CoreConfiguration[CoreId] = (pPcieConfig->PortConfiguration[PortId].PortPresent == ON)?GFX_CONFIG_AABB:GFX_CONFIG_AAAA; |
| } else { |
| if (pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AABB && |
| pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AAAA) { |
| //We have received request for unknown configuration. |
| //pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON; |
| pPcieConfig->PortConfiguration[PortId].PortPresent = 0; |
| pPcieConfig->PortConfiguration[PortId - 1].PortPresent = 0; |
| return AGESA_WARNING; |
| } |
| } |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreConfiguration[%d] = %x\n", CoreId, pPcieConfig->CoreConfiguration[CoreId])); |
| return AGESA_SUCCESS; |
| } |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Validate input parameters for early PCIE init. |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| AGESA_STATUS |
| PcieLibInitValidateInput ( |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| AGESA_STATUS Status; |
| PCIE_CONFIG *pPcieConfig; |
| NB_INFO NbInfo; |
| CORE CoreId; |
| PORT PortId; |
| |
| NbInfo = LibNbGetRevisionInfo (pConfig); |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| if (NbInfo.Type == NB_UNKNOWN || pPcieConfig == NULL) { |
| return AGESA_FATAL; |
| } |
| Status = AGESA_SUCCESS; |
| //Validate GFX configuration |
| if (PcieLibValidateGfxConfig (3, pConfig) != AGESA_SUCCESS) { |
| REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_CORE_CONFIGURATION, GPP1_CORE , 0, 0, 0, pConfig); |
| Status = AGESA_WARNING; |
| } |
| if (PcieLibValidateGfxConfig (12, pConfig) != AGESA_SUCCESS) { |
| REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_CORE_CONFIGURATION, GPP2_CORE , 0, 0, 0, pConfig); |
| Status = AGESA_WARNING; |
| } |
| //Enable SB port on NB - SB chain and disable otherwise |
| pPcieConfig->PortConfiguration[8].PortPresent = (pConfig->NbPciAddress.AddressValue == 0)?ON:OFF; |
| |
| for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { |
| if (pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON) { |
| //pPcieConfig->CoreSetting[CoreId].PowerOffUnusedLanes = OFF; |
| pPcieConfig->CoreSetting[CoreId].TxClockOff = OFF; |
| pPcieConfig->CoreSetting[CoreId].LclkClockOff = OFF; |
| pPcieConfig->CoreSetting[CoreId].PowerOffPll = OFF; |
| } |
| if (pPcieConfig->CoreSetting[CoreId].ChannelType != 0) { |
| //Set Trasmitter drive strength based on cahnnel type |
| if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieLongChannel) { |
| pPcieConfig->CoreSetting[CoreId].TxDriveStrength = (NbInfo.Revision == NB_REV_A11)? PcieTxDriveStrangth24mA : PcieTxDriveStrangth26mA; |
| } else { |
| pPcieConfig->CoreSetting[CoreId].TxDriveStrength = PcieTxDriveStrangth22mA; |
| } |
| // Enable half swing mode |
| if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieShortChannel) { |
| pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode = ON; |
| } else { |
| pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode = OFF; |
| } |
| } |
| } |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| if (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit == 0) { |
| pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit = 75; //Set 75W by default |
| } |
| if (pPcieConfig->CoreSetting[CoreId].ChannelType != 0) { |
| if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieLongChannel) { |
| pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB; |
| } else { |
| pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis3p5dB; |
| } |
| } |
| } |
| return Status; |
| } |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Enable PCIE Extended configuration MMIO. |
| * |
| * |
| * |
| * @param[in] PcieMmioBase MMIO Base Address in 1MB unit. |
| * @param[in] PcieMmioSize MMIO Size in 1MB unit |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| VOID |
| PcieLibSetPcieMmioBase ( |
| IN UINT16 PcieMmioBase, |
| IN UINT16 PcieMmioSize, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT8 BAR3BusRange; |
| |
| BAR3BusRange = LibAmdBitScanReverse ((UINT32)PcieMmioSize); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessWidth32, (UINT32)~BIT3, 0x0, pConfig); |
| LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG7F, AccessWidth8, (UINT32)~BIT6, BIT6, pConfig); |
| LibNbPciRMW (pConfig->NbPciAddress.AddressValue | (NB_PCI_REG84 + 2), AccessWidth8, (UINT32)~(0x7), (BAR3BusRange > 8)?0:BAR3BusRange, pConfig); |
| LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG1C, AccessWidth32, 0, (UINT32) (PcieMmioBase << 20), pConfig); |
| LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG7F, AccessWidth8, (UINT32)~BIT6, 0, pConfig); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG32, AccessWidth32, 0xffffffff, BIT28, pConfig); |
| LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessWidth32, 0xffffffff, BIT3, pConfig); |
| LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG04, AccessWidth8, (UINT32)~BIT1, BIT1, pConfig); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Assert/Deassert Strap valid enables programming for misc strap features. |
| * |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] Operation Assert or deassert strap valid. |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| VOID |
| PcieLibStrapModeControl ( |
| IN CORE CoreId, |
| IN PCIE_STRAP_MODE Operation, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE_INFO *pCoreInfo; |
| |
| pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); |
| LibNbPciIndexRMW ( |
| pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| pCoreInfo->StrapRegister, |
| AccessS3SaveWidth32, |
| ~(1 << pCoreInfo->StrapAddress), |
| (Operation == PcieCoreStrapConfigStart)?(1 << pCoreInfo->StrapAddress):0, |
| pConfig |
| ); |
| } |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get Pcie Port Info. |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| PORT_INFO* |
| PcieLibGetPortInfo ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| UINT32 CoreConfig; |
| PORT_INFO *pPortInfo; |
| PORT NativePortId; |
| GPP_CFG_INFO *pGppCfgInfoTable; |
| |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| CoreConfig = PcieLibGetCoreConfiguration (CoreId, pConfig); |
| switch (PcieLibGetCoreAddress (CoreId, pConfig)) { |
| case GPP1_CORE: |
| case GPP2_CORE: |
| pPortInfo = &pGfxPortFullA; |
| if (CoreConfig == GFX_CONFIG_AABB) { |
| if (PortId == 3 || PortId == 12) { |
| pPortInfo = &pGfxPortB; |
| } else { |
| pPortInfo = &pGfxPortA; |
| } |
| } |
| break; |
| case SB_CORE: |
| case GPP3b_CORE: |
| pPortInfo = &pGpp420000[0]; |
| break; |
| case GPP3a_CORE: |
| pGppCfgInfoTable = (GPP_CFG_INFO*)FIX_PTR_ADDR (&GppCfgInfoTable[CoreConfig - 1], NULL); |
| NativePortId = PcieLibNativePortId (PortId, pConfig); |
| if (NativePortId == 0xf) { |
| return NULL; |
| } |
| pPortInfo = &pGppCfgInfoTable->PortInfoPtr[NativePortId - 4]; |
| break; |
| default: |
| return NULL; |
| } |
| return (PORT_INFO*)FIX_PTR_ADDR (pPortInfo, NULL); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get Pointer to static port info |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| PORT_STATIC_INFO* |
| PcieLibGetStaticPortInfo ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| PORT_STATIC_INFO *pPortStaticInfo; |
| |
| pPortStaticInfo = (PORT_STATIC_INFO*)FIX_PTR_ADDR (&PortInfoTable[PortId - MIN_PORT_ID], NULL); |
| return pPortStaticInfo ; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get Native Port Id. |
| * Native Port Id can be different from Port ID only on GPPSB core ports. |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| PORT |
| PcieLibNativePortId ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| CORE CoreId; |
| GPP_CFG_INFO *pGppCfgInfoTable; |
| |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| if (PcieLibGetCoreAddress (CoreId, pConfig) == GPP3a_CORE) { |
| UINT32 CoreConfig; |
| CoreConfig = PcieLibGetCoreConfiguration (CoreId, pConfig); |
| pGppCfgInfoTable = (GPP_CFG_INFO*)FIX_PTR_ADDR (&GppCfgInfoTable[CoreConfig - 1], NULL); |
| return (pGppCfgInfoTable->PortIdMap >> ((PortId - 4) * 4)) & 0xF; |
| } else { |
| return PortId; |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get pointer to Core info structure. |
| * |
| * |
| * |
| * @param[in] CoreId PCI Express Core ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| CORE_INFO* |
| PcieLibGetCoreInfo ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| return (CORE_INFO*)FIX_PTR_ADDR (&CoreInfoTable[CoreId], NULL); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Reset Device in slot. |
| * Check if slot has controlled by GPI reset. If support toggle reset for 10us. |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| AGESA_STATUS |
| PcieLibResetSlot ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| AGESA_STATUS Status; |
| |
| Status = LibNbCallBack (PHCB_AmdPortResetSupported, (UINTN) (1 << PortId), pConfig); |
| if (Status == AGESA_SUCCESS) { |
| LibNbCallBack (PHCB_AmdPortResetAssert, (UINTN) (1 << PortId), pConfig); |
| STALL (GET_BLOCK_CONFIG_PTR (pConfig), 10, 0); |
| LibNbCallBack (PHCB_AmdPortResetDeassert, (UINTN) (1 << PortId), pConfig); |
| } |
| return Status; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Secondary level interface to check if Gen2 disabled. |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| BOOLEAN |
| PcieLibCheckGen2Disabled ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| SCRATCH_1 Scratch; |
| LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); |
| if ((Scratch.PortGen2Disable & (1 << (PortId - 2))) != 0) { |
| return FALSE; |
| } else { |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Force Gen2 Disable\n")); |
| return TRUE; |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Request Gen 2 disabled on next boot. |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| |
| VOID |
| PcieLibSetGen2Disabled ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *pConfig |
| ) |
| { |
| SCRATCH_1 Scratch; |
| |
| LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); |
| Scratch.PortGen2Disable &= (~(1 << (PortId - 2))); |
| LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Force link to compliance mode |
| * |
| * |
| * |
| * @param[in] PortId PCI Express Port ID |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| */ |
| VOID |
| PcieLibSetLinkCompliance ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| PCI_ADDR Port; |
| PCIE_CONFIG *pPcieConfig; |
| |
| Port = PcieLibGetPortPciAddress (PortId, pConfig); |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen1) { |
| LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC0, AccessWidth32, (UINT32)~BIT13, BIT13, pConfig); |
| } else { |
| LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, (UINT32)~BIT4, BIT4, pConfig); |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get PCIe device type |
| * |
| * |
| * |
| * @param[in] Device PCI address of device. |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| * @retval PCIe device type (see PCIE_DEVICE_TYPE) |
| */ |
| /*----------------------------------------------------------------------------------------*/ |
| |
| PCIE_DEVICE_TYPE |
| PcieGetDeviceType ( |
| IN PCI_ADDR Device, |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| UINT8 PcieCapPtr; |
| UINT8 Value; |
| |
| PcieCapPtr = LibNbFindPciCapability (Device.AddressValue, PCIE_CAP_ID, pConfig); |
| if (PcieCapPtr != 0) { |
| LibNbPciRead (Device.AddressValue | (PcieCapPtr + 0x2) , AccessWidth8, &Value, pConfig); |
| return Value >> 4; |
| } |
| return PcieNotPcieDevice; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get bitmap of cores that have active or potentially active ports |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| * @retval Bitmap of cores |
| */ |
| /*----------------------------------------------------------------------------------------*/ |
| |
| UINT8 |
| PcieLibGetActiveCoreMap ( |
| IN AMD_NB_CONFIG *pConfig |
| ) |
| { |
| PORT PortId; |
| CORE CoreId; |
| UINT8 ActiveCoreMap; |
| PCIE_CONFIG *pPcieConfig; |
| pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); |
| ActiveCoreMap = 0; |
| //Check through Ports |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) { |
| if (pPcieConfig->PortConfiguration[PortId].PortCompliance == ON || |
| pPcieConfig->PortConfiguration[PortId].PortDetected == ON || |
| pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) { |
| CoreId = PcieLibGetCoreId (PortId, pConfig); |
| ActiveCoreMap |= (1 << CoreId); |
| } |
| } |
| } |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Active Core Map = %x\n", ActiveCoreMap)); |
| return ActiveCoreMap; |
| } |