| /** |
| * @file |
| * |
| * PCIe in recovery support |
| * |
| * |
| * |
| * @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" |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * 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 |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * E X P O R T E D F U N C T I O N S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| VOID |
| PcieRecoveryCoreInit ( |
| IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr |
| ); |
| |
| VOID |
| PcieRecoveryPortTraining ( |
| IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr |
| ); |
| |
| VOID |
| PcieRecoveryCommonPortInit ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| VOID |
| PcieRecoveryCommonCoreInit ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| UINT32 |
| PcieRecoveryGetCoreAddress ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| PCI_ADDR |
| PcieRecoveryGetPortPciAddress ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| VOID |
| PcieRecoveryPcieCheckPorts ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| VOID |
| PcieRecoveryReleaseTraining ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| PORT |
| PcieRecoveryNativePortId ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *NbConfigPtr |
| ); |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * PCIE Recovery Init. Basic programming / EP training. |
| * After this call EP are fully operational. |
| * |
| * |
| * |
| * @param[in] ConfigPtr Northbridges configuration block pointer. |
| * |
| */ |
| AGESA_STATUS |
| AmdPcieEarlyInit ( |
| IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr |
| ) |
| { |
| #ifdef PCIE_RECOVERY_SUPPORT |
| PcieRecoveryCoreInit (ConfigPtr); |
| PcieRecoveryPortTraining (ConfigPtr); |
| #endif |
| return AGESA_SUCCESS; |
| } |
| |
| |
| #ifdef PCIE_RECOVERY_SUPPORT |
| |
| INDIRECT_REG_ENTRY |
| STATIC |
| PcieRecoveryMiscInitTable[] = { |
| { |
| NB_MISC_REG0C, |
| (UINT32)~0x001f00FC, |
| 0x00000000 |
| }, |
| { |
| 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 |
| { |
| 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 |
| { |
| NB_MISC_REG28, |
| 0xffffff00, |
| 0x0 |
| }, |
| { |
| NB_MISC_REG27, |
| 0x3fffffff, |
| 0x0 |
| }, |
| { |
| NB_MISC_REG2D, |
| (UINT32)~(BIT5), |
| 0x0 |
| } |
| }; |
| |
| // 2 3 4 5 6 7 8 9 A B C D |
| UINT8 PortToCoreMappingTable[] = { 0xff, 0xff, 0, 0, 3, 3, 3, 3, 4, 3, 3, 1, 1, 3 }; |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Minimum core initialization |
| * |
| * |
| * |
| * |
| * @param[in] ConfigPtr Northbridges configuration block pointer. |
| * |
| */ |
| |
| VOID |
| PcieRecoveryCoreInit ( |
| IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr |
| ) |
| { |
| CORE CoreId; |
| PORT PortId; |
| AMD_NB_CONFIG *NbConfigPtr; |
| PCIE_CONFIG *pPcieConfig; |
| |
| NbConfigPtr = &ConfigPtr->Northbridges[0]; |
| pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); |
| //Init Misc registers |
| LibNbIndirectTableInit ( |
| NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| 0, |
| (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryMiscInitTable[0],NULL), |
| (sizeof (PcieRecoveryMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)), |
| NbConfigPtr |
| ); |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON) { |
| pPcieConfig->CoreSetting[PortToCoreMappingTable[PortId]].CoreDisabled = OFF; |
| } |
| } |
| for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { |
| if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) { |
| //Init core registers and configuration |
| PcieRecoveryCommonCoreInit (CoreId, NbConfigPtr); |
| } |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Port link training initialization |
| * |
| * |
| * |
| * |
| * @param[in] ConfigPtr Northbridges configuration block pointer. |
| * |
| */ |
| |
| VOID |
| PcieRecoveryPortTraining ( |
| IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr |
| ) |
| { |
| PORT PortId; |
| UINT32 PortToHideMap; |
| AMD_NB_CONFIG *NbConfigPtr; |
| PCIE_CONFIG *pPcieConfig; |
| |
| PortToHideMap = 0; |
| NbConfigPtr = &ConfigPtr->Northbridges[0]; |
| pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON) { |
| PcieRecoveryCommonPortInit (PortId, NbConfigPtr); |
| if (LibNbCallBack (PHCB_AmdPortResetDeassert, 1 << PortId, NbConfigPtr) == AGESA_SUCCESS) { |
| STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), pPcieConfig->ResetToTrainingDelay, 0); |
| } |
| if (PortId != 8) { |
| PcieRecoveryReleaseTraining (PortId, NbConfigPtr); |
| } |
| } |
| } |
| STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ReceiverDetectionPooling, 0); |
| for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { |
| PCI_ADDR Port; |
| Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr); |
| if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PortId != 8) { |
| PcieRecoveryPcieCheckPorts (PortId, NbConfigPtr); |
| |
| pPcieConfig->PortConfiguration[PortId].PortLinkMode = PcieLinkModeGen1; |
| |
| LibNbPciIndexWrite ( |
| Port.AddressValue | NB_BIF_INDEX, |
| NB_BIFNBP_REG01, |
| AccessWidth32, |
| (UINT32*)&pPcieConfig->PortConfiguration[PortId], |
| NbConfigPtr |
| ); |
| } |
| if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF) { |
| PortToHideMap |= (1 << PortId); |
| } |
| } |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessWidth32, 0xffffffff, (PortToHideMap & 0xFC) | ((PortToHideMap & 0x3E00) << 7), NbConfigPtr); |
| } |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Check link training Status |
| * |
| * |
| * |
| * |
| * @param[in] Config Northbridges configuration structure pointer. |
| * |
| */ |
| VOID |
| PcieRecoveryPcieCheckPorts ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| PCIE_CONFIG *pPcieConfig; |
| PCI_ADDR Port; |
| UINT32 LinkState; |
| UINT32 LinkStatePooling; |
| UINT32 Value; |
| |
| pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); |
| Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr); |
| LinkStatePooling = pPcieConfig->ReceiverDetectionPooling; |
| do { |
| LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, NbConfigPtr); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCoreInit PortId = %d LinkState 0x%x\n", PortId, LinkState)); |
| LinkState &= 0x3F; |
| if (LinkState == 0x10) { |
| UINT16 VcoStatus; |
| BOOLEAN VcoNotCompleted; |
| UINT32 VcoPooling; |
| VcoNotCompleted = TRUE; |
| VcoPooling = 6000; |
| do { |
| LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &VcoStatus, NbConfigPtr); |
| if (VcoStatus & BIT1) { |
| LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, NbConfigPtr); |
| Value = (Value & 0xfffffe80) | ((Value & 0x70) >> 4) | BIT8; |
| LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, NbConfigPtr); |
| STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 5000, 0); |
| } else { |
| VcoNotCompleted = FALSE; |
| } |
| } while (VcoNotCompleted || --VcoPooling != 0); |
| if (!VcoNotCompleted) { |
| pPcieConfig->PortConfiguration[PortId].PortDetected = ON; |
| } |
| } else { |
| STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 1000, 0); |
| } |
| } while (LinkState != 0x10 && --LinkStatePooling != 0); |
| } |
| |
| |
| UINT8 PortTrainingOffset[] = { |
| 4, 5, 21, 22, 23, 24, 20, 25, 26, 6, 7 , 4 |
| }; |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Check link training Status |
| * |
| * |
| * |
| * |
| * @param[in] Config Northbridges configuration structure pointer. |
| * |
| */ |
| VOID |
| PcieRecoveryReleaseTraining ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| PORT NativePortId; |
| |
| NativePortId = PcieRecoveryNativePortId (PortId, NbConfigPtr); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryReleaseTraining PortId = %d NativeId %d BitOfset %d\n", |
| PortId, NativePortId, ((UINT8*)FIX_PTR_ADDR (&PortTrainingOffset[0], NULL))[NativePortId - MIN_PORT_ID])); |
| LibNbPciIndexRMW ( |
| NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, |
| (PortId == 13)? NB_MISC_REG2A:NB_MISC_REG08, |
| AccessWidth32, |
| ~(1 << ((UINT8*)FIX_PTR_ADDR (&PortTrainingOffset[0], NULL))[NativePortId - MIN_PORT_ID]), |
| 0, |
| NbConfigPtr |
| ); |
| } |
| |
| INDIRECT_REG_ENTRY PcieRecoveryPortInitTable[] = { |
| { |
| NB_BIFNBP_REG02, |
| (UINT32)~(BIT15), |
| BIT15 |
| }, |
| { |
| NB_BIFNBP_REGA1, |
| (UINT32)~(BIT24), |
| BIT11 |
| }, |
| { |
| NB_BIFNBP_REGB1, |
| 0xffffffff, |
| BIT28 + BIT23 + BIT19 + BIT20 |
| }, |
| { |
| NB_BIFNBP_REGA4, |
| (UINT32)~(BIT0), |
| 0x0 |
| }, |
| { |
| NB_BIFNBP_REGA2, |
| (UINT32)~(BIT13), |
| BIT13 |
| }, |
| { |
| NB_BIFNBP_REGA3, |
| (UINT32)~(BIT9), |
| BIT9 |
| }, |
| { |
| NB_BIFNBP_REGA0, |
| 0xffff00ff, |
| 0x6130 |
| }, |
| { |
| NB_BIFNBP_REG70, |
| (UINT32)~(BIT16 + BIT17 + BIT18), |
| BIT16 + BIT18 |
| }, |
| // Set Link for Gen1 |
| { |
| NB_BIFNBP_REGC0, |
| (UINT32)~(BIT15), |
| BIT15 |
| }, |
| { |
| NB_BIFNBP_REGA2, |
| (UINT32)~(BIT13), |
| BIT13 |
| }, |
| { |
| NB_BIFNBP_REGA4, |
| (UINT32)~(BIT0 + BIT29), |
| 0x0 |
| } |
| }; |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Port basic register init |
| * |
| * |
| * |
| * |
| * @param[in] Config Northbridges configuration structure pointer. |
| * |
| */ |
| |
| VOID |
| PcieRecoveryCommonPortInit ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| PCI_ADDR Port; |
| |
| Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr); |
| LibNbIndirectTableInit ( |
| Port.AddressValue | NB_BIF_INDEX, |
| 0x0, |
| (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryPortInitTable[0],NULL), |
| (sizeof (PcieRecoveryPortInitTable) / sizeof (INDIRECT_REG_ENTRY)), |
| NbConfigPtr |
| ); |
| LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessWidth8, 0xF0, 0x6, NbConfigPtr); |
| LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, 0xF0, 0x0, NbConfigPtr); |
| } |
| |
| |
| UINT8 GppConfigTable[] = { |
| 0x0, 0x1, 0x2, 0xC, 0xA, 0x4, 0xB |
| }; |
| |
| INDIRECT_REG_ENTRY PcieRecoveryCoreInitTable[] = { |
| { |
| NB_BIFNB_REG10, |
| (UINT32)~(BIT10 + BIT11 + BIT12), |
| BIT12 |
| }, |
| { |
| NB_BIFNB_REG20, |
| (UINT32)~(BIT8 + BIT9), |
| BIT9 |
| }, |
| { |
| NB_BIFNB_REG02, |
| (UINT32)~(BIT0), |
| BIT0 |
| }, |
| { |
| NB_BIFNB_REG40, |
| (UINT32)~(BIT14 + BIT15), |
| BIT15 |
| }, |
| { |
| NB_BIFNB_REGC1, |
| (UINT32)~(BIT0), |
| (BIT0 + BIT1 + BIT2) |
| }, |
| { |
| NB_BIFNB_REG1C, |
| 0x0, |
| (4 << 6) + (4 << 1) + 1 |
| } |
| }; |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Core basic register init |
| * |
| * |
| * |
| * |
| * @param[in] Config Northbridges configuration structure pointer. |
| * |
| */ |
| |
| VOID |
| PcieRecoveryCommonCoreInit ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| UINT32 CoreAddress; |
| PCIE_CONFIG *pPcieConfig; |
| |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCommonCoreInit CoreID = %d Enter\n", CoreId)); |
| CoreAddress = PcieRecoveryGetCoreAddress (CoreId, NbConfigPtr); |
| pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); |
| //Setup GPP1 core configuration |
| if (CoreAddress == GPP1_CORE && (pPcieConfig->CoreConfiguration[0] == GFX_CONFIG_AABB || NbConfigPtr->pPcieConfig->PortConfiguration[3].PortPresent == ON)) { |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, 0xffffffff, BIT15, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, BIT28, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT8, NbConfigPtr); |
| STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 2000, 0); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, 0x0, NbConfigPtr); |
| } |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, (UINT32)~BIT15, 0x0, NbConfigPtr); |
| //Setup GPP2 core configuration |
| if (CoreAddress == GPP2_CORE && (pPcieConfig->CoreConfiguration[1] == GFX_CONFIG_AABB || NbConfigPtr->pPcieConfig->PortConfiguration[12].PortPresent == ON)) { |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, 0xffffffff, BIT13, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, BIT29, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT9, NbConfigPtr); |
| STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 2000, 0); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT29, 0x0, NbConfigPtr); |
| } |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, (UINT32)~BIT13, 0x0, NbConfigPtr); |
| //Setup GPP core configuration |
| if (CoreAddress == GPP3a_CORE) { |
| UINT32 Mux; |
| UINT8 *pGppConfigTable; |
| Mux = 0; |
| pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT31, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT30, BIT30, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG67, AccessWidth32, 0xfffffff0, (UINT32)pGppConfigTable[pPcieConfig->CoreConfiguration[CoreId]], NbConfigPtr); |
| 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; |
| } |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, 0xf0000000, Mux, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT30, 0x0, NbConfigPtr); |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, (UINT32)~BIT31, 0x0, NbConfigPtr); |
| } |
| if (CoreAddress == GPP3b_CORE) { |
| LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2A, AccessWidth32, (UINT32)~BIT15, 0, NbConfigPtr); |
| } |
| LibNbIndirectTableInit ( |
| NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX, |
| CoreAddress, |
| (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryCoreInitTable[0],NULL), |
| (sizeof (PcieRecoveryCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)), |
| NbConfigPtr |
| ); |
| CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCommonCoreInit Exitr\n")); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * 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 |
| PcieRecoveryGetCoreAddress ( |
| IN CORE CoreId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| UINT32 CoreAddress; |
| CoreAddress = GPP1_CORE; |
| switch (CoreId) { |
| case 0x0: |
| CoreAddress = GPP1_CORE; |
| break; |
| case 0x1: |
| CoreAddress = GPP2_CORE; |
| break; |
| case 0x2: |
| CoreAddress = GPP3a_CORE; |
| break; |
| case 0x3: |
| CoreAddress = GPP3b_CORE; |
| break; |
| case 0x4: |
| CoreAddress = SB_CORE; |
| break; |
| default: |
| CIMX_ASSERT (FALSE); |
| } |
| return CoreAddress; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * 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 |
| PcieRecoveryGetPortPciAddress ( |
| IN PORT PortId, |
| IN AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| PCI_ADDR Port; |
| Port = NbConfigPtr->NbPciAddress; |
| Port.Address.Device = PortId; |
| return Port; |
| } |
| |
| UINT32 GppNativeIdTable[] = { |
| 0xff50fff4, |
| 0xf650fff4, |
| 0xff60f5f4, |
| 0xf760f5f4, |
| 0xf87065f4, |
| 0xf9807654 |
| }; |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * 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 |
| PcieRecoveryNativePortId ( |
| IN PORT PortId, |
| IN OUT AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| UINT32 GppNativeIdMap; |
| if (PortId > 3 && PortId < 11) { |
| GppNativeIdMap = ((UINT32*)FIX_PTR_ADDR (&GppNativeIdTable[0], NULL))[NbConfigPtr->pPcieConfig->CoreConfiguration[0x2] - 1]; |
| return (GppNativeIdMap >> ((PortId - 4)*4)) & 0xF; |
| } else { |
| return PortId; |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Initialize default PCIE_CONFIG setting |
| * |
| * |
| * |
| * @param[in] pConfig Northbridge configuration structure pointer. |
| * |
| */ |
| |
| AGESA_STATUS |
| PcieRecoveryInitializer ( |
| IN OUT AMD_NB_CONFIG *NbConfigPtr |
| ) |
| { |
| PCIE_CONFIG *pPcieConfig; |
| CORE CoreId; |
| pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); |
| if (pPcieConfig == NULL) { |
| return AGESA_FATAL; |
| } |
| LibAmdMemFill (pPcieConfig, 0, sizeof (PCIE_CONFIG), (AMD_CONFIG_PARAMS *)NbConfigPtr); |
| pPcieConfig->ReceiverDetectionPooling = 120; |
| pPcieConfig->ResetToTrainingDelay = 4; |
| for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { |
| pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON; |
| } |
| return AGESA_SUCCESS; |
| } |
| |
| #endif |