RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code
[coreboot.git] / 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 (file)
index 0000000..1111556
--- /dev/null
@@ -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"));
+};