From: Leif Lindholm <leif.lindholm@linaro.org>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: edk2-devel@lists.01.org, methavanitpong.pipat@socionext.com,
masahisa.kojima@linaro.org, masami.hiramatsu@linaro.org
Subject: Re: [PATCH edk2-platforms 05/14] Silicon/Synquacer: implement PciHostBridgeLib support
Date: Mon, 11 Sep 2017 15:22:08 +0100 [thread overview]
Message-ID: <20170911142208.h2ndb7od4tkjvu32@bivouac.eciton.net> (raw)
In-Reply-To: <20170908182315.9591-6-ard.biesheuvel@linaro.org>
On Fri, Sep 08, 2017 at 07:23:06PM +0100, Ard Biesheuvel wrote:
> Implement the glue library that exposes the PCIe root complexes to
> the generic PCI host bridge driver. Since that driver is the first
> one to access the PCI config space, put the low level init code for
> the RCs into this library's constructor.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c | 223 ++++++++++++
> Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf | 50 +++
> Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c | 383 ++++++++++++++++++++
> 3 files changed, 656 insertions(+)
>
> diff --git a/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c
> new file mode 100644
> index 000000000000..10ddaac3b924
> --- /dev/null
> +++ b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c
> @@ -0,0 +1,223 @@
> +/** @file
> + PCI Host Bridge Library instance for Socionext Synquacer ARM SOC
> +
> + Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
> +
> + This program and the accompanying materials are licensed and made available
> + 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.
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Platform/Pcie.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
The above is well enough sorted that I'd let it slip, but it isn't
flawless.
> +
> +#pragma pack(1)
> +typedef struct {
> + ACPI_HID_DEVICE_PATH AcpiDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
> +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +#pragma pack ()
> +
> +STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[] = {
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
> + (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
Shift the spaces after (UINT8) to after sizeof?
> + }
> + },
> + EISA_PNP_ID(0x0A08), // PCI Express
Space before (?
Why don't we have that 0x0a08 in a central header?
> + 0
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + },
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
> + (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
Shift the spaces after (UINT8) to after sizeof?
> + }
> + },
> + EISA_PNP_ID(0x0A08), // PCI Express
Same as above.
> + 1
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
> + L"Mem", L"I/O", L"Bus"
> +};
> +
> +STATIC PCI_ROOT_BRIDGE mPciRootBridges[] = {
> + {
> + 0, // Segment
> + 0, // Supports
> + 0, // Attributes
> + TRUE, // DmaAbove4G
> + FALSE, // NoExtendedConfigSpace
> + FALSE, // ResourceAssigned
> + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
> + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, // AllocationAttributes
> + { SYNQUACER_PCI_SEG0_BUSNUM_MIN,
> + SYNQUACER_PCI_SEG0_BUSNUM_MAX }, // Bus
> + { SYNQUACER_PCI_SEG0_PORTIO_MIN,
> + SYNQUACER_PCI_SEG0_PORTIO_MAX }, // Io
> + { SYNQUACER_PCI_SEG0_MMIO32_MIN,
> + SYNQUACER_PCI_SEG0_MMIO32_MAX }, // Mem
> + { SYNQUACER_PCI_SEG0_MMIO64_MIN,
> + SYNQUACER_PCI_SEG0_MMIO64_MAX }, // MemAbove4G
> + { MAX_UINT64, 0x0 }, // PMem
> + { MAX_UINT64, 0x0 }, // PMemAbove4G
> + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[0]
> + }, {
> + 1, // Segment
> + 0, // Supports
> + 0, // Attributes
> + TRUE, // DmaAbove4G
> + FALSE, // NoExtendedConfigSpace
> + FALSE, // ResourceAssigned
> + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
> + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, // AllocationAttributes
> + { SYNQUACER_PCI_SEG1_BUSNUM_MIN,
> + SYNQUACER_PCI_SEG1_BUSNUM_MAX }, // Bus
> + { SYNQUACER_PCI_SEG1_PORTIO_MIN,
> + SYNQUACER_PCI_SEG1_PORTIO_MAX }, // Io
> + { SYNQUACER_PCI_SEG1_MMIO32_MIN,
> + SYNQUACER_PCI_SEG1_MMIO32_MAX }, // Mem
> + { SYNQUACER_PCI_SEG1_MMIO64_MIN,
> + SYNQUACER_PCI_SEG1_MMIO64_MAX }, // MemAbove4G
> + { MAX_UINT64, 0x0 }, // PMem
> + { MAX_UINT64, 0x0 }, // PMemAbove4G
> + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[1]
> + }
> +};
> +
> +/**
> + 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 (
> + OUT UINTN *Count
> + )
> +{
> + *Count = ARRAY_SIZE (mPciRootBridges);
> +
> + return mPciRootBridges;
> +}
> +
> +/**
> + Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
> +
> + @param Bridges The root bridge instances array.
> + @param Count The count of the array.
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeRootBridges (
> + PCI_ROOT_BRIDGE *Bridges,
> + UINTN Count
> + )
> +{
> +}
> +
> +/**
> + 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 resources
> + 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 = 0;
> + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
> + while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> + DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
> + for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
> + ASSERT (Descriptor->ResType <
> + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
> + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
> + )
> + );
Replace with ARRAY_SIZE?
> + DEBUG ((DEBUG_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
> + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
> + Descriptor->AddrLen, Descriptor->AddrRangeMax
> + ));
> + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
> + DEBUG ((DEBUG_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
> + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
> + ((Descriptor->SpecificFlag &
> + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
> + ) != 0) ? L" (Prefetchable)" : L""
> + ));
> + }
> + }
> + //
> + // Skip the END descriptor for root bridge
> + //
> + ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
> + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
> + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
> + );
> + }
> +}
> diff --git a/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf
> new file mode 100644
> index 000000000000..cfa9b2fc1c07
> --- /dev/null
> +++ b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf
> @@ -0,0 +1,50 @@
> +## @file
> +# PCI Host Bridge Library instance for Socionext Synquacer ARM SOC
> +#
> +# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
> +#
> +# This program and the accompanying materials are licensed and made available
> +# 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 = 0x00010019
> + BASE_NAME = SynquacerPciHostBridgeLib
> + FILE_GUID = fdc92446-65bc-4f86-b4a0-014a2119a732
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PciHostBridgeLib|DXE_DRIVER
> + CONSTRUCTOR = SynquacerPciHostBridgeLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the build
> +# tools.
> +#
> +# VALID_ARCHITECTURES = AARCH64
Do we only have AArch64 support for this specific component?
> +#
> +
> +[Sources]
> + SynquacerPciHostBridgeLib.c
> + SynquacerPciHostBridgeLibConstructor.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + Silicon/Socionext/Synquacer/Synquacer.dec
> +
> +[LibraryClasses]
> + ArmLib
> + DebugLib
> + DevicePathLib
> + MemoryAllocationLib
> +
> +[FixedPcd]
> + gArmTokenSpaceGuid.PcdPciIoTranslation
> diff --git a/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c
> new file mode 100644
> index 000000000000..b3acca32070f
> --- /dev/null
> +++ b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c
> @@ -0,0 +1,383 @@
> +/** @file
> + PCI Host Bridge Library instance for Socionext Synquacer ARM SOC
> +
> + Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
> +
> + This program and the accompanying materials are licensed and made available
> + 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.
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/ArmLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Platform/Pcie.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 CORE_CONTROL 0x000
> +#define APP_LTSSM_ENABLE BIT4
> +#define DEVICE_TYPE (BIT3 | BIT2 | BIT1 | BIT0)
> +
> +#define AXI_CLK_STOP 0x004
> +#define DBI_ACLK_STOP BIT8
> +#define SLV_ACLK_STOP BIT4
> +#define MSTR_ACLK_STOP BIT0
> +#define DBI_CSYSREQ_REG BIT9
> +#define SLV_CSYSREQ_REG BIT5
> +#define MSTR_CSYSREQ_REG BIT1
> +
> +#define RESET_CONTROL_1 0x00C
> +#define PERST_N_O_REG BIT5
> +#define PERST_N_I_REG BIT4
> +#define BUTTON_RST_N_REG BIT1
> +#define PWUP_RST_N_REG BIT0
> +
> +#define RESET_CONTROL_2 0x010
> +
> +#define RESET_SELECT_1 0x014
> +#define SQU_RST_SEL BIT29
> +#define PHY_RST_SEL BIT28
> +#define PWR_RST_SEL BIT24
> +#define STI_RST_SEL BIT20
> +#define N_STI_RST_SEL BIT16
> +#define CORE_RST_SEL BIT12
> +#define PERST_SEL BIT4
> +#define BUTTON_RST_SEL BIT1
> +#define PWUP_RST_SEL BIT0
> +
> +#define RESET_SELECT_2 0x018
> +#define DBI_ARST_SEL BIT8
> +#define SLV_ARST_SEL BIT4
> +#define MSTR_ARST_SEL BIT0
> +
> +#define EM_CONTROL 0x030
> +#define PRE_DET_STT_REG BIT4
> +
> +#define EM_SELECT 0x034
> +#define PRE_DET_STT_SEL BIT4
> +
> +#define PM_CONTROL_2 0x050
> +#define SYS_AUX_PWR_DET BIT8
> +
> +#define PHY_CONFIG_COM_6 0x114
> +#define PIPE_PORT_SEL (BIT1 | BIT0)
> +
> +#define LINK_MONITOR 0x210
> +#define SMLH_LINK_UP BIT0
> +
> +#define LINK_CAPABILITIES_REG 0x07C
> +#define PCIE_CAP_MAX_LINK_WIDTH (BIT7 | BIT6 | BIT5 | BIT4)
> +#define PCIE_CAP_MAX_LINK_SPEED (BIT3 | BIT2 | BIT1 | BIT0)
> +
> +#define LINK_CONTROL_LINK_STATUS_REG 0x080
> +#define PCIE_CAP_NEGO_LINK_WIDTH (BIT23 | BIT22 | BIT21 | BIT20)
> +#define PCIE_CAP_LINK_SPEED (BIT19 | BIT18 | BIT17 | BIT16)
> +
> +#define TYPE1_CLASS_CODE_REV_ID_REG 0x008
> +#define BASE_CLASS_CODE 0xFF000000
> +#define BASE_CLASS_CODE_VALUE 0x06
> +#define SUBCLASS_CODE 0x00FF0000
> +#define SUBCLASS_CODE_VALUE 0x04
> +#define PROGRAM_INTERFACE 0x0000FF00
> +#define PROGRAM_INTERFACE_VALUE 0x00
> +
> +#define MISC_CONTROL_1_OFF 0x8BC
> +#define DBI_RO_WR_EN BIT0
> +
> +STATIC
> +VOID
> +ConfigureWindow (
> + IN EFI_PHYSICAL_ADDRESS DbiBase,
> + IN UINTN Index,
> + IN UINT64 CpuBase,
> + IN UINT64 PciBase,
> + IN UINT64 Size,
> + IN UINTN Type,
> + IN UINTN EnableFlags
> + )
> +{
> + ArmDataMemoryBarrier ();
> +
> + MmioWrite32 (DbiBase + IATU_VIEWPORT_OFF,
> + IATU_VIEWPORT_OUTBOUND | IATU_VIEWPORT_REGION_INDEX (Index));
> +
> + ArmDataMemoryBarrier ();
> +
> + MmioWrite32 (DbiBase + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(CpuBase & 0xFFFFFFFF));
> + MmioWrite32 (DbiBase + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(CpuBase >> 32));
> + MmioWrite32 (DbiBase + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(CpuBase + Size - 1));
> + MmioWrite32 (DbiBase + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(PciBase & 0xFFFFFFFF));
> + MmioWrite32 (DbiBase + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(PciBase >> 32));
> + MmioWrite32 (DbiBase + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> + Type);
> + MmioWrite32 (DbiBase + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN | EnableFlags);
No barrier needed here?
> +}
> +
> +STATIC
> +VOID
> +SnPcieSetData (
> + EFI_PHYSICAL_ADDRESS Base,
> + UINT32 Offset,
> + UINT32 Mask,
> + UINT32 In
> + )
> +{
> + UINT32 Data;
> + UINT32 Shift;
> +
> + Shift = 1;
> + if (In) {
> + while (!(Mask & Shift))
{
> + Shift <<= 1;
}
/
Leif
> + Data = (MmioRead32 (Base + Offset) & ~Mask) | (In * Shift);
> + } else {
> + Data = MmioRead32 (Base + Offset) & ~Mask;
> + }
> +
> + MmioWrite32 (Base + Offset, Data);
> +}
> +
> +STATIC
> +UINT32
> +SnPcieReadData (
> + EFI_PHYSICAL_ADDRESS Base,
> + UINT32 Offset,
> + UINT32 Mask
> + )
> +{
> + UINT32 Shift;
> +
> + Shift = 0;
> + while (!(Mask & 1)) {
> + Mask >>= 1;
> + Shift++;
> + }
> +
> + return (MmioRead32 (Base + Offset) >> Shift) & Mask;
> +}
> +
> +STATIC
> +VOID
> +SnDbiRoWrEn (
> + IN EFI_PHYSICAL_ADDRESS DbiBase,
> + IN INTN MaxLinkWidth,
> + IN INTN MaxLinkSpeed
> + )
> +{
> + SnPcieSetData (DbiBase, MISC_CONTROL_1_OFF, DBI_RO_WR_EN, 1);
> +
> + SnPcieSetData (DbiBase, LINK_CAPABILITIES_REG, PCIE_CAP_MAX_LINK_WIDTH, MaxLinkWidth);
> + SnPcieSetData (DbiBase, LINK_CAPABILITIES_REG, PCIE_CAP_MAX_LINK_SPEED, MaxLinkSpeed);
> +
> + SnPcieSetData (DbiBase, TYPE1_CLASS_CODE_REV_ID_REG, BASE_CLASS_CODE, BASE_CLASS_CODE_VALUE);
> + SnPcieSetData (DbiBase, TYPE1_CLASS_CODE_REV_ID_REG, SUBCLASS_CODE, SUBCLASS_CODE_VALUE);
> + SnPcieSetData (DbiBase, TYPE1_CLASS_CODE_REV_ID_REG, PROGRAM_INTERFACE, PROGRAM_INTERFACE_VALUE);
> +
> + SnPcieSetData (DbiBase, MISC_CONTROL_1_OFF, DBI_RO_WR_EN, 0);
> +}
> +
> +STATIC
> +VOID
> +PciInitController (
> + IN EFI_PHYSICAL_ADDRESS ExsBase,
> + IN EFI_PHYSICAL_ADDRESS DbiBase,
> + IN EFI_PHYSICAL_ADDRESS ConfigBase,
> + IN CONST PCI_ROOT_BRIDGE *RootBridge
> + )
> +{
> + SnPcieSetData (ExsBase, EM_SELECT, PRE_DET_STT_SEL, 0);
> + SnPcieSetData (ExsBase, EM_CONTROL, PRE_DET_STT_REG, 0);
> + SnPcieSetData (ExsBase, EM_CONTROL, PRE_DET_STT_REG, 1);
> +
> + // 1: Assert all PHY / LINK resets
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , PERST_SEL , 0);
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_I_REG , 0);
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_O_REG , 0);
> +
> + // Device Reset(PERST#) is effective afrer Set device_type (RC)
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , PWUP_RST_SEL , 0);
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, PWUP_RST_N_REG, 0);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , BUTTON_RST_SEL , 0);
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, BUTTON_RST_N_REG, 0);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , PWR_RST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_2 , MSTR_ARST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_2 , SLV_ARST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_2 , DBI_ARST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , CORE_RST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , STI_RST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , N_STI_RST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , SQU_RST_SEL , 1);
> + SnPcieSetData (ExsBase, RESET_SELECT_1 , PHY_RST_SEL , 1);
> +
> + // 2: Set P<n>_app_ltssm_enable='0' for reprogramming before linkup.
> + SnPcieSetData (ExsBase, CORE_CONTROL, APP_LTSSM_ENABLE, 0);
> +
> + // 3: Set device_type (RC)
> + SnPcieSetData (ExsBase, CORE_CONTROL, DEVICE_TYPE, 4);
> +
> + // 4: Set Bifurcation 1=disable 4=able
> + // 5: Supply Reference (It has executed)
> + // 6: Wait for 10usec (Reference Clocks is stable)
> + // 7 De assert PERST# */
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_I_REG, 1);
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_O_REG, 1);
> +
> + // 8 Assert SYS_AUX_PWR_DET
> + SnPcieSetData(ExsBase, PM_CONTROL_2, SYS_AUX_PWR_DET, 1);
> +
> + // 9 Supply following clocks
> + SnPcieSetData (ExsBase, AXI_CLK_STOP, MSTR_CSYSREQ_REG, 1);
> + SnPcieSetData (ExsBase, AXI_CLK_STOP, MSTR_ACLK_STOP, 0);
> + SnPcieSetData (ExsBase, AXI_CLK_STOP, SLV_CSYSREQ_REG, 1);
> + SnPcieSetData (ExsBase, AXI_CLK_STOP, SLV_ACLK_STOP, 0);
> + SnPcieSetData (ExsBase, AXI_CLK_STOP, DBI_CSYSREQ_REG, 1);
> + SnPcieSetData (ExsBase, AXI_CLK_STOP, DBI_ACLK_STOP, 0);
> +
> + // 10 De assert PHY reset
> + // 11 De assert LINK's PMC reset
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, PWUP_RST_N_REG, 1);
> + SnPcieSetData (ExsBase, RESET_CONTROL_1, BUTTON_RST_N_REG, 1);
> + // 12 PHY auto
> + // 13 Wrapper auto
> + // 14-17 PHY auto
> + // 18 Wrapper auto
> + // 19 Update registers through DBI AXI Slave interface
> + SnDbiRoWrEn (DbiBase, 4 /* lanes */, /* Gen */ 2);
> +
> + //
> + // ECAM shift mode uses bits [27:12] of the untranslated address as
> + // B/D/F identifiers. This only works as expected if the base of the
> + // region is aligned to 256 MB, or the effective bus numbers will be
> + // out of sync with the bus base and limit values we chose.
> + //
> + ASSERT ((ConfigBase % SIZE_256MB) == RootBridge->Bus.Base * SIZE_1MB);
> +
> + MmioOr32 (DbiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_IO_SPACE |
> + EFI_PCI_COMMAND_MEMORY_SPACE |
> + EFI_PCI_COMMAND_BUS_MASTER);
> +
> + // Region 0: MMIO32 range
> + ConfigureWindow (DbiBase, 0,
> + RootBridge->Mem.Base,
> + RootBridge->Mem.Base,
> + RootBridge->Mem.Limit - RootBridge->Mem.Base + 1,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + 0);
> +
> + // Region 1: Type 0 config space
> + ConfigureWindow (DbiBase, 1,
> + ConfigBase + RootBridge->Bus.Base * SIZE_1MB,
> + 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 (DbiBase, 2,
> + ConfigBase + RootBridge->Bus.Base * SIZE_1MB + SIZE_64KB,
> + 0x0,
> + (RootBridge->Bus.Limit - RootBridge->Bus.Base + 1) * SIZE_1MB - SIZE_64KB,
> + 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 (DbiBase, 3,
> + FixedPcdGet32 (PcdPciIoTranslation) + RootBridge->Io.Base,
> + RootBridge->Io.Base,
> + RootBridge->Io.Limit - RootBridge->Io.Base + 1,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO,
> + 0);
> +
> + // Region 4: MMIO64 range
> + ConfigureWindow (DbiBase, 4,
> + RootBridge->MemAbove4G.Base,
> + RootBridge->MemAbove4G.Base,
> + RootBridge->MemAbove4G.Limit - RootBridge->MemAbove4G.Base + 1,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + 0);
> +
> + // enable link
> + if (SnPcieReadData (ExsBase, CORE_CONTROL, APP_LTSSM_ENABLE) == 0) {
> + SnPcieSetData (ExsBase, CORE_CONTROL, APP_LTSSM_ENABLE, 1);
> + }
> +}
> +
> +STATIC CONST struct {
> + EFI_PHYSICAL_ADDRESS DbiBase;
> + EFI_PHYSICAL_ADDRESS ExsBase;
> + EFI_PHYSICAL_ADDRESS ConfigBase;
> +} mBaseAddresses [] = {
> + {
> + SYNQUACER_PCI_SEG0_DBI_BASE,
> + SYNQUACER_PCI_SEG0_EXS_BASE,
> + SYNQUACER_PCI_SEG0_CONFIG_BASE
> + },
> + {
> + SYNQUACER_PCI_SEG1_DBI_BASE,
> + SYNQUACER_PCI_SEG1_EXS_BASE,
> + SYNQUACER_PCI_SEG1_CONFIG_BASE
> + },
> +};
> +
> +
> +EFI_STATUS
> +EFIAPI
> +SynquacerPciHostBridgeLibConstructor (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + PCI_ROOT_BRIDGE *RootBridges;
> + UINTN Count;
> + UINTN Idx;
> +
> + RootBridges = PciHostBridgeGetRootBridges (&Count);
> + ASSERT (Count == ARRAY_SIZE(mBaseAddresses));
> + if (Count != ARRAY_SIZE(mBaseAddresses)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + for (Idx = 0; Idx < Count; Idx++) {
> + PciInitController (mBaseAddresses[Idx].ExsBase,
> + mBaseAddresses[Idx].DbiBase,
> + mBaseAddresses[Idx].ConfigBase,
> + &RootBridges[Idx]);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> --
> 2.11.0
>
next prev parent reply other threads:[~2017-09-11 14:19 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-08 18:23 [PATCH edk2-platforms 00/14] add support for Socionext Synquacer EVB Ard Biesheuvel
2017-09-08 18:23 ` [PATCH edk2-platforms 01/14] Silicon/Synquacer: add package with platform headers Ard Biesheuvel
2017-09-11 13:31 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 02/14] Silicon/Synquacer: add MemoryInitPeiLib implementation Ard Biesheuvel
2017-09-11 13:36 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 03/14] Platform: add support for Socionext Synquacer eval board Ard Biesheuvel
2017-09-11 13:54 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 04/14] Silicon/Synquacer: implement PciSegmentLib to support dual RCs Ard Biesheuvel
2017-09-11 14:03 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 05/14] Silicon/Synquacer: implement PciHostBridgeLib support Ard Biesheuvel
2017-09-11 14:22 ` Leif Lindholm [this message]
2017-09-08 18:23 ` [PATCH edk2-platforms 06/14] Silicon/Synquacer: implement EFI_CPU_IO2_PROTOCOL Ard Biesheuvel
2017-09-11 14:45 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 07/14] Platform/SynquacerEvalBoard: add PCI support Ard Biesheuvel
2017-09-11 14:48 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 08/14] Silicon/Socionext: add driver for NETSEC network controller Ard Biesheuvel
2017-09-11 16:12 ` Leif Lindholm
2017-10-28 13:06 ` Ard Biesheuvel
2017-10-28 21:25 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 09/14] Platform/SynquacerEvalBoard: add NETSEC driver Ard Biesheuvel
2017-09-11 16:23 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 10/14] Silicon/Synquacer: add ACPI support Ard Biesheuvel
2017-09-11 16:33 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 11/14] Silicon/Synquacer: add device tree support for eval board Ard Biesheuvel
2017-09-11 16:37 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 12/14] Silicon/Synquacer: add NorFlashPlatformLib implementation Ard Biesheuvel
2017-09-11 16:38 ` Leif Lindholm
2017-09-08 18:23 ` [PATCH edk2-platforms 13/14] Silicon/Socionext: add driver for SPI NOR flash Ard Biesheuvel
2017-09-11 19:13 ` Leif Lindholm
[not found] ` <e55ff6c595f74189bd53787f3b6b2283@SOC-EX03V.e01.socionext.com>
2017-09-12 8:38 ` Leif Lindholm
2017-09-12 10:48 ` methavanitpong.pipat
2017-09-08 18:23 ` [PATCH edk2-platforms 14/14] Platform/Synquacer: incorporate NOR flash and variable drivers Ard Biesheuvel
2017-09-11 19:13 ` Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170911142208.h2ndb7od4tkjvu32@bivouac.eciton.net \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox