From 9292d89be84d6abf9257ddb872887d4f53b2a00e Mon Sep 17 00:00:00 2001 From: Kerry Sheh Date: Tue, 31 Jan 2012 20:39:37 +0800 Subject: RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code Change-Id: If9908ffeb5b707a660db38dc44f5118347cbcc06 Signed-off-by: Kerry Sheh Signed-off-by: Kerry Sheh Reviewed-on: http://review.coreboot.org/557 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c | 475 +++++++++++++++++++++++ 1 file changed, 475 insertions(+) create mode 100644 src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c (limited to 'src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c') diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c new file mode 100644 index 0000000000..1111556270 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c @@ -0,0 +1,475 @@ +/** + * @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")); +}; -- cgit v1.2.3