public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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
> 


  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