blob: 11115562700f15b9d8918e2ffbfa9072bffa16ce [file] [log] [blame]
/**
* @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 "HotplugFirmware.h"
/*----------------------------------------------------------------------------------------
* D E F I N I T I O N S A N D M A C R O S
*----------------------------------------------------------------------------------------
*/
#define MCU_CLEAR_BLOCK_LENGTH 16
/*----------------------------------------------------------------------------------------
* 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
*----------------------------------------------------------------------------------------
*/
INDIRECT_REG_ENTRY
STATIC
PcieMiscInitTable[] = {
{
NB_MISC_REG20,
(UINT32)~BIT1,
0x0
}, //enable static device remapping by default
{
NB_MISC_REG22,
0xffffffff,
BIT27 | (0x8 << 12) | (0x8 << 16) | (0x8 << 20)
},
{
NB_MISC_REG2B,
0xffffffff,
(0x8 << 12)
},
{
NB_MISC_REG6C,
0xffffffff,
(0x8 << 16)
},
{
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
};
/*----------------------------------------------------------------------------------------*/
/**
* Misc Initialization prior port training.
*
*
*
* @param[in] pConfig Northbridge configuration structure pointer.
*
*/
VOID
PcieLibPreTrainingInit (
IN AMD_NB_CONFIG *pConfig
)
{
UINT32 Value;
PCIE_CONFIG *pPcieConfig;
UINT32 ServerHotplugMask;
BOOLEAN SmuWa;
CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPreTrainingInit Enter\n"));
pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
ServerHotplugMask = 0;
//Init Misc registers
LibNbIndirectTableInit (
pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
0,
(INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieMiscInitTable[0],NULL),
(sizeof (PcieMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)),
pConfig
);
//Setup peer-to-peer
if (pPcieConfig->PcieConfiguration.Peer2Peer == ON) {
if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (3, pConfig)] == GFX_CONFIG_AABB) {
Value = 0x08080404;
} else {
Value = 0x08080008;
}
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG49, AccessWidth32, 0, Value, pConfig);
if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (12, pConfig)] == GFX_CONFIG_AABB) {
Value = 0xFFFF0404;
} else {
Value = 0xFFFF0008;
}
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2F, AccessWidth32, 0, Value, pConfig);
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG48, AccessWidth32, (UINT32)~(BIT8), 0xffff0000, pConfig);
}
//Remap device number
#ifndef DEVICE_REMAP_DISABLE
if (PciePortRemapInit (pConfig) != AGESA_SUCCESS ) {
REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_DEVICE_REMAP, 0, 0, 0, 0, pConfig);
}
#endif
#ifndef HOTPLUG_SUPPORT_DISABLED
ServerHotplugMask = PcieInitHotplug (pConfig);
#endif
LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4A, AccessWidth32, &Value, pConfig);
SmuWa = ((Value & BIT21) != 0) ? TRUE : FALSE;
if (SmuWa || ServerHotplugMask != 0) {
UINT32 BlockIndex;
UINT32 SmuWaData;
UINT16 Address;
UINT32 Data[MCU_CLEAR_BLOCK_LENGTH];
LibNbMcuControl (AssertReset, pConfig);
// clear SMU RAM
LibAmdMemFill (&Data[0], 0, sizeof (Data), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
for (Address = 0; Address < (16 * 1024); Address = Address + 4 * MCU_CLEAR_BLOCK_LENGTH) {
LibNbLoadMcuFirmwareBlock (Address, MCU_CLEAR_BLOCK_LENGTH, &Data[0], pConfig);
}
//Load SMU firmware
for (BlockIndex = 0; BlockIndex < Fm.NumberOfBlock; BlockIndex++) {
LibNbLoadMcuFirmwareBlock (Fm.BlockArray[BlockIndex].Address, Fm.BlockArray[BlockIndex].Length, Fm.BlockArray[BlockIndex].Data, pConfig);
}
if (SmuWa) {
SmuWaData = LibHtGetSmuWaData (pConfig);
LibNbLoadMcuFirmwareBlock (0xFE70, 0x1, &SmuWaData, pConfig);
}
SmuWaData = ((SmuWa == TRUE) ? 0x100 : 0x100) | ((ServerHotplugMask != 0) ? 0x1 : 0);
LibNbLoadMcuFirmwareBlock (0xFE74, 0x1, &SmuWaData, pConfig);
LibNbMcuControl (DeAssertReset, pConfig);
}
#ifndef HOTPLUG_SUPPORT_DISABLED
PcieCheckHotplug (ServerHotplugMask, pConfig);
#endif
}
INDIRECT_REG_ENTRY PcieCoreInitTable[] = {
{
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_REGC2,
(UINT32)~(BIT25),
BIT25
},
{
NB_BIFNB_REGC1,
(UINT32)~(BIT0),
(BIT0 + BIT1 + BIT2)
},
{
NB_BIFNB_REG1C,
0x0,
(4 << 6) + (4 << 1) + 1
}
};
INDIRECT_REG_ENTRY PcieRd790CoreInitTable[] = {
{
NB_BIFNB_REGC2,
(UINT32)~(BIT14),
(BIT14)
},
{
NB_BIFNB_REGC1,
(UINT32)~(BIT2),
0x0
},
};
/*----------------------------------------------------------------------------------------*/
/**
* Init Core registers
*
*
*
* @param[in] CoreId PCI Express Core ID
* @param[in] pConfig Northbridge configuration structure pointer.
*/
VOID
PcieLibCommonCoreInit (
IN CORE CoreId,
IN AMD_NB_CONFIG *pConfig
)
{
UINT32 CoreAddress;
NB_INFO NbInfo;
CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit (CoreId = %d) Enter\n", CoreId));
CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
NbInfo = LibNbGetRevisionInfo (pConfig);
LibNbIndirectTableInit (
pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
CoreAddress,
(INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieCoreInitTable[0],NULL),
(sizeof (PcieCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
pConfig
);
if (CoreAddress == SB_CORE) {
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG10 | CoreAddress, AccessWidth32, (UINT32)~BIT9, BIT9, pConfig);
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT26, BIT26 + BIT1, pConfig);
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG1C | CoreAddress, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig);
}
if ( NbInfo.Type < NB_SR5690 ) {
LibNbIndirectTableInit (
pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
CoreAddress,
(INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRd790CoreInitTable[0], NULL),
(sizeof (PcieRd790CoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
pConfig
);
}
CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit Exit\n"));
};
/*----------------------------------------------------------------------------------------*/
/**
* Init Core after training is completed
*
*
*
* @param[in] CoreId PCI Express Core ID
* @param[in] pConfig Northbridge configuration structure pointer. *
*/
VOID
PcieLibCoreAfterTrainingInit (
IN CORE CoreId,
IN AMD_NB_CONFIG *pConfig
)
{
UINT32 CoreAddress;
PCIE_CONFIG *pPcieConfig;
PCI_ADDR ClkPciAddress;
pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
ClkPciAddress = pConfig->NbPciAddress;
ClkPciAddress.Address.Function = 1;
LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG20 | CoreAddress, AccessWidth32, (UINT32)~(BIT9), 0, pConfig);
//Save core setting in scratch register
LibNbPciIndexWrite (
pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
NB_BIFNB_REG01 | CoreAddress,
AccessWidth32,
(UINT32*)&pPcieConfig->CoreSetting[CoreId],
pConfig
);
//Save general setting in scratch
LibNbEnableClkConfig (pConfig);
LibNbPciWrite (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig);
LibNbDisableClkConfig (pConfig);
}
INDIRECT_REG_ENTRY PciePortInitTable[] = {
{
NB_BIFNBP_REG02,
(UINT32)~(BIT15),
BIT15
},
{
NB_BIFNBP_REGA1,
(UINT32)~(BIT24 + BIT26),
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,
0xffff000f,
0x6830
},
{
NB_BIFNBP_REGC1,
0xfffffff0,
0xC
},
{
NB_BIFNBP_REG70,
(UINT32)~(BIT16 + BIT17 + BIT18),
BIT16 + BIT18
}
};
/*----------------------------------------------------------------------------------------*/
/**
* Init port registers
*
*
*
* @param[in] PortId PCI Express Port ID
* @param[in] pConfig Northbridge configuration structure pointer.
*
*/
VOID
PcieLibCommonPortInit (
IN PORT PortId,
IN AMD_NB_CONFIG *pConfig
)
{
PCI_ADDR Port;
PCIE_CONFIG *pPcieConfig;
UINT32 PcieSlotCapability;
UINT32 CoreAddress;
CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit PortId %d Enter\n", PortId));
Port = PcieLibGetPortPciAddress (PortId, pConfig);
CoreAddress = PcieLibGetCoreAddress (PcieLibGetCoreId (PortId, pConfig), pConfig);
pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
LibNbIndirectTableInit (
Port.AddressValue | NB_BIF_INDEX,
0x0,
(INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PciePortInitTable[0],NULL),
(sizeof (PciePortInitTable) / sizeof (INDIRECT_REG_ENTRY)),
pConfig
);
if (CoreAddress == GPP3a_CORE || CoreAddress == SB_CORE || CoreAddress == GPP3b_CORE) {
LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~(BIT16 + BIT17 + BIT18), (BIT17 + BIT18), pConfig);
if (CoreAddress == GPP3a_CORE) {
LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGB1, AccessWidth32, (UINT32)~(BIT22), BIT22, pConfig);
}
}
// Set completion timeout
LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessS3SaveWidth8, 0xF0, 0x6, pConfig);
//if (CoreAddress != SB_CORE) {
// LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig);
//}
//For hotplug ports
//if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ||
// pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON ||
// LibNbGetRevisionInfo (pConfig).Revision == NB_REV_A11) {
LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG20, AccessWidth32, (UINT32)~BIT19, 0x0, pConfig);
//}
// Enable Immediate ACK
if (pPcieConfig->ExtPortConfiguration[PortId].PortL1ImmediateACK == ON) {
LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA0, AccessWidth32, (UINT32)~BIT23, BIT23, pConfig);
}
//Set up slot capability
PcieSlotCapability = (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit << 7) |
((Port.Address.Device | Port.Address.Bus << 5 ) << 19);
LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessS3SaveWidth32, (UINT32)~((0x3ff << 7) | (0x1fff << 19)), PcieSlotCapability, pConfig);
LibNbPciRMW (Port.AddressValue | NB_PCIP_REG5A, AccessS3SaveWidth16, (UINT32)~BIT8, BIT8, pConfig);
//Set interrupt pin info
LibNbPciRMW (Port.AddressValue | NB_PCIP_REG3D, AccessS3SaveWidth8, 0x0, 0x1, pConfig);
CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit Exit\n"));
};