aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c
diff options
context:
space:
mode:
authorKerry Sheh <shekairui@gmail.com>2012-01-31 20:39:37 +0800
committerPatrick Georgi <patrick@georgi-clan.de>2012-02-02 13:54:36 +0100
commit9292d89be84d6abf9257ddb872887d4f53b2a00e (patch)
tree9eaa548f1742745f57fc92a12734649fec8db1cd /src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c
parent17670866a0d12839bc2a4c852210ccf11d3cb4b2 (diff)
RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code
Change-Id: If9908ffeb5b707a660db38dc44f5118347cbcc06 Signed-off-by: Kerry Sheh <kerry.she@amd.com> Signed-off-by: Kerry Sheh <shekairui@gmail.com> Reviewed-on: http://review.coreboot.org/557 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c')
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c475
1 files changed, 475 insertions, 0 deletions
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"));
+};