aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/cimx/rd890/nbLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/cimx/rd890/nbLib.c')
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbLib.c1138
1 files changed, 1138 insertions, 0 deletions
diff --git a/src/vendorcode/amd/cimx/rd890/nbLib.c b/src/vendorcode/amd/cimx/rd890/nbLib.c
new file mode 100644
index 0000000000..5862768bb0
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbLib.c
@@ -0,0 +1,1138 @@
+/**
+ * @file
+ *
+ * NB library functions.
+ *
+ *
+ *
+ * @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 "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * 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
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get silicon type and revision info.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr configuration structure pointer.
+ * @retval NB_INFO Northbrige Info Structure.
+ */
+/*----------------------------------------------------------------------------------------*/
+NB_INFO
+LibNbGetRevisionInfo (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ NB_INFO RevisionInfo;
+ UINT16 DeviceId;
+ UINT8 RevisionId;
+ UINT32 PrivateId;
+ LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x8, AccessWidth8, &RevisionId, NbConfigPtr);
+ RevisionInfo.Revision = RevisionId;
+ LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x2, AccessWidth16, &DeviceId, NbConfigPtr);
+ switch (DeviceId) {
+ case 0x5956:
+ RevisionInfo.Type = NB_RD890TV;
+ break;
+ case 0x5957:
+ RevisionInfo.Type = NB_RX780;
+ break;
+ case 0x5958:
+ RevisionInfo.Type = NB_RD780;
+ break;
+ case 0x5A10:
+ RevisionInfo.Type = NB_SR5690;
+ break;
+ case 0x5A11:
+ RevisionInfo.Type = NB_RD890;
+ break;
+ case 0x5A12:
+ RevisionInfo.Type = NB_SR5670;
+ break;
+ case 0x5A13:
+ RevisionInfo.Type = NB_SR5650;
+ break;
+ case 0x5A14:
+ RevisionInfo.Type = NB_990FX;
+ LibNbPciIndexRead (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG7D, AccessWidth32, &PrivateId, NbConfigPtr);
+ PrivateId = (PrivateId >> 21) & 0x0f;
+ if (PrivateId == 1) {
+ RevisionInfo.Type = NB_990FX;
+ }
+ if (PrivateId == 2) {
+ RevisionInfo.Type = NB_990X;
+ }
+ if (PrivateId == 3) {
+ RevisionInfo.Type = NB_970;
+ }
+ break;
+ default:
+ RevisionInfo.Type = NB_UNKNOWN;
+ CIMX_ASSERT (FALSE);
+ }
+ return RevisionInfo;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Call Back routine.
+ *
+ *
+ *
+ * @param[in] CallBackId Callback ID.
+ * @param[in] Data Callback specific data.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+LibNbCallBack (
+ IN UINT32 CallBackId,
+ IN OUT UINTN Data,
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CALLOUT_ENTRY CallBackPtr = GET_BLOCK_CONFIG_PTR (NbConfigPtr)->StandardHeader.CalloutPtr;
+
+ Status = AGESA_UNSUPPORTED;
+ if (CallBackPtr != NULL) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack CallBackId = 0x%x\n", CallBackId));
+ Status = (*CallBackPtr) (CallBackId, Data, GET_BLOCK_CONFIG_PTR (NbConfigPtr));
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack Return = 0x%x\n", Status));
+ }
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Call Back routine.
+ *
+ *
+ *
+ * @param[in] SystemApi Pointer to System API
+ * @param[in] ConfigPtr Northbridge block configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+LibSystemApiCall (
+ IN SYSTEM_API SystemApi,
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ API_WORKSPACE Workspace;
+ UINT8 NorthbridgeId;
+
+ LibAmdMemFill (&Workspace, 0, sizeof (API_WORKSPACE), (AMD_CONFIG_PARAMS *)&(ConfigPtr->StandardHeader));
+ Workspace.ConfigPtr = ConfigPtr;
+ Workspace.Status = AGESA_SUCCESS;
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ ConfigPtr->Northbridges[NorthbridgeId].ConfigPtr = &Workspace.ConfigPtr;
+ }
+ if (SystemApi != NULL) {
+ (*SystemApi)(ConfigPtr);
+ }
+ return Workspace.Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Call Back routine.
+ *
+ *
+ *
+ * @param[in] NbApi Pointer to NB API
+ * @param[in] ConfigPtr Northbridge block configuration structure pointer
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+LibNbApiCall (
+ IN NB_API NbApi,
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ UINT8 NorthbridgeId;
+ AGESA_STATUS Status;
+
+ Status = AGESA_SUCCESS;
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ AMD_NB_CONFIG *NbConfigPtr = &ConfigPtr->Northbridges[NorthbridgeId];
+ ConfigPtr->CurrentNorthbridge = NorthbridgeId;
+ if (!LibNbIsDevicePresent (NbConfigPtr->NbPciAddress, NbConfigPtr)) {
+ REPORT_EVENT (AGESA_WARNING, GENERAL_ERROR_NB_NOT_PRESENT, 0 , 0, 0, 0, NbConfigPtr);
+ continue;
+ }
+ if (NbApi != NULL) {
+ Status = (*NbApi) (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ break;
+ }
+ }
+ }
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write PCI register.
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Width Access width.
+ * @param[in] Value Pointer to new register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciWrite (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR DeviceAddress;
+ DeviceAddress.AddressValue = Address;
+ LibAmdPciWrite (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read PCI register
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Width Access width.
+ * @param[in] Value Pointer to save register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbPciRead (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR DeviceAddress;
+ DeviceAddress.AddressValue = Address;
+ LibAmdPciRead (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write PCI register
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Width Access width.
+ * @param[in] Mask AND Mask.
+ * @param[in] Data OR Mask.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbPciRMW (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbPciRead (Address, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbPciWrite (Address, Width, &Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read PCI Index/Data Address space
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address.
+ * @param[in] Width Access width of Index/Data register.
+ * @param[in] Value Pointer to save register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciIndexRead (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ OUT UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 IndexOffset;
+ IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81)));
+ LibNbPciWrite (Address, Width, &Index, NbConfigPtr);
+ LibNbPciRead (Address + IndexOffset, Width, Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write PCI Index/Data Address space
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address.
+ * @param[in] Width Access width of Index/Data register.
+ * @param[in] Value Pointer to save register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciIndexWrite (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 IndexOffset;
+ IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81)));
+ LibNbPciWrite (Address, Width, &Index, NbConfigPtr);
+ LibNbPciWrite (Address + IndexOffset , Width, Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write PCI Index/Data Address space
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address.
+ * @param[in] Width Access width of Index/Data register.
+ * @param[in] Mask AND Mask.
+ * @param[in] Data OR Mask.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciIndexRMW (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbPciIndexRead (Address, Index, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbPciIndexWrite (Address, Index, Width, &Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Program table of indirect register.
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address. Index address OR with INDIRECT_REG_ENTRY.Register
+ * @param[in] pTable Pointer to indirect register table.
+ * @param[in] Length Number of entry in indirect register table.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbIndirectTableInit (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN INDIRECT_REG_ENTRY *pTable,
+ IN UINTN Length,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINTN i;
+ for (i = 0; i < Length; i++) {
+ LibNbPciIndexRMW (Address, Index | pTable[i].Register , AccessS3SaveWidth32, pTable[i].Mask, pTable[i].Data, NbConfigPtr);
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Find PCI capability pointer
+ *
+ *
+ *
+ *
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+
+UINT8
+LibNbFindPciCapability (
+ IN UINT32 Address,
+ IN UINT8 CapabilityId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT8 CapabilityPtr;
+ UINT8 CurrentCapabilityId;
+ PCI_ADDR Device;
+ Device.AddressValue = Address;
+ CapabilityPtr = 0x34;
+ if (!LibNbIsDevicePresent (Device, NbConfigPtr)) {
+ return 0;
+ }
+ while (CapabilityPtr != 0) {
+ LibNbPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, NbConfigPtr);
+ if (CapabilityPtr) {
+ LibNbPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, NbConfigPtr);
+ if (CurrentCapabilityId == CapabilityId) break;
+ CapabilityPtr++;
+ }
+ }
+ return CapabilityPtr;
+}
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Find PCIe extended capability pointer
+ *
+ *
+ *
+ *
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+
+UINT16
+LibNbFindPcieExtendedCapability (
+ IN UINT32 Address,
+ IN UINT16 ExtendedCapabilityId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT16 CapabilityPtr;
+ UINT32 ExtendedCapabilityIdBlock;
+ if (LibNbFindPciCapability (Address, 0x10, NbConfigPtr) != 0) {
+ CapabilityPtr = 0x100;
+ LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr);
+ if (ExtendedCapabilityIdBlock != 0 && (UINT16)ExtendedCapabilityIdBlock != 0xffff) {
+ do {
+ if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) {
+ return CapabilityPtr;
+ }
+ CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff);
+ LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr);
+ } while (CapabilityPtr != 0);
+ }
+ }
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read IO space
+ *
+ *
+ *
+ * @param[in] Address IO Port address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to save IO port value;
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbIoRead (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdIoRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write IO space
+ *
+ *
+ *
+ * @param[in] Address IO Port address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to new IO port value
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+VOID
+LibNbIoWrite (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdIoWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write IO space
+ *
+ *
+ *
+ * @param[in] Address IO Port address.
+ * @param[in] Width Access width
+ * @param[in] Mask AND Mask
+ * @param[in] Data OR Mask
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbIoRMW (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbIoRead (Address, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbIoWrite (Address, Width, &Value, NbConfigPtr);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read CPU HT link Phy register
+ *
+ *
+ *
+ * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
+ * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
+ * @param[in] Register Register address.
+ * @param[in] Value Pointer to save register value
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbCpuHTLinkPhyRead (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ OUT UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Data;
+ PCI_ADDR CpuPciAddress;
+ UINT8 LinkId;
+ LinkId = Link & 0xf;
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0);
+ LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | ((Register & 0xfe00)?BIT29:0), NbConfigPtr);
+ do {
+ LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr);
+ } while ((Data & BIT31) == 0);
+ LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write CPU HT link Phy register
+ *
+ *
+ *
+ * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
+ * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
+ * @param[in] Register Register address.
+ * @param[in] Value Pointer to new register value
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbCpuHTLinkPhyWrite (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ IN UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Data;
+ PCI_ADDR CpuPciAddress;
+ UINT8 LinkId;
+ LinkId = Link & 0xf;
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0);
+ LibNbPciWrite (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr);
+ LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | BIT30 | ((Register & 0xfe00)?BIT29:0), NbConfigPtr);
+ do {
+ LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr);
+ } while ((Data & BIT31) == 0);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write CPU HT link Phy register
+ *
+ *
+ *
+ * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
+ * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
+ * @param[in] Register Register address.
+ * @param[in] Mask AND Mask.
+ * @param[in] Data OR Mask.
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbCpuHTLinkPhyRMW (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbCpuHTLinkPhyRead (Node, Link, Register, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbCpuHTLinkPhyWrite (Node, Link, Register, &Value, NbConfigPtr);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable Clock Config space access.
+ * Enable access to Clock Config Space at 0:0:1 PCI address.
+ *
+ *
+ * @param[in] pConfig Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbEnableClkConfig (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, BIT0, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Disable Clock Config space access.
+ * Disable access to Clock Config Space at 0:0:1 PCI address.
+ *
+ *
+ * @param[in] pConfig Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbDisableClkConfig (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, 0x0 , pConfig);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if PCI Device Present
+ *
+ *
+ *
+ * @param[in] Device Device PCI address.
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ * @retval TRUE Device present.
+ * @retval FALSE Device not present.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+BOOLEAN
+LibNbIsDevicePresent (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 VendorId;
+ LibNbPciRead (Device.AddressValue, AccessWidth32, &VendorId, NbConfigPtr);
+ return (VendorId == 0xffffffff)?FALSE:TRUE;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if IOMMU enabled
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ * @retval TRUE IOMMU not enabled.
+ * @retval FALSE IOMMU not enabled.
+ */
+/*----------------------------------------------------------------------------------------*/
+BOOLEAN
+LibNbIsIommuEnabled (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR IommuAddress;
+ IommuAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue;
+ IommuAddress.Address.Function = 2;
+ if (LibNbIsDevicePresent (IommuAddress, NbConfigPtr)) {
+ UINT8 Value;
+ LibNbPciRead (IommuAddress.AddressValue | 0x44, AccessWidth8, &Value, NbConfigPtr);
+ if ((Value & BIT0) != 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Reverse bit in DWORD.
+ * Reverse bits in bitfield inside DWORD.
+ *
+ *
+ * @param[in] Data Value to reverse.
+ * @param[in] StartBit Start bit.
+ * @param[in] StopBit Stop bit.
+ * @retval Reversed Value.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+UINT32
+LibNbBitReverse (
+ IN UINT32 Data,
+ IN UINT8 StartBit,
+ IN UINT8 StopBit
+ )
+{
+
+ UINT32 Bitr;
+ UINT32 Bitl;
+ UINT32 Distance;
+
+ while (StartBit < StopBit) {
+ Bitr = Data & (1 << StartBit );
+ Bitl = Data & (1 << StopBit );
+ Distance = StopBit - StartBit;
+ Data = (Data & ((UINT32)~(Bitl | Bitr))) | (Bitr << Distance ) | (Bitl >> Distance);
+ StartBit++;
+ StopBit--;
+ }
+ return Data;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read CPU family
+ *
+ *
+ *
+ * @retval 0xXX00000 CPU family.
+ *
+ */
+UINT32
+LibNbGetCpuFamily (
+ VOID
+ )
+{
+ CPUID_DATA Cpuid;
+ CpuidRead (0x1, &Cpuid);
+ return Cpuid.EAX_Reg & 0xff00000;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Load Firmware block
+ *
+ *
+ *
+ * @param[in] Address Address to load firmware
+ * @param[in] Size Firmware block size
+ * @param[in] FirmwareBlockPtr Pointer to firmware block
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ */
+VOID
+LibNbLoadMcuFirmwareBlock (
+ IN UINT16 Address,
+ IN UINT16 Size,
+ IN UINT32 *FirmwareBlockPtr,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 i;
+ PCI_ADDR ClkPciAddress;
+ UINT32 Selector;
+
+ Selector = (Address >= 0x200)?0x0000000:0x10000;
+ ClkPciAddress = NbConfigPtr->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ LibNbEnableClkConfig (NbConfigPtr);
+ for (i = 0; i < Size; i++) {
+ LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address + (i * 4)), AccessWidth32, &FirmwareBlockPtr[i], NbConfigPtr);
+ }
+ LibNbDisableClkConfig (NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read SMU firmware ram
+ *
+ *
+ *
+ * @param[in] Address Address to read
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ */
+UINT32
+LibNbReadMcuRam (
+ IN UINT16 Address,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ PCI_ADDR ClkPciAddress;
+ UINT32 Selector;
+
+ Selector = (Address >= 0x200) ? 0x0000000 : 0x10000;
+ ClkPciAddress = NbConfigPtr->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ LibNbEnableClkConfig (NbConfigPtr);
+ LibNbPciIndexRead (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address), AccessWidth32, &Value, NbConfigPtr);
+ LibNbDisableClkConfig (NbConfigPtr);
+ return Value;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * MCU Control
+ *
+ *
+ *
+ * @param[in] Operation Set/Reset MCU controller
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+VOID
+LibNbMcuControl (
+ IN NB_MCU_MODE Operation,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR ClkPciAddress;
+ UINT32 Value;
+
+ Value = (Operation == AssertReset)?0x00000ee1:0x00000ee2;
+ ClkPciAddress = NbConfigPtr->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "LibNbMcuControl Operation [0x%x]\n", Operation));
+ LibNbEnableClkConfig (NbConfigPtr);
+ LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, 0x00030000, AccessWidth32, &Value, NbConfigPtr);
+ LibNbDisableClkConfig (NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write memory space
+ *
+ *
+ *
+ * @param[in] Address Memory address.
+ * @param[in] Width Access width
+ * @param[in] Mask AND Mask
+ * @param[in] Data OR Mask
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbMemRMW (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbMemRead (Address, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbMemWrite (Address, Width, &Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read memory space
+ *
+ *
+ *
+ * @param[in] Address Memory address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to memory to store value
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbMemRead (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdMemRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write memory space
+ *
+ *
+ *
+ * @param[in] Address Memory address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to memory to get value
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbMemWrite (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdMemWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan Pci Bridge
+ *
+ *
+ *
+ * @param[in] This Pointer to PCI topology scan protocol
+ * @param[in] Bridge Address of PCI to PCI bridge to scan.
+ */
+
+SCAN_STATUS
+LibNbScanPciBridgeBuses (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Bridge
+ )
+{
+ SCAN_STATUS Status;
+ UINT8 CurrentBus;
+ UINT8 MinBus;
+ UINT8 MaxBus;
+ PCI_ADDR Device;
+
+ CIMX_ASSERT (This != NULL);
+ if (This->ScanBus == NULL) {
+ return SCAN_FINISHED;
+ }
+ LibNbPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &MinBus, This->pConfig);
+ LibNbPciRead (Bridge.AddressValue | 0x1A, AccessWidth8, &MaxBus, This->pConfig);
+ if (MinBus == 0 || MaxBus == 0) {
+ return SCAN_FINISHED;
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Scan bridge %d:%d:%d \n", Bridge.Address.Bus, Bridge.Address.Device, Bridge.Address.Function));
+ for (CurrentBus = MinBus; CurrentBus <= MaxBus; CurrentBus++) {
+ Device.AddressValue = MAKE_SBDFO (0, CurrentBus, 0, 0, 0);
+ Status = This->ScanBus (This, Device);
+ }
+ return SCAN_FINISHED;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan Pci Bus
+ *
+ *
+ *
+ * @param[in] This Pointer to PCI topology scan protocol
+ * @param[in] Device Pci address device to start bus scan from
+ */
+/*----------------------------------------------------------------------------------------*/
+SCAN_STATUS
+LibNbScanPciBus (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Device
+ )
+{
+ SCAN_STATUS Status;
+ UINT32 CurrentDevice;
+ CIMX_ASSERT (This != NULL);
+ if (This->ScanDevice == NULL) {
+ return SCAN_FINISHED;
+ }
+ for (CurrentDevice = Device.Address.Device; CurrentDevice <= 0x1f; CurrentDevice++) {
+ Device.Address.Device = CurrentDevice;
+ if (LibNbIsDevicePresent (Device, This->pConfig)) {
+ Status = This->ScanDevice (This, Device);
+ if (Status == SCAN_STOP_BUS_ENUMERATION) {
+ return Status;
+ }
+
+ }
+ }
+ return SCAN_FINISHED;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan Pci Device
+ *
+ *
+ *
+ * @param[in] This Pointer to PCI topology scan protocol
+ * @param[in] Device Pci address device to scan
+ */
+/*----------------------------------------------------------------------------------------*/
+
+SCAN_STATUS
+LibNbScanPciDevice (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Device
+ )
+{
+ SCAN_STATUS Status;
+ UINT8 Header;
+ UINT32 CurrentFunction;
+ UINT32 MaxFunction;
+ CIMX_ASSERT (This != NULL);
+ if (This->ScanFunction == NULL) {
+ return SCAN_FINISHED;
+ }
+ LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Header, This->pConfig);
+ MaxFunction = (Header & 0x80)?7:0;
+ for (CurrentFunction = Device.Address.Function; CurrentFunction <= MaxFunction; CurrentFunction++) {
+ Device.Address.Function = CurrentFunction;
+ if (LibNbIsDevicePresent (Device, This->pConfig)) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Scan function %d:%d:%d \n", Device.Address.Bus, Device.Address.Device, Device.Address.Function));
+ Status = This->ScanFunction (This, Device);
+ if (Status == SCAN_STOP_DEVICE_ENUMERATION || Status == SCAN_STOP_BUS_ENUMERATION) {
+ return Status;
+ }
+ }
+ }
+ return SCAN_FINISHED;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set default Indexes
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbSetDefaultIndexes (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR PciAddress;
+ PORT PortId;
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, SB_CORE, NbConfigPtr);
+ PciAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ PciAddress.Address.Device = PortId;
+ LibNbPciRMW (PciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
+ }
+}