blob: 918fbd43f14071024f8c8cce4ae332b682c9a397 [file] [log] [blame]
/**
* @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