From nobody Mon Feb 9 11:51:34 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+40321+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+40321+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1557395648; cv=none; d=zoho.com; s=zohoarc; b=Ex5qqiM04zVTR+D2cE50gVJhCWfqXAbFZ0ZAYbVd+xEolmzHdKuP+2VeRCKC+nBx8NUm5tZS33JYNaCvkoAM0ITUN6Tn7fFsLFubDA3arNjIMUeARCCeHQLHQeVM/NicHUyI5eo861uw9XOcymALn1PwDuRPpA6i03yKD0LjUuw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1557395648; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=3/+OoApvk5fQ7Dy84G+LApYbqM6cwwon4AM9asjkGn4=; b=SRWyPhRtfJnqThb1hcZGADNWb19uw3uHAH9UQhIMNqFL+/fFyiz5YAoo5l3fsTNBJiGsG9mFS8NiQA8SzLXyGkjfalkDegRfgPqHj6QIMD3g7PNBeN6ACfRyLV77e8OrXIp7IPp+PLLwe9bNy7kDCVTmk7xAc3Tw10juZRy4umM= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+40321+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1557395648266563.4543621087473; Thu, 9 May 2019 02:54:08 -0700 (PDT) Return-Path: X-Received: from mail-lf1-f67.google.com (mail-lf1-f67.google.com [209.85.167.67]) by groups.io with SMTP; Thu, 09 May 2019 02:54:07 -0700 X-Received: by mail-lf1-f67.google.com with SMTP id h13so1094276lfc.7 for ; Thu, 09 May 2019 02:54:06 -0700 (PDT) X-Gm-Message-State: APjAAAVt3XEsue4bCF58KJw4Y1W9tO2tmr6VlmLn5zjrXHTTmeGhUyGO OYZklVzvRbEMRJ/2lupBXCYAMduforc= X-Google-Smtp-Source: APXvYqwpDPJQuS4jBsir9hR3ZVCRS6kbks9ErBeZNSRJ2cSfyoIDj2WKWG3LSixOdlZnJYjPMHr8vw== X-Received: by 2002:ac2:5143:: with SMTP id q3mr2020963lfd.169.1557395644487; Thu, 09 May 2019 02:54:04 -0700 (PDT) X-Received: from gilgamesh.semihalf.com (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id l25sm276668lfk.57.2019.05.09.02.54.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 May 2019 02:54:03 -0700 (PDT) From: "Marcin Wojtas" To: devel@edk2.groups.io Cc: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, mw@semihalf.com, jsd@semihalf.com, jaz@semihalf.com, kostap@marvell.com, Jici.Gao@arm.com, rebecca@bluestop.org, kettenis@jive.eu Subject: [edk2-devel] [edk2-platforms: PATCH 07/14] Marvell/Armada7k8k: Implement PciHostBridgeLib Date: Thu, 9 May 2019 11:53:35 +0200 Message-Id: <1557395622-32425-8-git-send-email-mw@semihalf.com> In-Reply-To: <1557395622-32425-1-git-send-email-mw@semihalf.com> References: <1557395622-32425-1-git-send-email-mw@semihalf.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,mw@semihalf.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1557395647; bh=AQH0pSn2ofZkUtYOihi5wrS5rVA88z3FBfYN0X6PSts=; h=Cc:Date:From:Reply-To:Subject:To; b=kxp4P4O0hKGmKZZ7Uw4F3xuX2rkE6fe0m65/rKf5NGdsPAHClyoz0QNw3zIegFWCPOr laO98xib0I2iyqaWJRSGgm2Fg6fAb6aFRLcmG2poF/8n9Zot7TSeOMON3X66brbfgTlNK nD0BK7OjVrn3LIE8JrVMm01XCNDdzIX74QY= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add an implementation of the PciHostBridgeLib glue library that describes the PCIe RC on this SoC so that the generic PCI host bridge driver can attach to it. This includes a constructor which performs the SoC specific init and training sequences. This patch is based on work of Ard Biesheuvel and Jing Hua / Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Marcin Wojtas --- Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostBridg= eLib.inf | 52 +++ Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostBridg= eLibConstructor.h | 95 ++++++ Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostBridg= eLib.c | 244 +++++++++++++++ Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostBridg= eLibConstructor.c | 330 ++++++++++++++++++++ 4 files changed, 721 insertions(+) create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBri= dgeLib/PciHostBridgeLib.inf create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBri= dgeLib/PciHostBridgeLibConstructor.h create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBri= dgeLib/PciHostBridgeLib.c create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBri= dgeLib/PciHostBridgeLibConstructor.c diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/= PciHostBridgeLib.inf b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHost= BridgeLib/PciHostBridgeLib.inf new file mode 100644 index 0000000..e46f71d --- /dev/null +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHost= BridgeLib.inf @@ -0,0 +1,52 @@ +## @file +# PCI Host Bridge Library instance for Marvell Armada 7k/8k SOC +# +# Copyright (c) 2017, Linaro Ltd. All rights reserved.
+# Copyright (c) 2019 Marvell International Ltd. All rights reserved.
+# +# This program and the accompanying materials are licensed and made avail= able +# under the terms and conditions of the BSD License which accompanies this +# distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR +# IMPLIED. +# +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D Armada7k8kPciHostBridgeLib + FILE_GUID =3D 7f989c9d-02a0-4348-8aeb-ab2e1566fb18 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PciHostBridgeLib|DXE_DRIVER + CONSTRUCTOR =3D Armada7k8kPciHostBridgeLibConstructor + +[Sources] + PciHostBridgeLib.c + PciHostBridgeLibConstructor.c + +[Packages] + ArmPkg/ArmPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Silicon/Marvell/Marvell.dec + +[LibraryClasses] + ArmLib + ArmadaSoCDescLib + DebugLib + DevicePathLib + MemoryAllocationLib + MvGpioLib + UefiBootServicesTableLib + +[Protocols] + gEmbeddedGpioProtocolGuid + gMarvellBoardDescProtocolGuid + +[Depex] + gMarvellPlatformInitCompleteProtocolGuid diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/= PciHostBridgeLibConstructor.h b/Silicon/Marvell/Armada7k8k/Library/Armada7k= 8kPciHostBridgeLib/PciHostBridgeLibConstructor.h new file mode 100644 index 0000000..ff9d919 --- /dev/null +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHost= BridgeLibConstructor.h @@ -0,0 +1,95 @@ +/** @file + PCI Host Bridge Library instance for Marvell 70x0/80x0 + + Copyright (c) 2017, Linaro Ltd. All rights reserved.
+ Copyright (c) 2019 Marvell International Ltd. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#ifndef __PCI_HOST_BRIDGE_LIB_CONSTRUCTOR_H__ +#define __PCI_HOST_BRIDGE_LIB_CONSTRUCTOR_H__ + +#define IATU_VIEWPORT_OFF 0x900 +#define IATU_VIEWPORT_INBOUND BIT31 +#define IATU_VIEWPORT_OUTBOUND 0 +#define IATU_VIEWPORT_REGION_INDEX(Idx) ((Idx) & 7) + +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0 0x904 +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM 0x0 +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO 0x2 +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0 0x4 +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1 0x5 + +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0 0x908 +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN BIT31 +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_CFG_SHIFT_MODE BIT28 + +#define IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0 0x90C +#define IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0 0x910 +#define IATU_LIMIT_ADDR_OFF_OUTBOUND_0 0x914 +#define IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0 0x918 +#define IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0 0x91C + +#define PORT_LINK_CTRL_OFF 0x710 +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x1 (0x01 << 16) +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x2 (0x03 << 16) +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x4 (0x07 << 16) +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x8 (0x0f << 16) +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x16 (0x1f << 16) +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_MASK (0x3f << 16) + +#define GEN2_CTRL_OFF 0x80c +#define GEN2_CTRL_OFF_NUM_OF_LANES(n) (((n) & 0x1f) = << 8) +#define GEN2_CTRL_OFF_NUM_OF_LANES_MASK (0x1f << 8) +#define GEN2_CTRL_OFF_DIRECT_SPEED_CHANGE BIT17 + +#define PCIE_GLOBAL_CTRL_OFFSET 0x8000 +#define PCIE_GLOBAL_APP_LTSSM_EN BIT2 +#define PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC (0x4 << 4) +#define PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK (0xF << 4) + +#define PCIE_GLOBAL_STATUS_REG 0x8008 +#define PCIE_GLOBAL_STATUS_RDLH_LINK_UP BIT1 +#define PCIE_GLOBAL_STATUS_PHY_LINK_UP BIT9 + +#define PCIE_PM_STATUS 0x8014 +#define PCIE_PM_LTSSM_STAT_MASK (0x3f << 3) + +#define PCIE_GLOBAL_INT_MASK1_REG 0x8020 +#define PCIE_INT_A_ASSERT_MASK BIT9 +#define PCIE_INT_B_ASSERT_MASK BIT10 +#define PCIE_INT_C_ASSERT_MASK BIT11 +#define PCIE_INT_D_ASSERT_MASK BIT12 + +#define PCIE_ARCACHE_TRC_REG 0x8050 +#define PCIE_AWCACHE_TRC_REG 0x8054 +#define PCIE_ARUSER_REG 0x805C +#define PCIE_AWUSER_REG 0x8060 + +#define ARCACHE_DEFAULT_VALUE 0x3511 +#define AWCACHE_DEFAULT_VALUE 0x5311 + +#define AX_USER_DOMAIN_INNER_SHAREABLE (0x1 << 4) +#define AX_USER_DOMAIN_OUTER_SHAREABLE (0x2 << 4) +#define AX_USER_DOMAIN_MASK (0x3 << 4) + +#define PCIE_LINK_CAPABILITY 0x7C +#define PCIE_LINK_CTL_2 0xA0 +#define TARGET_LINK_SPEED_MASK 0xF +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +#define PCIE_GEN3_EQU_CTRL 0x8A8 +#define GEN3_EQU_EVAL_2MS_DISABLE BIT5 + +#define PCIE_LINK_UP_TIMEOUT_US 40000 + +#endif diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/= PciHostBridgeLib.c b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBr= idgeLib/PciHostBridgeLib.c new file mode 100644 index 0000000..ff6288c --- /dev/null +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHost= BridgeLib.c @@ -0,0 +1,244 @@ +/** @file + PCI Host Bridge Library instance for Marvell Armada 70x0/80x0 + + Copyright (c) 2017, Linaro Ltd. All rights reserved.
+ Copyright (c) 2019 Marvell International Ltd. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#pragma pack(1) +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH; +#pragma pack () + +STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath =3D { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) + } + }, + EISA_PNP_ID(0x0A08), // PCI Express + 0 + }, + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] =3D { + L"Mem", L"I/O", L"Bus" +}; + +/** + Return all the root bridge instances in an array. + + @param Count Return the count of root bridge instances. + + @return All the root bridge instances in an array. + The array should be passed into PciHostBridgeFreeRootBridges() + when it's not used. + +**/ +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeGetRootBridges ( + UINTN *Count + ) +{ + MARVELL_BOARD_DESC_PROTOCOL *BoardDescriptionProtocol; + MV_BOARD_PCIE_DESCRIPTION *BoardPcieDescription; + MV_PCIE_CONTROLLER *PcieController; + PCI_ROOT_BRIDGE *PciRootBridges; + PCI_ROOT_BRIDGE *RootBridge; + EFI_STATUS Status; + UINTN Index; + + *Count =3D 0; + + /* Obtain list of available controllers */ + Status =3D gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid, + NULL, + (VOID **)&BoardDescriptionProtocol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot locate BoardDesc protocol\n", + __FUNCTION__)); + return NULL; + } + + Status =3D BoardDescriptionProtocol->PcieDescriptionGet ( + BoardDescriptionProtocol, + &BoardPcieDescription); + if (Status =3D=3D EFI_NOT_FOUND) { + /* No controllers used on the platform, exit silently */ + return NULL; + } else if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot get Pcie board desc from BoardDesc protocol\n", + __FUNCTION__)); + return NULL; + } + + /* Assign return values */ + PciRootBridges =3D AllocateZeroPool (BoardPcieDescription->PcieControlle= rCount * + sizeof (PCI_ROOT_BRIDGE)); + if (PciRootBridges =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate resources\n", __FUNCTION__)= ); + return NULL; + } + + *Count =3D BoardPcieDescription->PcieControllerCount; + RootBridge =3D PciRootBridges; + + /* Fill information of all root bridge instances */ + for (Index =3D 0; Index < *Count; Index++, RootBridge++) { + + PcieController =3D &(BoardPcieDescription->PcieControllers[Index]); + + RootBridge->Segment =3D 0; + RootBridge->Supports =3D 0; + RootBridge->Attributes =3D RootBridge->Supports; + + RootBridge->DmaAbove4G =3D FALSE; + + RootBridge->AllocationAttributes =3D EFI_PCI_HOST_BRIDGE_COMBINE_MEM_= PMEM | + EFI_PCI_HOST_BRIDGE_MEM64_DECODE; + + RootBridge->Bus.Base =3D PcieController->PcieBusMin; + RootBridge->Bus.Limit =3D PcieController->PcieBusMax; + RootBridge->Io.Base =3D PcieController->PcieIoWinBase; + RootBridge->Io.Limit =3D PcieController->PcieIoWinBase + + PcieController->PcieIoWinSize - 1; + RootBridge->Mem.Base =3D PcieController->PcieMmio32WinBase; + RootBridge->Mem.Limit =3D PcieController->PcieMmio32WinBase + + PcieController->PcieMmio32WinSize - 1; + RootBridge->MemAbove4G.Base =3D PcieController->PcieMmio64WinBase; + RootBridge->MemAbove4G.Limit =3D PcieController->PcieMmio64WinBase + + PcieController->PcieMmio64WinSize - 1; + + /* No separate ranges for prefetchable and non-prefetchable BARs */ + RootBridge->PMem.Base =3D MAX_UINT64; + RootBridge->PMem.Limit =3D 0; + RootBridge->PMemAbove4G.Base =3D MAX_UINT64; + RootBridge->PMemAbove4G.Limit =3D 0; + + ASSERT (PcieController->PcieMmio64Translation =3D=3D 0); + ASSERT (PcieController->PcieMmio32Translation =3D=3D 0); + + RootBridge->NoExtendedConfigSpace =3D FALSE; + + RootBridge->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBri= dgeDevicePath; + } + + return PciRootBridges; +} + +/** + Free the root bridge instances array returned from PciHostBridgeGetRootB= ridges(). + + @param Bridges The root bridge instances array. + @param Count The count of the array. + +**/ +VOID +EFIAPI +PciHostBridgeFreeRootBridges ( + PCI_ROOT_BRIDGE *Bridges, + UINTN Count + ) +{ + FreePool (Bridges); +} + +/** + Inform the platform that the resource conflict happens. + + @param HostBridgeHandle Handle of the Host Bridge. + @param Configuration Pointer to PCI I/O and PCI memory resource + descriptors. The Configuration contains the reso= urces + for all the root bridges. The resource for each = root + bridge is terminated with END descriptor and an + additional END is appended indicating the end of= the + entire resources. The resource descriptor field + values follow the description in + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + .SubmitResources(). + +**/ +VOID +EFIAPI +PciHostBridgeResourceConflict ( + EFI_HANDLE HostBridgeHandle, + VOID *Configuration + ) +{ + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; + UINTN RootBridgeIndex; + + DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n")); + + RootBridgeIndex =3D 0; + Descriptor =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; + + while (Descriptor->Desc =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR) { + + DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); + + for (; Descriptor->Desc =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR; Descript= or++) { + ASSERT (Descriptor->ResType < + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) / + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0]))); + + DEBUG ((DEBUG_ERROR, + " %s: Length/Alignment =3D 0x%lx / 0x%lx\n", + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType], + Descriptor->AddrLen, Descriptor->AddrRangeMax)); + + if (Descriptor->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_MEM) { + DEBUG ((DEBUG_ERROR, + " Granularity/SpecificFlag =3D %ld / %02x%s\n", + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, + ((Descriptor->SpecificFlag & + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE)= !=3D 0) ? + L" (Prefetchable)" : L"")); + } + } + /* Skip the END descriptor for root bridge */ + ASSERT (Descriptor->Desc =3D=3D ACPI_END_TAG_DESCRIPTOR); + Descriptor =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)( + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1); + } +} diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/= PciHostBridgeLibConstructor.c b/Silicon/Marvell/Armada7k8k/Library/Armada7k= 8kPciHostBridgeLib/PciHostBridgeLibConstructor.c new file mode 100644 index 0000000..ced2c12 --- /dev/null +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHost= BridgeLibConstructor.c @@ -0,0 +1,330 @@ +/** @file + PCI Host Bridge Library instance for Marvell 70x0/80x0 + + Copyright (c) 2017, Linaro Ltd. All rights reserved.
+ Copyright (c) 2019 Marvell International Ltd. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include "PciHostBridgeLibConstructor.h" + +/** + This function configures PCIE controllers IATU windows. + + @param [in] PcieBaseAddress PCIE controller base address. + @param [in] Index IATU window index. + @param [in] CpuBase Address from the CPU perspective. + @param [in] PciBase Target PCIE address. + @param [in] Size IATU window size. + @param [in] Type IATU window type. + @param [in] EnableFlags Extra configuration flags. + + @retval none + +**/ +STATIC +VOID +ConfigureWindow ( + IN EFI_PHYSICAL_ADDRESS PcieBaseAddress, + IN UINTN Index, + IN UINT64 CpuBase, + IN UINT64 PciBase, + IN UINT64 Size, + IN UINTN Type, + IN UINTN EnableFlags + ) +{ + ArmDataMemoryBarrier (); + + MmioWrite32 (PcieBaseAddress + IATU_VIEWPORT_OFF, + IATU_VIEWPORT_OUTBOUND | IATU_VIEWPORT_REGION_INDEX (Index)); + + ArmDataMemoryBarrier (); + + MmioWrite32 (PcieBaseAddress + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0, + (UINT32)(CpuBase & 0xFFFFFFFF)); + MmioWrite32 (PcieBaseAddress + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0, + (UINT32)(CpuBase >> 32)); + MmioWrite32 (PcieBaseAddress + IATU_LIMIT_ADDR_OFF_OUTBOUND_0, + (UINT32)(CpuBase + Size - 1)); + MmioWrite32 (PcieBaseAddress + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, + (UINT32)(PciBase & 0xFFFFFFFF)); + MmioWrite32 (PcieBaseAddress + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0, + (UINT32)(PciBase >> 32)); + MmioWrite32 (PcieBaseAddress + IATU_REGION_CTRL_1_OFF_OUTBOUND_0, + Type); + MmioWrite32 (PcieBaseAddress + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN | EnableFlags); +} + +/** + Perform PCIE slot reset using external GPIO pin. + + @param [in] PcieBaseAddress PCIE controller base address. + + @retval none + +**/ +STATIC +VOID +WaitForLink ( + IN EFI_PHYSICAL_ADDRESS PcieBaseAddress + ) +{ + UINT32 Mask; + UINT32 Status; + UINT32 Timeout; + + if (!(MmioRead32 (PcieBaseAddress + PCIE_PM_STATUS) & PCIE_PM_LTSSM_STAT= _MASK)) { + DEBUG ((DEBUG_INIT, "%a: no PCIE device detected\n", __FUNCTION__)); + return; + } + + /* Wait for the link to establish itself */ + DEBUG ((DEBUG_INIT, "%a: waiting for PCIE link\n", __FUNCTION__)); + + Mask =3D PCIE_GLOBAL_STATUS_RDLH_LINK_UP | PCIE_GLOBAL_STATUS_PHY_LINK_U= P; + Timeout =3D PCIE_LINK_UP_TIMEOUT_US / 10; + do { + Status =3D MmioRead32 (PcieBaseAddress + PCIE_GLOBAL_STATUS_REG); + if ((Status & Mask) =3D=3D Mask) { + DEBUG ((DEBUG_ERROR, "pcie@0x%x link UP\n", PcieBaseAddress)); + break; + } + gBS->Stall (10); + } while (Timeout--); +} + +/** + Perform PCIE slot reset using external GPIO pin. + + @param [in] *PcieResetGpio GPIO pin description. + + @retval EFI_SUCEESS PCIE slot reset succeeded. + @retval Other Return error status. + +**/ +STATIC +EFI_STATUS +ResetPcieSlot ( + IN MV_GPIO_PIN *PcieResetGpio + ) +{ + EMBEDDED_GPIO_MODE Mode; + EMBEDDED_GPIO_PIN GpioPin; + EMBEDDED_GPIO *GpioProtocol; + EFI_STATUS Status; + + /* Get GPIO protocol */ + Status =3D MvGpioGetProtocol (PcieResetGpio->ControllerType, &GpioProtoc= ol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Unable to find GPIO protocol\n", __FUNCTION_= _)); + return Status; + } + + GpioPin =3D GPIO (PcieResetGpio->ControllerId, PcieResetGpio->PinNumber), + + /* Reset the slot by toggling the GPIO pin */ + Mode =3D PcieResetGpio->ActiveHigh ? GPIO_MODE_OUTPUT_1 : GPIO_MODE_OUTP= UT_0; + Status =3D GpioProtocol->Set (GpioProtocol, GpioPin, Mode); + gBS->Stall (10 * 1000); + + Mode =3D PcieResetGpio->ActiveHigh ? GPIO_MODE_OUTPUT_0 : GPIO_MODE_OUTP= UT_1; + Status =3D GpioProtocol->Set (GpioProtocol, GpioPin, Mode); + gBS->Stall (20 * 1000); + + return EFI_SUCCESS; +} + +/** + Obtain resources and perform a low-level PCIE controllers + configuration. + + @param [in] ImageHandle The image handle. + @param [in] *SystemTable The system table. + + @retval EFI_SUCEESS PCIE configuration successful. + @retval Other Return error status. + +**/ +EFI_STATUS +EFIAPI +Armada7k8kPciHostBridgeLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + MARVELL_BOARD_DESC_PROTOCOL *BoardDescriptionProtocol; + MV_BOARD_PCIE_DESCRIPTION *BoardPcieDescription; + MV_PCIE_CONTROLLER *PcieController; + EFI_PHYSICAL_ADDRESS PcieBaseAddress; + EFI_STATUS Status; + UINTN Index; + + /* Obtain list of available controllers */ + Status =3D gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid, + NULL, + (VOID **)&BoardDescriptionProtocol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot locate BoardDesc protocol\n", + __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + Status =3D BoardDescriptionProtocol->PcieDescriptionGet ( + BoardDescriptionProtocol, + &BoardPcieDescription); + if (Status =3D=3D EFI_NOT_FOUND) { + /* No controllers used on the platform, exit silently */ + return EFI_SUCCESS; + } else if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot get Pcie board desc from BoardDesc protocol\n", + __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + for (Index =3D 0; Index < BoardPcieDescription->PcieControllerCount; Ind= ex++) { + + PcieController =3D &(BoardPcieDescription->PcieControllers[Index]); + + ASSERT (PcieController->PcieBusMin =3D=3D 0); + ASSERT (PcieController->ConfigSpaceAddress % SIZE_256MB =3D=3D 0); + + if (PcieController->HaveResetGpio =3D=3D TRUE) { + /* Reset PCIE slot */ + Status =3D ResetPcieSlot (&PcieController->PcieResetGpio); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot reset Pcie Slot\n", + __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + } + + /* Low level PCIE controller configuration */ + PcieBaseAddress =3D PcieController->PcieBaseAddress; + + MmioAndThenOr32 (PcieBaseAddress + PORT_LINK_CTRL_OFF, + ~PORT_LINK_CTRL_OFF_LINK_CAPABLE_MASK, + PORT_LINK_CTRL_OFF_LINK_CAPABLE_x4); + + MmioAndThenOr32 (PcieBaseAddress + GEN2_CTRL_OFF, + ~GEN2_CTRL_OFF_NUM_OF_LANES_MASK, + GEN2_CTRL_OFF_NUM_OF_LANES(4) | GEN2_CTRL_OFF_DIRECT_SPEED_CHANGE); + + MmioAndThenOr32 (PcieBaseAddress + PCIE_GLOBAL_CTRL_OFFSET, + ~(PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK | PCIE_GLOBAL_APP_LTSSM_EN), + PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC); + + MmioWrite32 (PcieBaseAddress + PCIE_ARCACHE_TRC_REG, + ARCACHE_DEFAULT_VALUE); + + MmioWrite32 (PcieBaseAddress + PCIE_AWCACHE_TRC_REG, + AWCACHE_DEFAULT_VALUE); + + MmioAndThenOr32 (PcieBaseAddress + PCIE_ARUSER_REG, + ~AX_USER_DOMAIN_MASK, + AX_USER_DOMAIN_OUTER_SHAREABLE); + + MmioAndThenOr32 (PcieBaseAddress + PCIE_AWUSER_REG, + ~AX_USER_DOMAIN_MASK, + AX_USER_DOMAIN_OUTER_SHAREABLE); + + MmioAndThenOr32 (PcieBaseAddress + PCIE_LINK_CTL_2, + ~TARGET_LINK_SPEED_MASK, + LINK_SPEED_GEN_3); + + MmioAndThenOr32 (PcieBaseAddress + PCIE_LINK_CAPABILITY, + ~TARGET_LINK_SPEED_MASK, + LINK_SPEED_GEN_3); + + MmioOr32 (PcieBaseAddress + PCIE_GEN3_EQU_CTRL, + GEN3_EQU_EVAL_2MS_DISABLE); + + MmioOr32 (PcieBaseAddress + PCIE_GLOBAL_CTRL_OFFSET, + PCIE_GLOBAL_APP_LTSSM_EN); + + /* Region 0: MMIO32 range */ + ConfigureWindow (PcieBaseAddress, + 0, + PcieController->PcieMmio32WinBase, + PcieController->PcieMmio32WinBase, + PcieController->PcieMmio32WinSize, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, + 0); + + /* Region 1: Type 0 config space */ + ConfigureWindow (PcieBaseAddress, + 1, + PcieController->ConfigSpaceAddress, + 0x0, + SIZE_64KB, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0, + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_CFG_SHIFT_MODE); + + /* Region 2: Type 1 config space */ + ConfigureWindow (PcieBaseAddress, + 2, + PcieController->ConfigSpaceAddress + SIZE_64KB, + 0x0, + PcieController->PcieBusMax * SIZE_1MB, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1, + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_CFG_SHIFT_MODE); + + /* Region 3: port I/O range */ + ConfigureWindow (PcieBaseAddress, + 3, + PcieController->PcieIoTranslation, + PcieController->PcieIoWinBase, + PcieController->PcieIoWinSize, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO, + 0); + + /* Region 4: MMIO64 range */ + ConfigureWindow (PcieBaseAddress, + 4, + PcieController->PcieMmio64WinBase, + PcieController->PcieMmio64WinBase, + PcieController->PcieMmio64WinSize, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, + 0); + + MmioOr32 (PcieBaseAddress + PCIE_GLOBAL_INT_MASK1_REG, + PCIE_INT_A_ASSERT_MASK | + PCIE_INT_B_ASSERT_MASK | + PCIE_INT_C_ASSERT_MASK | + PCIE_INT_D_ASSERT_MASK); + + WaitForLink (PcieBaseAddress); + + /* Enable the RC */ + MmioOr32 (PcieBaseAddress + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_IO_SPACE | + EFI_PCI_COMMAND_MEMORY_SPACE | + EFI_PCI_COMMAND_BUS_MASTER); + } + + return EFI_SUCCESS; +} --=20 2.7.4 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#40321): https://edk2.groups.io/g/devel/message/40321 Mute This Topic: https://groups.io/mt/31553480/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-