diff options
Diffstat (limited to 'src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c')
-rw-r--r-- | src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c | 343 |
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 |