public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: edk2-devel@lists.01.org, leif.lindholm@linaro.org
Cc: daniel.thompson@linaro.org, masami.hiramatsu@linaro.org
Subject: [PATCH edk2-platforms v2 06/23] Silicon/SynQuacer: implement PciHostBridgeLib support
Date: Wed, 25 Oct 2017 18:59:30 +0100	[thread overview]
Message-ID: <20171025175947.22798-7-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <20171025175947.22798-1-ard.biesheuvel@linaro.org>

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            | 220 +++++++++++
 Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf          |  50 +++
 Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c | 388 ++++++++++++++++++++
 3 files changed, 658 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..3937e98c0213
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.c
@@ -0,0 +1,220 @@
+/** @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/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#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)
+        }
+      },
+      EISA_PNP_ID (0x0A08), // PCI Express
+      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)
+        }
+      },
+      EISA_PNP_ID (0x0A08), // PCI Express
+      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 <
+              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr));
+      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..fca62b2577da
--- /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
+#
+
+[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..3c6eff602f74
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
@@ -0,0 +1,388 @@
+/** @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);
+}
+
+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;
+    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  EFI_PHYSICAL_ADDRESS    IoMemBase,
+  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,
+    IoMemBase,
+    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;
+  EFI_PHYSICAL_ADDRESS      IoMemBase;
+} mBaseAddresses [] = {
+  {
+    SYNQUACER_PCI_SEG0_DBI_BASE,
+    SYNQUACER_PCI_SEG0_EXS_BASE,
+    SYNQUACER_PCI_SEG0_CONFIG_BASE,
+    SYNQUACER_PCI_SEG0_PORTIO_MEMBASE
+  },
+  {
+    SYNQUACER_PCI_SEG1_DBI_BASE,
+    SYNQUACER_PCI_SEG1_EXS_BASE,
+    SYNQUACER_PCI_SEG1_CONFIG_BASE,
+    SYNQUACER_PCI_SEG1_PORTIO_MEMBASE
+  },
+};
+
+
+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,
+                       mBaseAddresses[Idx].IoMemBase,
+                       &RootBridges[Idx]);
+  }
+
+  return EFI_SUCCESS;
+}
+
-- 
2.11.0



  parent reply	other threads:[~2017-10-25 17:56 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-25 17:59 [PATCH edk2-platforms v2 00/23] add support for Socionext Synquacer Ard Biesheuvel
2017-10-25 17:59 ` [PATCH edk2-platforms v2 01/23] Silicon/SynQuacer: add package with platform headers Ard Biesheuvel
2017-10-26 14:39   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 02/23] Silicon/Socionext: add driver for NETSEC network controller Ard Biesheuvel
2017-10-26 14:49   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 03/23] Silicon/SynQuacer: add MemoryInitPeiLib implementation Ard Biesheuvel
2017-10-26 14:56   ` Leif Lindholm
2017-10-26 14:57     ` Ard Biesheuvel
2017-10-26 15:05       ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 04/23] Platform: add support for Socionext SynQuacer eval board Ard Biesheuvel
2017-10-26 15:02   ` Leif Lindholm
2017-10-26 15:14     ` Ard Biesheuvel
2017-10-25 17:59 ` [PATCH edk2-platforms v2 05/23] Silicon/SynQuacer: implement PciSegmentLib to support dual RCs Ard Biesheuvel
2017-10-26 15:06   ` Leif Lindholm
2017-10-25 17:59 ` Ard Biesheuvel [this message]
2017-10-26 15:10   ` [PATCH edk2-platforms v2 06/23] Silicon/SynQuacer: implement PciHostBridgeLib support Leif Lindholm
2017-10-26 15:12     ` Ard Biesheuvel
2017-10-25 17:59 ` [PATCH edk2-platforms v2 07/23] Silicon/SynQuacer: implement EFI_CPU_IO2_PROTOCOL Ard Biesheuvel
2017-10-26 15:13   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 08/23] Platform/SynQuacerEvalBoard: add PCI support Ard Biesheuvel
2017-10-26 15:38   ` Leif Lindholm
2017-10-26 15:41     ` Ard Biesheuvel
2017-10-26 21:49       ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 09/23] Platform/SynQuacerEvalBoard: add NETSEC driver Ard Biesheuvel
2017-10-26 15:39   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 10/23] Silicon/SynQuacer: add ACPI support Ard Biesheuvel
2017-10-26 17:13   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 11/23] Silicon/SynQuacer: add device tree support for eval board Ard Biesheuvel
2017-10-26 17:15   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 12/23] Silicon/SynQuacer: add NorFlashPlatformLib implementation Ard Biesheuvel
2017-10-25 17:59 ` [PATCH edk2-platforms v2 13/23] Silicon/Socionext: add driver for SPI NOR flash Ard Biesheuvel
2017-10-26 21:19   ` Leif Lindholm
2017-10-28 14:16     ` Ard Biesheuvel
2017-10-28 21:31       ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 14/23] Platform/SynQuacer: incorporate NOR flash and variable drivers Ard Biesheuvel
2017-10-25 17:59 ` [PATCH edk2-platforms v2 15/23] Silicon/SynQuacer: implement PlatformFlashAccessLib Ard Biesheuvel
2017-10-26 21:22   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 16/23] SynQuacer/SynQuacerMemoryInitPeiLib: add capsule support Ard Biesheuvel
2017-10-26 21:27   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 17/23] Socionext/SynQuacerEvalBoard: wire up basic " Ard Biesheuvel
2017-10-26 21:28   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 18/23] Socionext/SynQuacerEvalBoard: switch to execute in place Ard Biesheuvel
2017-10-26 21:30   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 19/23] Platform/SynQuacerEvalBoard: add signed capsule update support Ard Biesheuvel
2017-10-26 21:33   ` Leif Lindholm
2017-10-28 13:48     ` Ard Biesheuvel
2017-10-25 17:59 ` [PATCH edk2-platforms v2 20/23] Silicon/SynQuacer/AcpiTables: hide PCI domain #0 Ard Biesheuvel
2017-10-26 21:34   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 21/23] Silicon/SynQuacerPciHostBridgeLib: add workaround to support 32-bit only cards Ard Biesheuvel
2017-10-26 21:35   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 22/23] Platform/Socionext: add support for Socionext Developer Box rev 0.1 Ard Biesheuvel
2017-10-26 21:46   ` Leif Lindholm
2017-10-25 17:59 ` [PATCH edk2-platforms v2 23/23] Platform/DeveloperBox: add ConsolePrefDxe driver Ard Biesheuvel
2017-10-26 21:46   ` 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=20171025175947.22798-7-ard.biesheuvel@linaro.org \
    --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