aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.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/nbPcieHotplug.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/nbPcieHotplug.c')
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c
new file mode 100644
index 0000000000..25ef38f587
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c
@@ -0,0 +1,343 @@
+/**
+ * @file
+ *
+ * Routines to support Hotplug.
+ *
+ *
+ *
+ * @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 "amdSbLib.h"
+
+#ifndef HOTPLUG_SUPPORT_DISABLED
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+#define ATTN_BUTTON_PRESENT BIT0
+#define PWR_CONTROLLER_PRESENT BIT1
+#define MRL_SENSOR_PRESENT BIT2
+#define ATTN_INDICATOR_PRESENT BIT3
+#define PWR_INDICATOR_PRESENT BIT4
+#define HOTPLUG_SURPRISE BIT5
+#define HOTPLUG_CAPABLE BIT6
+
+#define ATTN_BUTTON_PRESSED BIT0
+#define PWR_FAULT_DETECTED BIT1
+#define MRL_SENSOR_CHANGED BIT2
+#define PRESENCE_DETECT_CHANGED BIT3
+#define COMMAND_COMPLETED BIT4
+#define MRL_SENSOR_STATE BIT5
+#define PRESENCE_DETECT_STATE BIT6
+#define DL_STATE_CHANGED BIT8
+
+#define PWR_CONTROLLER_CNTL BIT10
+#define NO_COMMAND_COMPLETED_SUPPORTED BIT18
+#define SERVER_HOTPLUG_CAPABILITY \
+ (ATTN_BUTTON_PRESENT | PWR_CONTROLLER_PRESENT | ATTN_INDICATOR_PRESENT | PWR_INDICATOR_PRESENT | HOTPLUG_CAPABLE)
+#define NATIVE_HOTPLUG_CAPABILITY \
+ (HOTPLUG_SURPRISE | HOTPLUG_CAPABLE)
+
+#define SERVER_HOTPLUG 1
+#define NATIVE_HOTPLUG 2
+/*----------------------------------------------------------------------------------------
+ * 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
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Ports Hotplug capability.
+ * Initialize hotplug controller init port hotplug capability
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval AGESA_SUCCESS Hotplug controller successfully initialized.
+ * @retval AGESA_FAIL Failure during initialization of hotplug controller.
+ */
+/*----------------------------------------------------------------------------------------*/
+UINT32
+PcieInitHotplug (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 ServerHotplugPortMask;
+ PORT PortId;
+ PCI_ADDR ClkPciAddress;
+ NB_INFO NbInfo;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ ServerHotplugPortMask = 0;
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ if (NbInfo.Type == NB_SR5690) {
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON &&
+ pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == SERVER_HOTPLUG) {
+ UINT8 HpDescriptorRegister;
+ UINT8 HpDescriptorOffset;
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorOffset = (PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig))->HotplugAddress;
+ if (HpDescriptorOffset != 0xff) {
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorRegister = (PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig))->HotplugRegister;
+ //Enable CLK config
+ LibNbEnableClkConfig (pConfig);
+ //Setup descriptor
+ LibNbPciRMW (
+ ClkPciAddress.AddressValue | HpDescriptorRegister ,
+ AccessWidth32,
+ 0xffffffff,
+ ((1 << 3) | (pPcieConfig->ExtPortConfiguration[PortId].PortHotplugDevMap << 2) | pPcieConfig->ExtPortConfiguration[PortId].PortHotplugByteMap) << HpDescriptorOffset,
+ pConfig
+ );
+ //Hide CLK config
+ LibNbDisableClkConfig (pConfig);
+ // Enable power fault
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT4, BIT4, pConfig);
+ //Set up capability. Keep NO_COMMAND_COMPLETED_SUPPORTED (bit 18) to zero
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xfffbffff, SERVER_HOTPLUG_CAPABILITY, pConfig);
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ }
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == NATIVE_HOTPLUG) {
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xffffffff, NATIVE_HOTPLUG_CAPABILITY, pConfig);
+ }
+ }
+ }
+ }
+ return ServerHotplugPortMask;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Ports Hotplug capability.
+ * Initialize hotplug controller init port hotplug capability
+ *
+ * @param[in] ServerHotplugPortMask ServerHotplugPortMask
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval AGESA_SUCCESS Hotplug controller successfully initialized.
+ * @retval AGESA_FAIL Failure during initialization of hotplug controller.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+PcieCheckHotplug (
+ IN UINT32 ServerHotplugPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PORT PortId;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckHotplug Enter\n"));
+ //Check if Firmware loaded successfully
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ //Check Firmware Loaded successfully
+ if ((ServerHotplugPortMask & (1 << PortId)) != 0) {
+ UINT32 Count;
+ PCI_ADDR Port;
+ UINT16 SlotStatus;
+
+ Count = 30; //Setup counter for 30ms
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ do {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0);
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, &SlotStatus, pConfig);
+ } while ((SlotStatus & (ATTN_BUTTON_PRESSED | PWR_FAULT_DETECTED)) == 0 && --Count != 0);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Hotplug Firmware Init PortId = %d SlotStatus = 0x%x Retry = %d\n", PortId, SlotStatus, Count));
+ if ((SlotStatus & PWR_FAULT_DETECTED) != 0 || (SlotStatus & (PWR_FAULT_DETECTED | ATTN_BUTTON_PRESSED)) == 0) {
+ REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_HOTPLUG_INIT, PortId, 0, 0, 0, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " ERROR!!!Hotplug Firmware Init FAIL\n"));
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, (UINT32)~SERVER_HOTPLUG_CAPABILITY, 0x0, pConfig);
+ } else {
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ if ((SlotStatus & PRESENCE_DETECT_CHANGED) != 0) {
+ //Power on slot
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG70, AccessWidth16, (UINT32)~PWR_CONTROLLER_CNTL, 0x0, pConfig);
+ }
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckHotplug Exit\n"));
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Ports Hotplug capability.
+ * Initialize hotplug controller init port hotplug capability
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval AGESA_SUCCESS Hotplug controller successfully initialized.
+ * @retval AGESA_FAIL Failure during initialization of hotplug controller.
+ */
+/*----------------------------------------------------------------------------------------*/
+/*
+AGESA_STATUS
+PcieInitHotplug (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT32 ServerHotplugPortMask;
+ PORT PortId;
+ PCI_ADDR ClkPciAddress;
+ NB_INFO NbInfo;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ ServerHotplugPortMask = 0;
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ Status = AGESA_SUCCESS;
+ if (NbInfo.Type == NB_SR5690) {
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON &&
+ pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == SERVER_HOTPLUG) {
+ UINT8 HpDescriptorRegister;
+ UINT8 HpDescriptorOffset;
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorOffset = (PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig))->HotplugAddress;
+ if (HpDescriptorOffset != 0xff) {
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorRegister = (PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig))->HotplugRegister;
+ //Enable CLK config
+ LibNbEnableClkConfig (pConfig);
+ //Setup descriptor
+ LibNbPciRMW (
+ ClkPciAddress.AddressValue | HpDescriptorRegister ,
+ AccessWidth32,
+ 0xffffffff,
+ ((1 << 3) | (pPcieConfig->ExtPortConfiguration[PortId].PortHotplugDevMap << 2) | pPcieConfig->ExtPortConfiguration[PortId].PortHotplugByteMap) << HpDescriptorOffset,
+ pConfig
+ );
+ //Hide CLK config
+ LibNbDisableClkConfig (pConfig);
+ // Enable power fault
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT4, BIT4, pConfig);
+ //Set up capability. Keep NO_COMMAND_COMPLETED_SUPPORTED (bit 18) to zero
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xfffbffff, SERVER_HOTPLUG_CAPABILITY, pConfig);
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ }
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == NATIVE_HOTPLUG) {
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xffffffff, NATIVE_HOTPLUG_CAPABILITY, pConfig);
+ }
+ }
+ }
+ if (ServerHotplugPortMask != 0) {
+ UINT32 FirmwareLength;
+ FirmwareLength = sizeof (Firmware);
+ if (FirmwareLength > 0) {
+ UINT32 *pFirmware;
+ pFirmware = (UINT32*)FIX_PTR_ADDR (&Firmware[0], NULL);
+ //Load firmware
+ LibNbMcuControl (AssertReset, pConfig);
+ LibNbLoadMcuFirmwareBlock (0x200, (sizeof (Firmware) - 64), pFirmware, pConfig);
+ LibNbLoadMcuFirmwareBlock (0xFFC0, 64, &pFirmware[(sizeof (Firmware) - 64) / 4], pConfig);
+ LibNbMcuControl (DeAssertReset, pConfig);
+ }
+ }
+ //Check if Firmware loaded successfully
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ //Check Firmware Loaded successfully
+ if ((ServerHotplugPortMask & (1 << PortId)) != 0) {
+ UINT32 Count;
+ PCI_ADDR Port;
+ UINT16 SlotStatus;
+
+ Count = 30; //Setup counter for 30ms
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ do {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0);
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, &SlotStatus, pConfig);
+ } while ((SlotStatus & (ATTN_BUTTON_PRESSED | PWR_FAULT_DETECTED)) == 0 && --Count != 0);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Hotplug Firmware Init PortId = %d SlotStatus = 0x%x Retry = %d\n", PortId, SlotStatus, Count));
+ if ((SlotStatus & PWR_FAULT_DETECTED) != 0 || (SlotStatus & (PWR_FAULT_DETECTED | ATTN_BUTTON_PRESSED)) == 0) {
+ Status = AGESA_ERROR;
+ REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_HOTPLUG_INIT, PortId, 0, 0, 0, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " ERROR!!!Hotplug Firmware Init FAIL\n", PortId));
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, ~SERVER_HOTPLUG_CAPABILITY, 0x0, pConfig);
+ } else {
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ if ((SlotStatus & PRESENCE_DETECT_CHANGED) != 0) {
+ //Power on slot
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG70, AccessWidth16, ~PWR_CONTROLLER_CNTL, 0x0, pConfig);
+ }
+ }
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Exit. Status[0x%x]\n", Status));
+ return Status;
+}
+*/
+#endif \ No newline at end of file