From 9292d89be84d6abf9257ddb872887d4f53b2a00e Mon Sep 17 00:00:00 2001 From: Kerry Sheh Date: Tue, 31 Jan 2012 20:39:37 +0800 Subject: RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code Change-Id: If9908ffeb5b707a660db38dc44f5118347cbcc06 Signed-off-by: Kerry Sheh Signed-off-by: Kerry Sheh Reviewed-on: http://review.coreboot.org/557 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/vendorcode/amd/cimx/rd890/nbLib.c | 1138 +++++++++++++++++++++++++++++++++ 1 file changed, 1138 insertions(+) create mode 100644 src/vendorcode/amd/cimx/rd890/nbLib.c (limited to 'src/vendorcode/amd/cimx/rd890/nbLib.c') diff --git a/src/vendorcode/amd/cimx/rd890/nbLib.c b/src/vendorcode/amd/cimx/rd890/nbLib.c new file mode 100644 index 000000000000..5862768bb0a2 --- /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); + } +} -- cgit v1.2.3