public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH edk2-platforms v2 00/16] Add PCIe Support
@ 2020-05-26  8:37 Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Add PCIe Support for NXP Layerscape SoC which supports
different PCIe controllers.
Use generic PCIe drivers and wire up PciHostBridgeLib,
PciSegmentLib and PciCpuIo2Dxe driver for controller
specific implementation.

V1 Series can be referred here:
https://edk2.groups.io/g/devel/message/60116?p=,,,20,0,0,0::relevance,,PCIe+Support,20,2,0,74395799


Changes in V2:
- Addressed review comments received on V1.

Meenakshi Aggarwal (1):
  Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg

Wasim Khan (15):
  Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
  Silicon/NXP: LS1043A: Define PCIe related PCDs
  Silicon/NXP: Implement PciHostBridgeLib support
  Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS
    Ctrl
  Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU
    Windows
  Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
  Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
  Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
  Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
  Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS
    Controller
  Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
  Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
  Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
  Platform/NXP: LS1043aRdbPkg: Enable PCIE support
  Platform/NXP: LS1043aRdbPkg : Increase fv image size

 Silicon/NXP/NxpQoriqLs.dec                                |  12 +
 Silicon/NXP/LS1043A/LS1043A.dsc.inc                       |   7 +
 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc              |  20 +
 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf              |  20 +-
 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf         |  40 +
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf |  43 +
 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf       |  36 +
 Silicon/NXP/Include/Pcie.h                                | 228 ++++++
 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c           | 628 +++++++++++++++
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 830 ++++++++++++++++++++
 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c         | 699 +++++++++++++++++
 11 files changed, 2560 insertions(+), 3 deletions(-)
 create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
 create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
 create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
 create mode 100755 Silicon/NXP/Include/Pcie.h
 create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
 create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
 create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 02/16] Silicon/NXP: LS1043A: Define " Wasim Khan
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Add PCIe related PCDs.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Droped PcdPciDebug

 Silicon/NXP/NxpQoriqLs.dec | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 0722f59ef4f6..9ff5ce8a1c6e 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -27,3 +27,11 @@ [Guids.common]
 [PcdsFeatureFlag]
   gNxpQoriqLsTokenSpaceGuid.PcdI2cErratumA009203|FALSE|BOOLEAN|0x00000315
   gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|FALSE|BOOLEAN|0x00000316
+  gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x00000317
+
+[PcdsFixedAtBuild.common]
+  # Pcds for PCI Express
+  gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x0|UINT64|0x00000500
+  gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|0|UINT32|0x00000501
+  gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
+  gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 02/16] Silicon/NXP: LS1043A: Define PCIe related PCDs
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Define PCIe related PCDs for LS1043A.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Dropped PcdPciDebug

 Silicon/NXP/LS1043A/LS1043A.dsc.inc | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Silicon/NXP/LS1043A/LS1043A.dsc.inc b/Silicon/NXP/LS1043A/LS1043A.dsc.inc
index 67f5ba68dcd5..e023bfbc7c04 100644
--- a/Silicon/NXP/LS1043A/LS1043A.dsc.inc
+++ b/Silicon/NXP/LS1043A/LS1043A.dsc.inc
@@ -30,4 +30,11 @@ [PcdsFixedAtBuild.common]
 
 [PcdsFeatureFlag]
   gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|TRUE
+  gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|TRUE
+
+[PcdsFixedAtBuild.common]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x4000000000
+  gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|3
+  gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x10000
+  gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x7FC
 ##
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 03/16] Silicon/NXP: Implement PciHostBridgeLib support
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 02/16] Silicon/NXP: LS1043A: Define " Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Implement PciHostBridgeLib that exposes the PCIe root complexes to
the generic PCI host bridge driver.

Setup PCIe Layerscape Controller and setup CFG, IO,
MMIO and MMIO64 iATU windows.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Added logic to create MMIO64 windows based on MMIO64 available space
    - Drop EmbeddedPkg/EmbeddedPkg.dec
    - Removed "__" from header file inclusion

 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf |  39 ++
 Silicon/NXP/Include/Pcie.h                                |  80 +++
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 558 ++++++++++++++++++++
 3 files changed, 677 insertions(+)

diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 000000000000..aa4802b019f6
--- /dev/null
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,39 @@
+## @file
+#  PCI Host Bridge Library instance for NXP ARM SOC
+#
+#  Copyright 2018-2020 NXP
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = PciHostBridgeLib
+  FILE_GUID                      = f4c99bcc-5c95-49ad-b0f3-fc5b611dc9c1
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciHostBridgeLib
+
+[Sources]
+  PciHostBridgeLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/NXP/NxpQoriqLs.dec
+
+[LibraryClasses]
+  DebugLib
+  DevicePathLib
+  IoAccessLib
+  MemoryAllocationLib
+  PcdLib
+
+[FeaturePcd]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian
+
+[FixedPcd]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+  gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
+  gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
+  gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
new file mode 100755
index 000000000000..9dbe876b9c1a
--- /dev/null
+++ b/Silicon/NXP/Include/Pcie.h
@@ -0,0 +1,80 @@
+/** @file
+  PCI memory configuration for NXP
+
+  Copyright 2018-2020 NXP
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PCI_H
+#define PCI_H
+
+#define PCI_SEG0_NUM              0
+#define PCI_SEG1_NUM              1
+#define PCI_SEG2_NUM              2
+#define PCI_SEG3_NUM              3
+#define PCI_SEG4_NUM              4
+#define PCI_SEG5_NUM              5
+#define PCI_SEG0_MMIO_MEMBASE     FixedPcdGet64 (PcdPciExp1BaseAddr)
+#define PCI_SEG0_DBI_BASE         0x03400000
+
+#define PCI_LINK_DOWN             0x0
+#define PCI_LINK_UP               0x1
+
+// Segment configuration
+#define PCI_SEG_BUSNUM_MIN        0x0
+#define PCI_SEG_BUSNUM_MAX        0xff
+#define PCI_SEG_PORTIO_MIN        0x0
+#define PCI_SEG_PORTIO_MAX        0xffff
+#define SEG_CFG_SIZE              0x00001000
+#define SEG_MEM_BASE              0x40000000
+#define SEG_MEM_SIZE              0xC0000000
+#define SEG_MEM_LIMIT             SEG_MEM_BASE + (SEG_MEM_SIZE -1)
+#define SEG_IO_BASE               0x10000000
+#define SEG_MEM64_BASE            0x400000000
+#define PCI_BASE_DIFF             0x800000000
+#define PCI_DBI_SIZE_DIFF         0x100000
+#define PCI_SEG0_PHY_CFG0_BASE    PCI_SEG0_MMIO_MEMBASE
+#define PCI_SEG0_PHY_CFG1_BASE    PCI_SEG0_PHY_CFG0_BASE + SEG_CFG_SIZE
+#define PCI_SEG0_PHY_MEM_BASE     PCI_SEG0_MMIO_MEMBASE + SEG_MEM_BASE
+#define PCI_SEG0_PHY_MEM64_BASE   PCI_SEG0_MMIO_MEMBASE + SEG_MEM64_BASE
+#define PCI_MMIO64_WIN_SIZE       SIZE_16GB
+#define PCI_SEG0_PHY_IO_BASE      PCI_SEG0_MMIO_MEMBASE + SEG_IO_BASE
+
+// PCIe Controller configuration
+#define NUM_PCIE_CONTROLLER       FixedPcdGet32 (PcdNumPciController)
+#define PCI_LUT_DBG               FixedPcdGet32 (PcdPcieLutDbg)
+#define PCI_LUT_BASE              FixedPcdGet32 (PcdPcieLutBase)
+#define LTSSM_PCIE_L0             0x11
+
+#define PCI_CLASS_BRIDGE_PCI      0x0604
+#define PCI_CLASS_DEVICE          0x8
+#define PCI_DBI_RO_WR_EN          0x8bc
+#define CLASS_CODE_MASK           0xffff
+#define CLASS_CODE_SHIFT          0x10
+
+// PCIe Layerscape Controller
+#define IATU_VIEWPORT_OFF                            0x900
+#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0            0x904
+#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0            0x908
+#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 IATU_VIEWPORT_OUTBOUND                       0x0
+#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN  BIT31
+
+// ATU Programming
+#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_INDEX0        0x0
+#define IATU_REGION_INDEX1        0x1
+#define SEG_CFG_BUS               0x00000000
+#define SEG_MEM_BUS               0x40000000
+#define SEG_IO_SIZE               0x10000
+#define SEG_IO_BUS                0x0
+
+#endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 000000000000..230fcf57690e
--- /dev/null
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,558 @@
+/** @file
+  PCI Host Bridge Library instance for NXP SoCs
+
+  Copyright 2018-2020 NXP
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoAccessLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <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
+      PCI_SEG0_NUM
+    },
+
+    {
+      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
+      PCI_SEG1_NUM
+    },
+
+    {
+      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
+      PCI_SEG2_NUM
+    },
+
+    {
+      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
+      PCI_SEG3_NUM
+    },
+
+    {
+      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
+      PCI_SEG4_NUM
+    },
+
+    {
+      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
+      PCI_SEG5_NUM
+    },
+
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      {
+        END_DEVICE_PATH_LENGTH,
+        0
+      }
+    }
+  }
+};
+
+STATIC
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+  L"Mem", L"I/O", L"Bus"
+};
+
+#define PCI_ALLOCATION_ATTRIBUTES       EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | \
+                                        EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+
+#define PCI_SUPPORT_ATTRIBUTES          EFI_PCI_ATTRIBUTE_ISA_IO_16 | \
+                                        EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
+                                        EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
+                                        EFI_PCI_ATTRIBUTE_VGA_IO_16  | \
+                                        EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
+
+PCI_ROOT_BRIDGE mPciRootBridges[NUM_PCIE_CONTROLLER];
+
+/**
+   Helper function to check PCIe link state
+
+   @param Pcie Address of PCIe host controller.
+
+**/
+STATIC
+INTN
+PcieLinkUp (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN UINT32 Idx
+  )
+{
+  MMIO_OPERATIONS *PcieOps;
+  UINT32 State;
+  UINT32 LtssmMask;
+
+  LtssmMask = 0x3f;
+
+  PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
+  State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask;
+
+  if (State < LTSSM_PCIE_L0) {
+    DEBUG ((DEBUG_INFO,"PCIE%d : reg @ 0x%lx, no link: LTSSM=0x%02x\n",
+            Idx + 1, Pcie, State));
+    return PCI_LINK_DOWN;
+  }
+
+  return PCI_LINK_UP;
+}
+
+/**
+  Function to set-up PCIe outbound window
+
+  @param Dbi     Address of PCIe host controller.
+  @param Idx     Index of iATU outbound window.
+  @param Type    Type(Cfg0/Cfg1/Mem/IO) of iATU outbound window.
+  @param Phys    PCIe controller phy address for outbound window.
+  @param BusAdr  PCIe controller bus address for outbound window.
+  @param Size    Window size
+
+**/
+STATIC
+VOID
+PcieOutboundSet (
+  IN EFI_PHYSICAL_ADDRESS Dbi,
+  IN UINT32 Idx,
+  IN UINT32 Type,
+  IN UINT64 Phys,
+  IN UINT64 BusAddr,
+  IN UINT64 Size
+  )
+{
+  // PCIe Layerscape : Outbound Window
+  MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
+                (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
+
+  MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
+                (UINT32)Phys);
+
+  MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
+                (UINT32)(Phys >> 32));
+
+  MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
+                (UINT32)(Phys + Size - BIT0));
+
+  MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
+                (UINT32)BusAddr);
+
+  MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
+                (UINT32)(BusAddr >> 32));
+
+  MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
+                (UINT32)Type);
+
+  MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+                IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+}
+
+/**
+  Function to set-up iATU windows for Layerscape PCIe controller
+
+  @param Pcie      Address of PCIe host controller
+  @param Cfg0Base  PCIe controller phy address Type0 Configuration Space.
+  @param Cfg1Base  PCIe controller phy address Type1 Configuration Space.
+  @param MemBase   PCIe controller phy address Memory Space.
+  @param Mem64Base PCIe controller phy address MMIO64 Space.
+  @param IoBase    PCIe controller phy address IO Space.
+**/
+STATIC
+VOID
+PcieLsSetupAtu (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN EFI_PHYSICAL_ADDRESS Cfg0Base,
+  IN EFI_PHYSICAL_ADDRESS Cfg1Base,
+  IN EFI_PHYSICAL_ADDRESS MemBase,
+  IN EFI_PHYSICAL_ADDRESS Mem64Base,
+  IN EFI_PHYSICAL_ADDRESS IoBase
+  )
+{
+  UINT64 Cfg0BaseAddr;
+  UINT64 Cfg1BaseAddr;
+  UINT64 Cfg0BusAddress;
+  UINT64 Cfg1BusAddress;
+  UINT64 Cfg0Size;
+  UINT64 Cfg1Size;
+  UINT64 Mem64End;
+  UINT32 Index;
+
+  Cfg0BaseAddr = Cfg0Base;
+  Cfg1BaseAddr = Cfg1Base;
+  Cfg0BusAddress = SEG_CFG_BUS;
+  Cfg1BusAddress = SEG_CFG_BUS;
+  Cfg0Size = SEG_CFG_SIZE;
+  Cfg1Size = SEG_CFG_SIZE;
+
+  Index = 0;
+  // iATU : OUTBOUND WINDOW 1 : CFG0
+  PcieOutboundSet (Pcie,
+    Index++,
+    IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0,
+    Cfg0BaseAddr,
+    Cfg0BusAddress,
+    Cfg0Size);
+
+  // iATU : OUTBOUND WINDOW 2 : CFG1
+  PcieOutboundSet (Pcie,
+    Index++,
+    IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1,
+    Cfg1BaseAddr,
+    Cfg1BusAddress,
+    Cfg1Size);
+
+  // iATU : OUTBOUND WINDOW 3 : MEM
+  PcieOutboundSet (Pcie,
+    Index++,
+    IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+    MemBase,
+    SEG_MEM_BUS,
+    SEG_MEM_SIZE);
+
+  //
+  // To allow maximum MMIO64 space, MMIO64 window
+  // size must be multiple of max iATU size (4GB)
+  //
+  ASSERT ((PCI_MMIO64_WIN_SIZE & (SIZE_4GB - 1)) == 0);
+
+  Mem64End = Mem64Base + PCI_MMIO64_WIN_SIZE - 1;
+  while (Mem64Base < Mem64End) {
+    // iATU : OUTBOUND WINDOWs : MMIO64
+    PcieOutboundSet (Pcie,
+      Index++,
+      IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+      Mem64Base,
+      Mem64Base,
+      SIZE_4GB);
+    Mem64Base += SIZE_4GB;
+  }
+
+  // iATU : OUTBOUND WINDOW : IO
+  PcieOutboundSet (Pcie,
+    Index++,
+    IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO,
+    IoBase,
+    SEG_IO_BUS,
+    SEG_IO_SIZE
+    );
+}
+/**
+  Helper function to set-up PCIe controller
+
+  @param Pcie       Address of PCIe host controller
+  @param Cfg0Base   PCIe controller phy address Type0 Configuration Space.
+  @param Cfg1Base   PCIe controller phy address Type1 Configuration Space.
+  @param MemBase    PCIe controller phy address Memory Space.
+  @param Mem64Base  PCIe controller phy address MMIO64 Space.
+  @param IoBase     PCIe controller phy address IO Space.
+
+**/
+STATIC
+VOID
+PcieSetupCntrl (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN EFI_PHYSICAL_ADDRESS Cfg0Base,
+  IN EFI_PHYSICAL_ADDRESS Cfg1Base,
+  IN EFI_PHYSICAL_ADDRESS MemBase,
+  IN EFI_PHYSICAL_ADDRESS Mem64Base,
+  IN EFI_PHYSICAL_ADDRESS IoBase
+  )
+{
+  UINT32 Val;
+
+  // PCIe Layerscape Controller Setup
+  PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
+
+  // Program Class code for Layerscape PCIe controller
+  MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
+  Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
+  Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
+  Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
+  MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
+  MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
+}
+
+/**
+  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.
+
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+  OUT UINTN     *Count
+  )
+{
+  UINTN         Idx;
+  UINTN         Loop;
+  UINT64        PciPhyMemAddr[NUM_PCIE_CONTROLLER];
+  UINT64        PciPhyMem64Addr[NUM_PCIE_CONTROLLER];
+  UINT64        PciPhyCfg0Addr[NUM_PCIE_CONTROLLER];
+  UINT64        PciPhyCfg1Addr[NUM_PCIE_CONTROLLER];
+  UINT64        PciPhyIoAddr[NUM_PCIE_CONTROLLER];
+  UINT64        Regs[NUM_PCIE_CONTROLLER];
+  INTN          LinkUp;
+
+  for  (Idx = 0, Loop = 0; Idx < NUM_PCIE_CONTROLLER; Idx++) {
+    PciPhyMemAddr[Idx] = PCI_SEG0_PHY_MEM_BASE + (PCI_BASE_DIFF * Idx);
+    PciPhyMem64Addr[Idx] = PCI_SEG0_PHY_MEM64_BASE + (PCI_BASE_DIFF * Idx);
+    PciPhyCfg0Addr[Idx] = PCI_SEG0_PHY_CFG0_BASE + (PCI_BASE_DIFF * Idx);
+    PciPhyCfg1Addr[Idx] = PCI_SEG0_PHY_CFG1_BASE + (PCI_BASE_DIFF * Idx);
+    PciPhyIoAddr [Idx] =  PCI_SEG0_PHY_IO_BASE + (PCI_BASE_DIFF * Idx);
+    Regs[Idx] =  PCI_SEG0_DBI_BASE + (PCI_DBI_SIZE_DIFF * Idx);
+
+    // Check PCIe Link
+    LinkUp = PcieLinkUp(Regs[Idx], Idx);
+
+    if (!LinkUp) {
+      continue;
+    }
+    DEBUG ((DEBUG_INFO, "PCIE%d Passed Linkup Phase\n", Idx + 1));
+    // Set up PCIe Controller and ATU windows
+    PcieSetupCntrl (Regs[Idx],
+                    PciPhyCfg0Addr[Idx],
+                    PciPhyCfg1Addr[Idx],
+                    PciPhyMemAddr[Idx],
+                    PciPhyMem64Addr[Idx],
+                    PciPhyIoAddr[Idx]);
+
+    mPciRootBridges[Loop].Segment               = Idx;
+    mPciRootBridges[Loop].Supports              = PCI_SUPPORT_ATTRIBUTES;
+    mPciRootBridges[Loop].Attributes            = PCI_SUPPORT_ATTRIBUTES;
+    mPciRootBridges[Loop].DmaAbove4G            = TRUE;
+    mPciRootBridges[Loop].NoExtendedConfigSpace = FALSE;
+    mPciRootBridges[Loop].ResourceAssigned      = FALSE;
+    mPciRootBridges[Loop].AllocationAttributes  = PCI_ALLOCATION_ATTRIBUTES;
+
+    mPciRootBridges[Loop].Bus.Base              = PCI_SEG_BUSNUM_MIN;
+    mPciRootBridges[Loop].Bus.Limit             = PCI_SEG_BUSNUM_MAX;
+
+    mPciRootBridges[Loop].Io.Base               = PCI_SEG_PORTIO_MIN;
+    mPciRootBridges[Loop].Io.Limit              = PCI_SEG_PORTIO_MAX;
+    mPciRootBridges[Loop].Io.Translation        = MAX_UINT64 -
+                                                  (SEG_IO_SIZE * Idx) + 1;
+
+    mPciRootBridges[Loop].Mem.Base              = SEG_MEM_BASE;
+    mPciRootBridges[Loop].Mem.Limit             = SEG_MEM_LIMIT;
+    mPciRootBridges[Loop].Mem.Translation       = MAX_UINT64 -
+                                                  (PCI_SEG0_MMIO_MEMBASE +
+                                                  (PCI_BASE_DIFF *
+                                                  Idx)) + 1;
+
+    mPciRootBridges[Loop].MemAbove4G.Base       = PciPhyMem64Addr[Idx];
+    mPciRootBridges[Loop].MemAbove4G.Limit      = PciPhyMem64Addr[Idx] +
+                                                  (PCI_MMIO64_WIN_SIZE - 1);
+
+    mPciRootBridges[Loop].PMem.Base             = MAX_UINT64;
+    mPciRootBridges[Loop].PMem.Limit            = 0;
+    mPciRootBridges[Loop].PMemAbove4G.Base      = MAX_UINT64;
+    mPciRootBridges[Loop].PMemAbove4G.Limit     = 0;
+    mPciRootBridges[Loop].DevicePath            = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Idx];
+    Loop++;
+  }
+
+  if (Loop == 0) {
+    return NULL;
+  }
+
+  *Count = Loop;
+  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
+                   );
+  }
+
+  return;
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (2 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

PCIe layerscape controller supports CFG Shift feature. It can be
enabled by setting BIT[28] of iATU Control 2 Register.
Check PcdPciCfgShiftEnable to enable 'CFG Shift feature' in
PCIe controller.
if enable, PCIe layerscape controller shifts BDF from bits[27:12] to
bits[31:16] and supports Enhanced Configuration Address Mapping (ECAM)
mechanism.

PCIe layerscape controller is ECAM complaint for bus[0x1-0xff].
So create outbound CFG windows from 1MB-256MB (255 buses) for
type0/type1 configuration access.
PCIe layerscape controller is Non-ECAM complaint for bus 0.It does
not support device > 0 on bus 0. PciSegmentLib should handles this
limitation.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Introduced ECAM_BUS_SIZE and ECAM_CFG_REGION_SIZE for CFG
      region size and added comments for same.

 Silicon/NXP/NxpQoriqLs.dec                                |  3 ++
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf |  3 ++
 Silicon/NXP/Include/Pcie.h                                |  5 +++
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 37 +++++++++++++++-----
 4 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 9ff5ce8a1c6e..5358aaeb037e 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -35,3 +35,6 @@ [PcdsFixedAtBuild.common]
   gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|0|UINT32|0x00000501
   gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
   gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
+
+[PcdsDynamic.common]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
index aa4802b019f6..99807d5beb1f 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -37,3 +37,6 @@ [FixedPcd]
   gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
   gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
   gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
+
+[Pcd]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index 9dbe876b9c1a..f7c18c3aa094 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -27,6 +27,8 @@
 #define PCI_SEG_PORTIO_MIN        0x0
 #define PCI_SEG_PORTIO_MAX        0xffff
 #define SEG_CFG_SIZE              0x00001000
+#define ECAM_BUS_SIZE             SIZE_1MB
+#define ECAM_CFG_REGION_SIZE      SIZE_256MB
 #define SEG_MEM_BASE              0x40000000
 #define SEG_MEM_SIZE              0xC0000000
 #define SEG_MEM_LIMIT             SEG_MEM_BASE + (SEG_MEM_SIZE -1)
@@ -64,6 +66,7 @@
 #define IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0        0x91C
 #define IATU_VIEWPORT_OUTBOUND                       0x0
 #define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN  BIT31
+#define IATU_ENABLE_CFG_SHIFT_FEATURE                BIT28
 
 // ATU Programming
 #define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM   0x0
@@ -77,4 +80,6 @@
 #define SEG_IO_SIZE               0x10000
 #define SEG_IO_BUS                0x0
 
+#define CFG_SHIFT_ENABLE          (PcdGetBool (PcdPciCfgShiftEnable))
+
 #endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 230fcf57690e..9fae19095cba 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -259,8 +259,17 @@ PcieOutboundSet (
   MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
                 (UINT32)Type);
 
-  MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
-                IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+  if (CFG_SHIFT_ENABLE &&
+     ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
+     (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
+       MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+         (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
+         IATU_ENABLE_CFG_SHIFT_FEATURE)
+         );
+  } else {
+    MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+                  IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+  }
 }
 
 /**
@@ -293,12 +302,24 @@ PcieLsSetupAtu (
   UINT64 Mem64End;
   UINT32 Index;
 
-  Cfg0BaseAddr = Cfg0Base;
-  Cfg1BaseAddr = Cfg1Base;
-  Cfg0BusAddress = SEG_CFG_BUS;
-  Cfg1BusAddress = SEG_CFG_BUS;
-  Cfg0Size = SEG_CFG_SIZE;
-  Cfg1Size = SEG_CFG_SIZE;
+  if (CFG_SHIFT_ENABLE) {
+    DEBUG ((DEBUG_INFO, "PCIe: CFG Shift Method Enabled \n"));
+    Cfg0BaseAddr = Cfg0Base + SIZE_1MB;
+    Cfg1BaseAddr = Cfg0Base + SIZE_2MB;
+    Cfg0BusAddress = SIZE_1MB;
+    Cfg1BusAddress = SIZE_2MB;
+    // Region for type0 CFG transactions (only for bus1)
+    Cfg0Size = ECAM_BUS_SIZE;
+    // Region for type1 CFG transactions (for bus > 1)
+    Cfg1Size = (ECAM_CFG_REGION_SIZE - ECAM_BUS_SIZE); // 255MB
+  } else {
+    Cfg0BaseAddr = Cfg0Base;
+    Cfg1BaseAddr = Cfg1Base;
+    Cfg0BusAddress = SEG_CFG_BUS;
+    Cfg1BusAddress = SEG_CFG_BUS;
+    Cfg0Size = SEG_CFG_SIZE;
+    Cfg1Size = SEG_CFG_SIZE;
+  }
 
   Index = 0;
   // iATU : OUTBOUND WINDOW 1 : CFG0
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (3 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451 Wasim Khan
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Setup PCIe LayerscapeGen4 controller and setup CFG, IO,
MMIO and MMIO64 iATU windows.
Check for PcdPciLsGen4Ctrl to enable LsGen4 PCIe
controller.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Added logic to create MMIO64 ATU windows as per MMIO64 available space

 Silicon/NXP/NxpQoriqLs.dec                                |   1 +
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf |   1 +
 Silicon/NXP/Include/Pcie.h                                | 120 ++++++++++
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 247 ++++++++++++++++----
 4 files changed, 328 insertions(+), 41 deletions(-)

diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 5358aaeb037e..d4d3057af509 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -38,3 +38,4 @@ [PcdsFixedAtBuild.common]
 
 [PcdsDynamic.common]
   gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
+  gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl|FALSE|BOOLEAN|0x00000601
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
index 99807d5beb1f..aa5a9dec7c34 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -40,3 +40,4 @@ [FixedPcd]
 
 [Pcd]
   gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
+  gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index f7c18c3aa094..b7d46f3a3bd2 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -81,5 +81,125 @@
 #define SEG_IO_BUS                0x0
 
 #define CFG_SHIFT_ENABLE          (PcdGetBool (PcdPciCfgShiftEnable))
+#define PCI_LS_GEN4_CTRL          (PcdGetBool (PcdPciLsGen4Ctrl))
 
+// PCIe Layerscape Gen4 Controller
+#define GPEX_CLASSCODE                          0x474
+#define GPEX_CLASSCODE_SHIFT                    16
+#define GPEX_CLASSCODE_MASK                     0xffff
+#define PAB_AXI_PIO_CTRL(Idx)                   (0x840 + 0x10 * Idx)
+#define APIO_EN                                 0x1
+#define MEM_WIN_EN                              0x1 << 1
+#define IO_WIN_EN                               0x1 << 2
+#define CFG_WIN_EN                              0x1 << 3
+#define PAB_PEX_PIO_CTRL(Idx)                   (0x8c0 + 0x10 * Idx)
+#define PPIO_EN                                 (0x1 << 0)
+#define PAB_PEX_PIO_STAT(Idx)                   (0x8c4 + 0x10 * Idx)
+#define PAB_PEX_PIO_MT_STAT(Idx)                (0x8c8 + 0x10 * Idx)
+#define PEX_AMAP_CTRL_TYPE_SHIFT                0x1
+#define PEX_AMAP_CTRL_EN_SHIFT                  0x0
+#define PEX_AMAP_CTRL_TYPE_MASK                 0x3
+#define PEX_AMAP_CTRL_EN_MASK                   0x1
+#define PAB_PEX_AMAP_CTRL(Idx)                  (0x4ba0 + 0x10 * Idx)
+#define PAB_EXT_PEX_AMAP_SIZE(Idx)              (0xbef0 + 0x04 * Idx)
+#define PAB_PEX_AMAP_AXI_WIN(Idx)               (0x4ba4 + 0x10 * Idx)
+#define PAB_EXT_PEX_AMAP_AXI_WIN(Idx)           (0xb4a0 + 0x04 * Idx)
+#define PAB_PEX_AMAP_PEX_WIN_L(Idx)             (0x4ba8 + 0x10 * Idx)
+#define PAB_PEX_AMAP_PEX_WIN_H(Idx)             (0x4bac + 0x10 * Idx)
+#define PAB_CTRL                                0x808
+#define PAB_CTRL_APIO_EN                        0x1
+#define PAB_CTRL_PPIO_EN                        (0x1 << 1)
+#define PAB_CTRL_PAGE_SEL_SHIFT                 13
+#define PAB_CTRL_PAGE_SEL_MASK                  0x3f
+#define INDIRECT_ADDR_BNDRY                     0xc00
+#define PAGE_IDX_SHIFT                          10
+#define PAGE_ADDR_MASK                          0x3ff
+#define PAB_AXI_AMAP_CTRL(Idx)                  (0xba0 + 0x10 * Idx)
+#define PAB_EXT_AXI_AMAP_SIZE(Idx)              (0xbaf0 + 0x4 * Idx)
+#define PAB_AXI_AMAP_AXI_WIN(Idx)               (0xba4 + 0x10 * Idx)
+#define PAB_EXT_AXI_AMAP_AXI_WIN(Idx)           (0x80a0 + 0x4 * Idx)
+#define PAB_AXI_AMAP_PEX_WIN_L(Idx)             (0xba8 + 0x10 * Idx)
+#define PAB_AXI_AMAP_PEX_WIN_H(Idx)             (0xbac + 0x10 * Idx)
+#define PAB_AXI_TYPE_CFG                        0x00
+#define PAB_AXI_TYPE_IO                         0x01
+#define PAB_AXI_TYPE_MEM                        0x02
+#define AXI_AMAP_CTRL_EN                        0x1
+#define AXI_AMAP_CTRL_TYPE_SHIFT                1
+#define AXI_AMAP_CTRL_TYPE_MASK                 0x3
+#define AXI_AMAP_CTRL_SIZE_SHIFT                10
+#define AXI_AMAP_CTRL_SIZE_MASK                 0x3fffff
+
+
+#define OFFSET_TO_PAGE_IDX(Off)                 ((Off >> PAGE_IDX_SHIFT) \
+                                                & PAB_CTRL_PAGE_SEL_MASK)
+
+#define OFFSET_TO_PAGE_ADDR(Off)                ((Off & PAGE_ADDR_MASK) \
+                                                | INDIRECT_ADDR_BNDRY)
+/**
+  Function to set page for LsGen4 Ctrl
+
+  @param  Dbi    GPEX host controller address.
+  @param  PgIdx  The page index to select
+
+**/
+STATIC inline VOID PciLsGen4SetPg (
+  IN EFI_PHYSICAL_ADDRESS Dbi,
+  IN UINT8 PgIdx
+  )
+{
+  UINT32 Val;
+  Val = MmioRead32 (Dbi + PAB_CTRL);
+  Val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT);
+  Val |= (PgIdx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT;
+  MmioWrite32 (Dbi + PAB_CTRL, Val);
+}
+
+/**
+  Function to read LsGen4 PCIe controller config space
+  LsGen4 PCIe controller requires page number to be set
+  in Bridge Control Register(PAB) for offset > 3KB.
+
+  @param  Dbi     GPEX host controller address.
+  @param  Offset  Offset to read from
+
+**/
+STATIC inline INTN PciLsGen4Read32 (
+  IN EFI_PHYSICAL_ADDRESS Dbi,
+  IN UINT32 Offset
+  )
+{
+  if (Offset < INDIRECT_ADDR_BNDRY) {
+    PciLsGen4SetPg (Dbi, 0);
+    return MmioRead32 (Dbi + Offset);
+  } else {
+    // If Offset > 3KB, paging mechanism is used
+    // Select page index and offset within the page
+    PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
+    return MmioRead32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset));
+  }
+}
+
+/**
+  Function to write to LsGen4 PCIe controller config space
+  LsGen4 PCIe controller requires page number to be set
+  in Bridge Control Register(PAB) for offset > 3KB.
+
+  @param  Dbi     GPEX host controller address
+  @param  Offset  Offset to read from
+
+**/
+STATIC inline VOID PciLsGen4Write32 (
+  IN EFI_PHYSICAL_ADDRESS Dbi,
+  IN UINT32 Offset,
+  IN UINT32 Value
+  )
+{
+  if (Offset < INDIRECT_ADDR_BNDRY) {
+    PciLsGen4SetPg (Dbi, 0);
+    MmioWrite32 (Dbi + Offset, Value);
+  } else {
+    PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
+    MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value);
+  }
+}
 #endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 9fae19095cba..8e39fb25f83e 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -201,7 +201,11 @@ PcieLinkUp (
   UINT32 State;
   UINT32 LtssmMask;
 
-  LtssmMask = 0x3f;
+  if (PCI_LS_GEN4_CTRL) {
+    LtssmMask = 0x7f;
+  } else {
+    LtssmMask = 0x3f;
+  }
 
   PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
   State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask;
@@ -237,38 +241,58 @@ PcieOutboundSet (
   IN UINT64 Size
   )
 {
-  // PCIe Layerscape : Outbound Window
-  MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
-                (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
+  UINT32 Val;
 
-  MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
-                (UINT32)Phys);
-
-  MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
-                (UINT32)(Phys >> 32));
-
-  MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
-                (UINT32)(Phys + Size - BIT0));
-
-  MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
-                (UINT32)BusAddr);
-
-  MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
-                (UINT32)(BusAddr >> 32));
-
-  MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
-                (UINT32)Type);
-
-  if (CFG_SHIFT_ENABLE &&
-     ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
-     (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
-       MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
-         (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
-         IATU_ENABLE_CFG_SHIFT_FEATURE)
-         );
+  if (PCI_LS_GEN4_CTRL) {
+    // PCIe Layerscape Gen4: Outbound Window
+    Size = ~(Size -1 );
+    Val = PciLsGen4Read32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx));
+    Val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
+              (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
+              AXI_AMAP_CTRL_EN);
+    Val |= ((Type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
+             (((UINT32)Size >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
+             AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx), Val);
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_AXI_WIN (Idx), (UINT32)Phys);
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_AXI_WIN (Idx), Phys >> 32);
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L (Idx), (UINT32)BusAddr);
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H (Idx), BusAddr >> 32);
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_SIZE (Idx), Size >> 32);
   } else {
-    MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
-                  IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+    // PCIe Layerscape : Outbound Window
+    MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
+                  (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
+
+    MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
+                  (UINT32)Phys);
+
+    MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
+                  (UINT32)(Phys >> 32));
+
+    MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
+                  (UINT32)(Phys + Size - BIT0));
+
+    MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
+                  (UINT32)BusAddr);
+
+    MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
+                  (UINT32)(BusAddr >> 32));
+
+    MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
+                  (UINT32)Type);
+
+    if (CFG_SHIFT_ENABLE &&
+       ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
+       (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
+         MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+           (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
+           IATU_ENABLE_CFG_SHIFT_FEATURE)
+           );
+    } else {
+      MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+                    IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+    }
   }
 }
 
@@ -373,6 +397,116 @@ PcieLsSetupAtu (
     SEG_IO_SIZE
     );
 }
+
+/**
+  Function to set-up ATU windows for PCIe LayerscapeGen4 controller
+
+  @param Pcie      Address of PCIe host controller
+  @param Cfg0Base  PCIe controller phy address Type0 Configuration Space.
+  @param Cfg1Base  PCIe controller phy address Type1 Configuration Space.
+  @param MemBase   PCIe controller phy address Memory Space.
+  @param Mem64Base PCIe controller phy address MMIO64 Space.
+  @param IoBase    PCIe controller phy address IO Space.
+**/
+STATIC
+VOID
+PcieLsGen4SetupAtu (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN EFI_PHYSICAL_ADDRESS Cfg0Base,
+  IN EFI_PHYSICAL_ADDRESS Cfg1Base,
+  IN EFI_PHYSICAL_ADDRESS MemBase,
+  IN EFI_PHYSICAL_ADDRESS Mem64Base,
+  IN EFI_PHYSICAL_ADDRESS IoBase
+  )
+{
+  UINT64 Mem64End;
+  UINT32 Index;
+
+  Index=0;
+
+  // ATU : OUTBOUND WINDOW 1 : CFG0
+  PcieOutboundSet (Pcie, Index++,
+                         PAB_AXI_TYPE_CFG,
+                         Cfg0Base,
+                         SEG_CFG_BUS,
+                         SEG_CFG_SIZE);
+
+  // ATU : OUTBOUND WINDOW 2 : IO
+  PcieOutboundSet (Pcie, Index++,
+                         PAB_AXI_TYPE_IO,
+                         IoBase,
+                         SEG_IO_BUS,
+                         SEG_IO_SIZE);
+
+  // ATU : OUTBOUND WINDOW 3 : MEM
+  PcieOutboundSet (Pcie, Index++,
+                         PAB_AXI_TYPE_MEM,
+                         MemBase,
+                         SEG_MEM_BUS,
+                         SEG_MEM_SIZE);
+
+  //
+  // To allow maximum MMIO64 space, MMIO64 window
+  // size must be multiple of max iATU size (4GB)
+  //
+  ASSERT ((PCI_MMIO64_WIN_SIZE & (SIZE_4GB - 1)) == 0);
+
+  Mem64End = Mem64Base + PCI_MMIO64_WIN_SIZE - 1;
+  while (Mem64Base < Mem64End) {
+    // ATU : OUTBOUND WINDOW : MMIO64
+    PcieOutboundSet (Pcie, Index++,
+                           PAB_AXI_TYPE_MEM,
+                           Mem64Base,
+                           Mem64Base,
+                           SIZE_4GB);
+
+    Mem64Base += SIZE_4GB;
+  }
+}
+
+/**
+  Function to set-up PCIe inbound window
+
+  @param Pcie    Address of PCIe host controller.
+  @param Idx     Index of inbound window.
+  @param Type    Type(Cfg/Mem/IO) of iATU outbound window.
+  @param Phys    PCIe controller phy address for inbound window.
+  @param BusAdr  PCIe controller bus address for inbound window.
+  @param Size    Window size
+
+**/
+
+STATIC
+VOID
+PciSetupInBoundWin (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN UINT32 Idx,
+  IN UINT32  Type,
+  IN UINT64 Phys,
+  IN UINT64 BusAddr,
+  IN UINT64 Size)
+{
+  UINT32 Val;
+  UINT64 WinSize;
+
+  if (PCI_LS_GEN4_CTRL) {
+    Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx));
+    Val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
+    Val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
+    Val = (Val | (Type << PEX_AMAP_CTRL_TYPE_SHIFT));
+    Val = (Val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
+
+    WinSize = ~(Size - 1);
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx),
+                       (Val | (UINT32)WinSize));
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_SIZE(Idx), (WinSize>>32));
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_AXI_WIN(Idx), (UINT32)Phys);
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_AXI_WIN(Idx), (Phys>>32));
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_L(Idx), (UINT32)BusAddr);
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_H(Idx), (BusAddr >>32));
+  }
+}
+
 /**
   Helper function to set-up PCIe controller
 
@@ -397,16 +531,47 @@ PcieSetupCntrl (
 {
   UINT32 Val;
 
-  // PCIe Layerscape Controller Setup
-  PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
-
-  // Program Class code for Layerscape PCIe controller
-  MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
-  Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
-  Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
-  Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
-  MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
-  MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
+  if (PCI_LS_GEN4_CTRL) {
+    // PCIe LsGen4 Controller Setup
+
+    //Fix Class Code
+    Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE);
+    Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
+    Val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
+    PciLsGen4Write32 ((UINTN)Pcie, GPEX_CLASSCODE, Val);
+
+    // Enable APIO and Memory/IO/CFG Windows
+    Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0));
+    Val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0), Val);
+
+    // LsGen4 Inbound Window Setup
+    PciSetupInBoundWin (Pcie, 0, PAB_AXI_TYPE_MEM, 0 , 0, SIZE_1TB);
+
+    // LsGen4 Outbound Window Setup
+    PcieLsGen4SetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
+
+    // Enable AMBA & PEX PIO
+    Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_CTRL);
+    Val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_CTRL, Val);
+
+    Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0));
+    Val |= PPIO_EN;
+    PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0), Val);
+
+  } else {
+    // PCIe Layerscape Controller Setup
+    PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
+
+    // Program Class code for Layerscape PCIe controller
+    MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
+    Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
+    Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
+    Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
+    MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
+    MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
+  }
 }
 
 /**
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (4 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

When PCIe Layerscape Gen4 controller is sending multiple split
completions and ACK latency expires indicating that ACK should
be send at priority. But because of large number of split completions
and FC update DLLP,the controller does not give priority to ACK
transmission. This results into ACK latency timer timeout error
at the link partner and the pending TLPs are replayed by the
link partner again.

Workaround:
Reduce the ACK latency timeout value.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author

 Silicon/NXP/Include/Pcie.h                              | 4 ++++
 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index b7d46f3a3bd2..210e4c3cf5e7 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -202,4 +202,8 @@ STATIC inline VOID PciLsGen4Write32 (
     MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value);
   }
 }
+
+#define GPEX_ACK_REPLAY_TO                      0x438
+#define ACK_LAT_TO_VAL_SHIFT                    0
+#define ACK_LAT_TO_VAL_MASK                     0x1fff
 #endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 8e39fb25f83e..339a3d9bffa6 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -534,6 +534,12 @@ PcieSetupCntrl (
   if (PCI_LS_GEN4_CTRL) {
     // PCIe LsGen4 Controller Setup
 
+    // Workaround for A-011451
+    Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_ACK_REPLAY_TO);
+    Val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
+    Val |= (4 << ACK_LAT_TO_VAL_SHIFT);
+    PciLsGen4Write32 ((UINTN)Pcie, GPEX_ACK_REPLAY_TO, Val);
+
     //Fix Class Code
     Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE);
     Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (5 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451 Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Dump ATU windows for PCIe LsGen4 controller.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Drop PcdPciDebug and use DEBUG_CODE_BEGIN/DEBUG_CODE_END
    - Passing Max window number as argument to LsGen4DumpAtu()

 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c | 36 ++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 339a3d9bffa6..53b93e2b6f23 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -399,6 +399,38 @@ PcieLsSetupAtu (
 }
 
 /**
+  Dump PCIe LsGen4 ATU
+
+  @param Pcie     Address of PCIe host controller.
+  @param Count    Number of Windows
+**/
+VOID LsGen4DumpAtu (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN UINT32 Count
+  )
+{
+  UINT32 Cnt;
+  for (Cnt = 0; Cnt < Count; Cnt++) {
+    DEBUG ((DEBUG_INFO,"APIO WINDOW%d:\n", Cnt));
+    DEBUG ((DEBUG_INFO,"\tLOWER PHYS 0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_AXI_WIN (Cnt))));
+    DEBUG ((DEBUG_INFO,"\tUPPER PHYS 0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_EXT_AXI_AMAP_AXI_WIN (Cnt))));
+    DEBUG ((DEBUG_INFO,"\tLOWER BUS  0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_PEX_WIN_L (Cnt))));
+    DEBUG ((DEBUG_INFO,"\tUPPER BUS  0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_PEX_WIN_H (Cnt))));
+    DEBUG ((DEBUG_INFO,"\tSIZE      0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_CTRL (Cnt)) &
+            (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT)));
+    DEBUG ((DEBUG_INFO,"\tEXT_SIZE        0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_EXT_AXI_AMAP_SIZE (Cnt))));
+    DEBUG ((DEBUG_INFO,"\tCTRL:        0x%08x\n",
+            PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_CTRL (Cnt))));
+  }
+}
+
+/**
   Function to set-up ATU windows for PCIe LayerscapeGen4 controller
 
   @param Pcie      Address of PCIe host controller
@@ -462,6 +494,10 @@ PcieLsGen4SetupAtu (
 
     Mem64Base += SIZE_4GB;
   }
+
+  DEBUG_CODE_BEGIN ();
+  LsGen4DumpAtu (Pcie, Index);
+  DEBUG_CODE_END ();
 }
 
 /**
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (6 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Dump ATU windows for PCIe Layerscape controller.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Drop PcdPciDebug and use DEBUG_CODE_BEGIN/DEBUG_CODE_END
    - Passing Max window number as argument to LsDumpAtu()

 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c | 44 ++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 53b93e2b6f23..670353b6c8d4 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -297,6 +297,46 @@ PcieOutboundSet (
 }
 
 /**
+  Dump PCIe Layerscape ATU
+
+  @param Pcie     Address of PCIe host controller.
+  @param Count    Number of Windows
+**/
+VOID LsDumpAtu (
+  IN EFI_PHYSICAL_ADDRESS Pcie,
+  IN UINT32 Count
+  )
+{
+  UINT32 Cnt;
+  for (Cnt = 0; Cnt < Count; Cnt++) {
+    MmioWrite32 ((UINTN)Pcie + IATU_VIEWPORT_OFF,
+                  (UINT32)(IATU_VIEWPORT_OUTBOUND | Cnt));
+
+    DEBUG ((DEBUG_INFO, "iATU%d:\n",Cnt));
+    DEBUG ((DEBUG_INFO, "\tLOWER PHYS 0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0)));
+
+    DEBUG ((DEBUG_INFO, "\tUPPER PHYS 0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0)));
+
+    DEBUG ((DEBUG_INFO, "\tLOWER BUS 0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0)));
+
+    DEBUG ((DEBUG_INFO, "\tUPPER BUS 0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0)));
+
+    DEBUG ((DEBUG_INFO, "\tLIMIT     0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_LIMIT_ADDR_OFF_OUTBOUND_0)));
+
+    DEBUG ((DEBUG_INFO, "\tCR1       0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_REGION_CTRL_1_OFF_OUTBOUND_0)));
+
+    DEBUG ((DEBUG_INFO, "\tCR2       0x%08x\n",
+            MmioRead32 ((UINTN)Pcie + IATU_REGION_CTRL_2_OFF_OUTBOUND_0)));
+  }
+}
+
+/**
   Function to set-up iATU windows for Layerscape PCIe controller
 
   @param Pcie      Address of PCIe host controller
@@ -396,6 +436,10 @@ PcieLsSetupAtu (
     SEG_IO_BUS,
     SEG_IO_SIZE
     );
+
+  DEBUG_CODE_BEGIN ();
+  LsDumpAtu (Pcie, Index);
+  DEBUG_CODE_END ();
 }
 
 /**
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (7 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

We have different PCI config space region for bus 0 (Controller space) and
bus[0x1-0xff] on NXP SoCs with PCIe LS controller.
Add PciSegmentLib for PCIe LS controller.

For config transactions for Bus0:
  - Config transaction address = PCIe controller address + offset

For config transactions for Bus[0x1-0xff]:
  - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
    type0/type1 outbound window.
  - Config transaction address = PCIe config space address + offset

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Removed Signed-off and added Co-authored-by for co-author
    - Incorporated review comments:
      - Remove outer () while calculating Target
      - Use (Bus > 0) instead of (Bus)

 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf |  32 +
 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c   | 612 ++++++++++++++++++++
 2 files changed, 644 insertions(+)

diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
new file mode 100755
index 000000000000..a36e79239b33
--- /dev/null
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
@@ -0,0 +1,32 @@
+## @file
+#  PCI Segment Library for NXP SoCs with multiple RCs
+#
+#  Copyright 2018-2020 NXP
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = PciSegmentLib
+  FILE_GUID                      = c9f59261-5a60-4a4c-82f6-1f520442e100
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciSegmentLib|DXE_DRIVER
+  CONSTRUCTOR                    = PciSegLibInit
+
+[Sources]
+  PciSegmentLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/NXP/NxpQoriqLs.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+
+[FixedPcd]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
new file mode 100755
index 000000000000..d0bacca3d0d7
--- /dev/null
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -0,0 +1,612 @@
+/** @file
+  PCI Segment Library for NXP SoCs with multiple RCs
+
+  Copyright 2018-2020 NXP
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PiDxe.h>
+#include <Base.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Pcie.h>
+
+typedef enum {
+  PciCfgWidthUint8      = 0,
+  PciCfgWidthUint16,
+  PciCfgWidthUint32,
+  PciCfgWidthMax
+} PCI_CFG_WIDTH;
+
+/**
+  Assert the validity of a PCI Segment address.
+  A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
+
+  @param  A The address to validate.
+  @param  M Additional bits to assert to be zero.
+
+**/
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
+  ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
+
+STATIC
+UINT64
+PciLsCfgTarget (
+  IN  EFI_PHYSICAL_ADDRESS Dbi,
+  IN  UINT64               Address,
+  IN  UINT16               Segment,
+  IN  UINT8                Bus,
+  IN  UINT16               Offset
+  )
+{
+  UINT32 Target;
+
+  Target = (((Address >> 20) & 0xFF) << 24) |
+           (((Address >> 15) & 0x1F) << 19) |
+           (((Address >> 12) & 0x7) << 16);
+
+  if (Bus > 1) {
+    MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF, IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX1);
+  } else {
+    MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF, IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX0);
+  }
+
+  MmioWrite32 ((UINTN)Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, Target);
+
+  if (Bus > 1) {
+    return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + SEG_CFG_SIZE + Offset;
+  } else {
+    return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + Offset;
+  }
+}
+
+/**
+  Function to return PCIe Physical Address(PCIe view) or Controller
+  Address(CPU view) for different RCs
+
+  @param  Address Address passed from bus layer.
+  @param  Segment Segment number for Root Complex.
+  @param  Offset  Config space register offset.
+  @param  Bus     PCIe Bus number.
+
+  @return Return PCIe CPU or Controller address.
+
+**/
+STATIC
+UINT64
+PciLsGetConfigBase (
+  IN  UINT64      Address,
+  IN  UINT16      Segment,
+  IN  UINT16      Offset,
+  IN  UINT8       Bus
+  )
+{
+  UINT32 CfgAddr;
+
+  CfgAddr = (UINT16)Offset;
+  if (Bus > 0) {
+    return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
+  } else {
+    return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+  }
+}
+
+/**
+  Function to return PCIe Physical Address(PCIe view) or Controller
+  Address(CPU view) for different RCs
+
+  @param  Address Address passed from bus layer.
+  @param  Segment Segment number for Root Complex.
+  @param  Offset  Config space register offset.
+
+  @return Return PCIe CPU or Controller address.
+
+**/
+STATIC
+UINT64
+PciSegmentLibGetConfigBase (
+  IN  UINT64      Address,
+  IN  UINT16      Segment,
+  IN  UINT16      Offset
+  )
+{
+  UINT8  Bus;
+
+  Bus = ((UINT32)Address >> 20) & 0xff;
+  return PciLsGetConfigBase (Address, Segment, Offset, Bus);
+}
+
+/**
+  Internal worker function to read a PCI configuration register.
+
+  @param  Address The address that encodes the Segment, PCI Bus, Device,
+                  Function and Register.
+  @param  Width   The width of data to read
+
+  @return The value read from the PCI configuration register.
+
+**/
+STATIC
+UINT32
+PciSegmentLibReadWorker (
+  IN  UINT64                      Address,
+  IN  PCI_CFG_WIDTH               Width
+  )
+{
+  UINT64    Base;
+  UINT16    Offset;
+  UINT16    Segment;
+
+  Segment = (Address >> 32);
+  Offset = (Address & 0xfff );
+
+  Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
+
+  // ignore devices > 0 on bus 0
+  if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
+    return MAX_UINT32;
+  }
+
+  // ignore device > 0 on bus 1
+  if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
+    return MAX_UINT32;
+  }
+
+  switch (Width) {
+  case PciCfgWidthUint8:
+    return MmioRead8 (Base);
+  case PciCfgWidthUint16:
+    return MmioRead16 (Base);
+  case PciCfgWidthUint32:
+    return MmioRead32 (Base);
+  default:
+    ASSERT (FALSE);
+  }
+
+  return CHAR_NULL;
+}
+
+/**
+  Internal worker function to writes a PCI configuration register.
+
+  @param  Address The address that encodes the Segment, PCI Bus, Device,
+                  Function and Register.
+  @param  Width   The width of data to write
+  @param  Data    The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+STATIC
+UINT32
+PciSegmentLibWriteWorker (
+  IN  UINT64                      Address,
+  IN  PCI_CFG_WIDTH               Width,
+  IN  UINT32                      Data
+  )
+{
+  UINT64    Base;
+  UINT32    Offset;
+  UINT16    Segment;
+
+  Segment = (Address >> 32);
+  Offset = (Address & 0xfff );
+
+  Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
+
+  // ignore devices > 0 on bus 0
+  if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
+    return Data;
+  }
+
+  // ignore device > 0 on bus 1
+  if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
+    return MAX_UINT32;
+  }
+
+  switch (Width) {
+  case PciCfgWidthUint8:
+    MmioWrite8 (Base , Data);
+    break;
+  case PciCfgWidthUint16:
+    MmioWrite16 (Base , Data);
+    break;
+  case PciCfgWidthUint32:
+    MmioWrite32 (Base , Data);
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return Data;
+}
+
+/**
+  Register a PCI device so PCI configuration registers may be accessed after
+  SetVirtualAddressMap().
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address                  The address that encodes the PCI Bus, Device,
+                                   Function and Register.
+
+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
+                                   after ExitBootServices().
+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device
+                                   at runtime could not be mapped.
+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to
+                                   complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciSegmentRegisterForRuntimeAccess (
+  IN UINTN  Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  Reads an 8-bit PCI configuration register.
+
+  Reads and returns the 8-bit PCI configuration register specified by Address.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+
+  @return The 8-bit PCI configuration register specified by Address.
+
+**/
+UINT8
+EFIAPI
+PciSegmentRead8 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
+}
+
+/**
+  Writes an 8-bit PCI configuration register.
+
+  Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentWrite8 (
+  IN UINT64                    Address,
+  IN UINT8                     Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, Value);
+}
+
+/**
+  Reads a 16-bit PCI configuration register.
+
+  Reads and returns the 16-bit PCI configuration register specified by Address.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 16-bit PCI configuration register specified by Address.
+
+**/
+UINT16
+EFIAPI
+PciSegmentRead16 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return (UINT16) PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
+}
+
+/**
+  Writes a 16-bit PCI configuration register.
+
+  Writes the 16-bit PCI configuration register specified by Address with the
+  value specified by Value.
+
+  Value is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+PciSegmentWrite16 (
+  IN UINT64                    Address,
+  IN UINT16                    Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return (UINT16) PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, Value);
+}
+
+/**
+  Reads a 32-bit PCI configuration register.
+
+  Reads and returns the 32-bit PCI configuration register specified by Address.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+
+  @return The 32-bit PCI configuration register specified by Address.
+
+**/
+UINT32
+EFIAPI
+PciSegmentRead32 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
+}
+
+/**
+  Writes a 32-bit PCI configuration register.
+
+  Writes the 32-bit PCI configuration register specified by Address with the
+  value specified by Value.
+
+  Value is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device,
+                      Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT32
+EFIAPI
+PciSegmentWrite32 (
+  IN UINT64                    Address,
+  IN UINT32                    Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, Value);
+}
+
+/**
+  Reads a range of PCI configuration registers into a caller supplied buffer.
+
+  Reads the range of PCI configuration registers specified by StartAddress and
+  Size into the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be read. Size is
+  returned.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus,
+                        Device, Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  Buffer        The pointer to a buffer receiving the data read.
+
+  @return Size
+
+**/
+UINTN
+EFIAPI
+PciSegmentReadBuffer (
+  IN  UINT64                   StartAddress,
+  IN  UINTN                    Size,
+  OUT VOID                     *Buffer
+  )
+{
+  UINTN                             ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
+
+  if (Size == 0) {
+    return Size;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Read a byte if StartAddress is byte aligned
+    //
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+    StartAddress += sizeof (UINT8);
+    Size -= sizeof (UINT8);
+    Buffer = (UINT8*)Buffer + BIT0;
+  }
+
+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+    //
+    // Read a word if StartAddress is word aligned
+    //
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + BIT0;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    //
+    // Read as many double words as possible
+    //
+    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
+    StartAddress += sizeof (UINT32);
+    Size -= sizeof (UINT32);
+    Buffer = (UINT32*)Buffer + BIT0;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    //
+    // Read the last remaining word if exist
+    //
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + BIT0;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    //
+    // Read the last remaining byte if exist
+    //
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+  }
+
+  return ReturnValue;
+}
+
+
+/**
+  Copies the data in a caller supplied buffer to a specified range of PCI
+  configuration space.
+
+  Writes the range of PCI configuration registers specified by StartAddress and
+  Size from the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be written. Size is
+  returned.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus,
+                        Device, Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  Buffer        The pointer to a buffer containing the data to write.
+
+  @return The parameter of Size.
+
+**/
+UINTN
+EFIAPI
+PciSegmentWriteBuffer (
+  IN UINT64                    StartAddress,
+  IN UINTN                     Size,
+  IN VOID                      *Buffer
+  )
+{
+  UINTN                             ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
+
+  if (Size == 0) {
+    return Size;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Write a byte if StartAddress is byte aligned
+    //
+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
+    StartAddress += sizeof (UINT8);
+    Size -= sizeof (UINT8);
+    Buffer = (UINT8*)Buffer + BIT0;
+  }
+
+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+    //
+    // Write a word if StartAddress is word aligned
+    //
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + BIT0;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    //
+    // Write as many double words as possible
+    //
+    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
+    StartAddress += sizeof (UINT32);
+    Size -= sizeof (UINT32);
+    Buffer = (UINT32*)Buffer + BIT0;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    //
+    // Write the last remaining word if exist
+    //
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + BIT0;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    //
+    // Write the last remaining byte if exist
+    //
+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
+  }
+
+  return ReturnValue;
+}
+
+EFI_STATUS
+PciSegLibInit (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return EFI_SUCCESS;
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (8 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

PCIe Layerscape controller can be enabled for ECAM style
configuration access using CFG SHIFT Feature.

Check for PcdPciCfgShiftEnable to decide the configuration access
scheme to be used with PCIe LS controller.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Addressed review comment to use (Bus > 0) instead of (Bus)

 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf |  3 +++
 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c   | 20 ++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
index a36e79239b33..936213dc8a9d 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
@@ -30,3 +30,6 @@ [LibraryClasses]
 
 [FixedPcd]
   gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+
+[Pcd]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
index d0bacca3d0d7..e5251ecf0dd8 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -34,6 +34,8 @@ typedef enum {
 #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
   ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
 
+static BOOLEAN CfgShiftEnable;
+
 STATIC
 UINT64
 PciLsCfgTarget (
@@ -88,11 +90,20 @@ PciLsGetConfigBase (
 {
   UINT32 CfgAddr;
 
-  CfgAddr = (UINT16)Offset;
-  if (Bus > 0) {
-    return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
+  if (CfgShiftEnable) {
+    CfgAddr = (UINT32)Address;
+    if (Bus > 0) {
+      return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + CfgAddr;
+    } else {
+      return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+    }
   } else {
-    return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+    CfgAddr = (UINT16)Offset;
+    if (Bus > 0) {
+      return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
+    } else {
+      return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+    }
   }
 }
 
@@ -608,5 +619,6 @@ PciSegLibInit (
   IN EFI_SYSTEM_TABLE  *SystemTable
   )
 {
+  CfgShiftEnable = CFG_SHIFT_ENABLE;
   return EFI_SUCCESS;
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (9 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

PCIe Layerscape Gen4 controller is not ECAM compliant and have
different PCI config space region for bus 0 (Controller space) and
bus[0x1-0xff] on NXP SoCs.

For config transactions for Bus0:
  - Config transaction address = PCIe controller address + offset

For config transactions for Bus[0x1-0xff]:
  - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
    outbound configuration window.

PCIe LsGen4 controller uses paging mechanism to access registers.
To access PCIe CCSR registers which are above 3KB offset, page number
must be set in Bridge Control Register.

Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - fix typo in commit message
    - Removed Signed-off and added Co-authored-by for co-author
    - Addressed review comments to:
      - Drop outer () while calulating Target
      - Use (Bus > 0) instead of (Bus)

 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf |  1 +
 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c   | 60 +++++++++++++++++++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
index 936213dc8a9d..d6d7ea6e3b6b 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
@@ -33,3 +33,4 @@ [FixedPcd]
 
 [Pcd]
   gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
+  gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
index e5251ecf0dd8..09ce620ef988 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -35,6 +35,58 @@ typedef enum {
   ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
 
 static BOOLEAN CfgShiftEnable;
+static BOOLEAN PciLsGen4Ctrl;
+
+STATIC
+VOID
+PcieCfgSetTarget (
+  IN EFI_PHYSICAL_ADDRESS Dbi,
+  IN UINT32 Target)
+{
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L(0), Target);
+    PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
+}
+
+/**
+  Function to return PCIe Physical Address(PCIe view) or Controller
+  Address(CPU view) for NXP Layerscape Gen4 SoC
+
+  @param  Address Address passed from bus layer.
+  @param  Segment Segment number for Root Complex.
+  @param  Offset  Config space register offset.
+  @param  Bus     PCIe Bus number.
+
+  @return Return PCIe CPU or Controller address.
+
+**/
+STATIC
+UINT64
+PciLsGen4GetConfigBase (
+  IN  UINT64      Address,
+  IN  UINT16      Segment,
+  IN  UINT16      Offset,
+  IN  UINT8       Bus
+  )
+{
+  UINT32 Target;
+
+  if (Bus > 0) {
+    Target = (((Address >> 20) & 0xFF) << 24) |
+             (((Address >> 15) & 0x1F) << 19) |
+             (((Address >> 12) & 0x7) << 16);
+
+    PcieCfgSetTarget ((PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment), Target);
+    return PCI_SEG0_MMIO_MEMBASE + Offset + PCI_BASE_DIFF * Segment;
+  } else {
+      if (Offset < INDIRECT_ADDR_BNDRY) {
+        PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, 0);
+        return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
+      }
+      PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, OFFSET_TO_PAGE_IDX (Offset));
+      Offset = OFFSET_TO_PAGE_ADDR (Offset);
+      return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
+  }
+}
 
 STATIC
 UINT64
@@ -129,7 +181,12 @@ PciSegmentLibGetConfigBase (
   UINT8  Bus;
 
   Bus = ((UINT32)Address >> 20) & 0xff;
-  return PciLsGetConfigBase (Address, Segment, Offset, Bus);
+
+  if (PciLsGen4Ctrl) {
+    return PciLsGen4GetConfigBase (Address, Segment, Offset, Bus);
+  } else {
+    return PciLsGetConfigBase (Address, Segment, Offset, Bus);
+  }
 }
 
 /**
@@ -620,5 +677,6 @@ PciSegLibInit (
   )
 {
   CfgShiftEnable = CFG_SHIFT_ENABLE;
+  PciLsGen4Ctrl = PCI_LS_GEN4_CTRL;
   return EFI_SUCCESS;
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (10 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

With PCIe LsGen4 controller, clearing the Bus Master Enable bit in
Command register blocks all outbound transactions to be sent out
in RC mode.

According to PCI Express base specification, the Command register’s
Bus Master Enable bit of a PCI Express RC controller can only
control the forwarding of memory requests received at its root port
in the upstream direction. In other words, clearing the Bus Master
Enable bit must not block all outbound transactions to be sent out
toward RC’s downstream devices. Due to this erratum, when the
Command register’s Bus Master Enable bit is cleared, all the outbound
transactions from the device’s internal bus masters, including but
not limited to configuration read and write transactions, are
terminated with the slave error (SLVERR) response status on the PCI
Express RC controller’s internal AXI bus interface.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Addressed review comments to:
      - Drop outer () while calculating Target
      - Use (Bus > 0) instead of (Bus)

 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
index 09ce620ef988..572fbb195c19 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -39,6 +39,21 @@ static BOOLEAN PciLsGen4Ctrl;
 
 STATIC
 VOID
+PciLsGen4SetBusMaster (
+  IN EFI_PHYSICAL_ADDRESS Dbi
+  )
+{
+  UINT32 Val;
+
+  //Make sure the Master Enable bit not cleared
+  Val = PciLsGen4Read32 ((UINTN)Dbi, PCI_COMMAND_OFFSET);
+  if (!(Val & EFI_PCI_COMMAND_BUS_MASTER)) {
+    PciLsGen4Write32 ((UINTN)Dbi, PCI_COMMAND_OFFSET, Val | EFI_PCI_COMMAND_BUS_MASTER);
+  }
+}
+
+STATIC
+VOID
 PcieCfgSetTarget (
   IN EFI_PHYSICAL_ADDRESS Dbi,
   IN UINT32 Target)
@@ -71,6 +86,8 @@ PciLsGen4GetConfigBase (
   UINT32 Target;
 
   if (Bus > 0) {
+    PciLsGen4SetBusMaster (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment);
+
     Target = (((Address >> 20) & 0xFF) << 24) |
              (((Address >> 15) & 0x1F) << 19) |
              (((Address >> 12) & 0x7) << 16);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (11 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

NXP SoC has multiple PCIe RCs and there is no fix translation
offset between I/O port accesses and MMIO accesses.
Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL
to add the translation for different RCs for IO access.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
---

Notes:
    V2:
    - No change

 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf |  40 ++
 Silicon/NXP/Include/Pcie.h                        |  19 +
 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c   | 628 ++++++++++++++++++++
 3 files changed, 687 insertions(+)

diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
new file mode 100755
index 000000000000..0ee470e41d5e
--- /dev/null
+++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
@@ -0,0 +1,40 @@
+## @file
+#  Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
+#
+# Copyright 2018, 2020 NXP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = PciCpuIo2Dxe
+  FILE_GUID                      = 7bff18d7-9aae-434b-9c06-f10a7e157eac
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PciCpuIo2Initialize
+
+[Sources]
+  PciCpuIo2Dxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/NXP/NxpQoriqLs.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Pcd]
+  gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+  gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
+
+[Protocols]
+  gEfiCpuIo2ProtocolGuid                         ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index 210e4c3cf5e7..14cf385df7eb 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -42,6 +42,25 @@
 #define PCI_SEG0_PHY_MEM64_BASE   PCI_SEG0_MMIO_MEMBASE + SEG_MEM64_BASE
 #define PCI_MMIO64_WIN_SIZE       SIZE_16GB
 #define PCI_SEG0_PHY_IO_BASE      PCI_SEG0_MMIO_MEMBASE + SEG_IO_BASE
+#define PCI_SEG0_PORTIO_MIN       0x0
+#define PCI_SEG0_PORTIO_MAX       0xffff
+#define PCI_SEG0_PORTIO_OFFSET    0x0
+#define PCI_SEG1_PORTIO_MIN       0x0
+#define PCI_SEG1_PORTIO_MAX       0xffff
+#define PCI_SEG1_PORTIO_OFFSET    0x10000
+#define PCI_SEG2_PORTIO_MIN       0x0
+#define PCI_SEG2_PORTIO_MAX       0xffff
+#define PCI_SEG2_PORTIO_OFFSET    0x20000
+#define PCI_SEG3_PORTIO_MIN       0x0
+#define PCI_SEG3_PORTIO_MAX       0xffff
+#define PCI_SEG3_PORTIO_OFFSET    0x30000
+#define PCI_SEG4_PORTIO_MIN       0x0
+#define PCI_SEG4_PORTIO_MAX       0xffff
+#define PCI_SEG4_PORTIO_OFFSET    0x40000
+#define PCI_SEG5_PORTIO_MIN       0x0
+#define PCI_SEG5_PORTIO_MAX       0xffff
+#define PCI_SEG5_PORTIO_OFFSET    0x50000
+#define PCI_SEG_PORTIO_LIMIT      PCI_SEG5_PORTIO_MAX + PCI_SEG5_PORTIO_OFFSET
 
 // PCIe Controller configuration
 #define NUM_PCIE_CONTROLLER       FixedPcdGet32 (PcdNumPciController)
diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
new file mode 100755
index 000000000000..17db44a8b510
--- /dev/null
+++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
@@ -0,0 +1,628 @@
+/** @file
+  Produces the CPU I/O 2 Protocol.
+
+  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+  Copyright 2018-2020 NXP
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Pcie.h>
+#include <Protocol/CpuIo2.h>
+
+#define MAX_IO_PORT_ADDRESS PCI_SEG_PORTIO_LIMIT
+
+//
+// Handle for the CPU I/O 2 Protocol
+//
+STATIC EFI_HANDLE  mHandle = NULL;
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8 mInStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  0, // EfiCpuIoWidthFifoUint8
+  0, // EfiCpuIoWidthFifoUint16
+  0, // EfiCpuIoWidthFifoUint32
+  0, // EfiCpuIoWidthFifoUint64
+  1, // EfiCpuIoWidthFillUint8
+  2, // EfiCpuIoWidthFillUint16
+  4, // EfiCpuIoWidthFillUint32
+  8  // EfiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8 mOutStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  1, // EfiCpuIoWidthFifoUint8
+  2, // EfiCpuIoWidthFifoUint16
+  4, // EfiCpuIoWidthFifoUint32
+  8, // EfiCpuIoWidthFifoUint64
+  0, // EfiCpuIoWidthFillUint8
+  0, // EfiCpuIoWidthFillUint16
+  0, // EfiCpuIoWidthFillUint32
+  0  // EfiCpuIoWidthFillUint64
+};
+
+/**
+  Check parameters to a CPU I/O 2 Protocol service request.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work.
+
+  @param[in] MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
+  @param[in] Width          Signifies the width of the I/O or Memory operation.
+  @param[in] Address        The base address of the I/O operation.
+  @param[in] Count          The number of I/O operations to perform. The number of
+                            bytes moved is Width size * Count, starting at Address.
+  @param[in] Buffer         For read operations, the destination buffer to store the results.
+                            For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The parameters for this request pass the checks.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+CpuIoCheckParameter (
+  IN BOOLEAN                    MmioOperation,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  UINT64  MaxCount;
+  UINT64  Limit;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range
+  //
+  if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For FIFO type, the target address won't increase during the access,
+  // so treat Count as 1
+  //
+  if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
+    Count = 1;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port operations
+  //
+  Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+  if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Address is aligned
+  //
+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check to see if any address associated with this transfer exceeds the maximum
+  // allowed address.  The maximum address implied by the parameters passed in is
+  // Address + Size * Count.  If the following condition is met, then the transfer
+  // is not supported.
+  //
+  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
+  //
+  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
+  // can also be the maximum integer value supported by the CPU, this range
+  // check must be adjusted to avoid all oveflow conditions.
+  //
+  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+  if (Count == 0) {
+    if (Address > Limit) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Check to see if Buffer is aligned
+  //
+  if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width])  - 1))) != 0) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+TranslateIoAddress (
+  IN  OUT UINT64                 *Address
+  )
+{
+  UINT64 Start;
+  UINT64 End;
+  UINT64 Shift;
+  UINT64 SegIoHostAddressBase;
+
+  SegIoHostAddressBase = PCI_SEG0_PHY_IO_BASE;
+  Start = PCI_SEG0_PORTIO_MIN + PCI_SEG0_PORTIO_OFFSET;
+  End   = PCI_SEG0_PORTIO_MAX + PCI_SEG0_PORTIO_OFFSET;
+  Shift = SegIoHostAddressBase - PCI_SEG0_PORTIO_OFFSET;
+
+  if (*Address >= Start && *Address <= End) {
+    *Address += Shift;
+    return EFI_SUCCESS;
+  }
+
+  Start = PCI_SEG1_PORTIO_MIN + PCI_SEG1_PORTIO_OFFSET;
+  End   = PCI_SEG1_PORTIO_MAX + PCI_SEG1_PORTIO_OFFSET;
+  Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 1)) - PCI_SEG1_PORTIO_OFFSET;
+
+  if (*Address >= Start && *Address <= End) {
+    *Address += Shift;
+    return EFI_SUCCESS;
+  }
+
+  Start = PCI_SEG2_PORTIO_MIN + PCI_SEG2_PORTIO_OFFSET;
+  End   = PCI_SEG2_PORTIO_MAX + PCI_SEG2_PORTIO_OFFSET;
+  Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 2)) - PCI_SEG2_PORTIO_OFFSET;
+
+  if (*Address >= Start && *Address <= End) {
+    *Address += Shift;
+    return EFI_SUCCESS;
+  }
+
+  Start = PCI_SEG3_PORTIO_MIN + PCI_SEG3_PORTIO_OFFSET;
+  End   = PCI_SEG3_PORTIO_MAX + PCI_SEG3_PORTIO_OFFSET;
+  Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 3)) - PCI_SEG3_PORTIO_OFFSET;
+
+  if (*Address >= Start && *Address <= End) {
+    *Address += Shift;
+    return EFI_SUCCESS;
+  }
+
+  Start = PCI_SEG4_PORTIO_MIN + PCI_SEG4_PORTIO_OFFSET;
+  End   = PCI_SEG4_PORTIO_MAX + PCI_SEG4_PORTIO_OFFSET;
+  Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 4)) - PCI_SEG4_PORTIO_OFFSET;
+
+  if (*Address >= Start && *Address <= End) {
+    *Address += Shift;
+    return EFI_SUCCESS;
+  }
+
+  Start = PCI_SEG5_PORTIO_MIN + PCI_SEG5_PORTIO_OFFSET;
+  End   = PCI_SEG5_PORTIO_MAX + PCI_SEG5_PORTIO_OFFSET;
+  Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 5)) - PCI_SEG5_PORTIO_OFFSET;
+
+  if (*Address >= Start && *Address <= End) {
+    *Address += Shift;
+    return EFI_SUCCESS;
+  }
+  ASSERT (FALSE);
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+  Reads I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = TranslateIoAddress (&Address);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = Buffer; Count > 0;
+       Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  //
+  // Make sure the parameters are valid
+  //
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = TranslateIoAddress (&Address);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0;
+       Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// CPU I/O 2 Protocol instance
+//
+STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
+  {
+    CpuMemoryServiceRead,
+    CpuMemoryServiceWrite
+  },
+  {
+    CpuIoServiceRead,
+    CpuIoServiceWrite
+  }
+};
+
+
+/**
+  The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCpuIo2Initialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mHandle,
+                  &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (12 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support Wasim Khan
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>

Enable NetworkPkg for LS1043aRdb Platform.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - Change author

 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 11 +++++++++++
 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf |  5 +++++
 2 files changed, 16 insertions(+)

diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
index d45fd67c03b5..8f7f9d171587 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
@@ -22,6 +22,13 @@ [Defines]
   OUTPUT_DIRECTORY               = Build/LS1043aRdbPkg
   FLASH_DEFINITION               = Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
 
+  #
+  # Network definition
+  #
+  DEFINE NETWORK_TLS_ENABLE             = FALSE
+  DEFINE NETWORK_HTTP_BOOT_ENABLE       = FALSE
+  DEFINE NETWORK_ISCSI_ENABLE           = FALSE
+
 !include Silicon/NXP/NxpQoriqLs.dsc.inc
 !include Silicon/NXP/LS1043A/LS1043A.dsc.inc
 
@@ -54,4 +61,8 @@ [Components.common]
   Silicon/NXP/Drivers/I2cDxe/I2cDxe.inf
   Platform/NXP/LS1043aRdbPkg/Drivers/PlatformDxe/PlatformDxe.inf
 
+  #
+  # Networking stack
+  #
+!include NetworkPkg/Network.dsc.inc
  ##
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 931d0bb14f9b..596922221e8c 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -119,6 +119,11 @@ [FV.FvMain]
   INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
 
   #
+  # Networking stack
+  #
+!include NetworkPkg/Network.fdf.inc
+
+  #
   # FAT filesystem + GPT/MBR partitioning
   #
   INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (13 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
  2020-05-26  9:53 ` [PATCH edk2-platforms v2 00/16] Add PCIe Support Ard Biesheuvel
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Enable generic PCIe drivers and Wire up PciHostBridgeLib,
PciSegmentLib and PciCpuIo2Dxe.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---

Notes:
    V2:
    - No change

 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 9 +++++++++
 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 7 +++++++
 2 files changed, 16 insertions(+)

diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
index 8f7f9d171587..6d07d5164002 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
@@ -35,6 +35,8 @@ [Defines]
 [LibraryClasses.common]
   ArmPlatformLib|Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
   RealTimeClockLib|Silicon/Maxim/Library/Ds1307RtcLib/Ds1307RtcLib.inf
+  PciSegmentLib|Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
+  PciHostBridgeLib|Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
 
 [PcdsFixedAtBuild.common]
   #
@@ -62,6 +64,13 @@ [Components.common]
   Platform/NXP/LS1043aRdbPkg/Drivers/PlatformDxe/PlatformDxe.inf
 
   #
+  # PCI
+  #
+  Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  #
   # Networking stack
   #
 !include NetworkPkg/Network.dsc.inc
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 596922221e8c..81142f217a63 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -124,6 +124,13 @@ [FV.FvMain]
 !include NetworkPkg/Network.fdf.inc
 
   #
+  # PCI
+  #
+  INF Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  #
   # FAT filesystem + GPT/MBR partitioning
   #
   INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH edk2-platforms v2 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (14 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support Wasim Khan
@ 2020-05-26  8:37 ` Wasim Khan
  2020-05-26  9:53 ` [PATCH edk2-platforms v2 00/16] Add PCIe Support Ard Biesheuvel
  16 siblings, 0 replies; 19+ messages in thread
From: Wasim Khan @ 2020-05-26  8:37 UTC (permalink / raw)
  To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
	leif, jon
  Cc: Wasim Khan

From: Wasim Khan <wasim.khan@nxp.com>

Increase fv image size to pass debug build.

Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
---

Notes:
    V2:
    - No change

 Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 81142f217a63..1c160e349eb9 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -24,10 +24,12 @@
 
 [FD.LS1043ARDB_EFI]
 BaseAddress   = 0x82000000|gArmTokenSpaceGuid.PcdFdBaseAddress  #The base address of the FLASH Device.
-Size          = 0x00140000|gArmTokenSpaceGuid.PcdFdSize         #The size in bytes of the FLASH Device
+Size          = 0x00180000|gArmTokenSpaceGuid.PcdFdSize         #The size in bytes of the FLASH Device
 ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
 BlockSize     = 0x40000
-NumBlocks     = 0x5
+NumBlocks     = 0x6
 
 ################################################################################
 #
@@ -44,7 +46,7 @@ [FD.LS1043ARDB_EFI]
 # RegionType <FV, DATA, or FILE>
 #
 ################################################################################
-0x00000000|0x00140000
+0x00000000|0x00180000
 gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
 FV = FVMAIN_COMPACT
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH edk2-platforms v2 00/16] Add PCIe Support
  2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
                   ` (15 preceding siblings ...)
  2020-05-26  8:37 ` [PATCH edk2-platforms v2 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
@ 2020-05-26  9:53 ` Ard Biesheuvel
  2020-05-26 10:17   ` Ard Biesheuvel
  16 siblings, 1 reply; 19+ messages in thread
From: Ard Biesheuvel @ 2020-05-26  9:53 UTC (permalink / raw)
  To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
	leif, jon
  Cc: Wasim Khan

On 5/26/20 10:37 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
> 
> Add PCIe Support for NXP Layerscape SoC which supports
> different PCIe controllers.
> Use generic PCIe drivers and wire up PciHostBridgeLib,
> PciSegmentLib and PciCpuIo2Dxe driver for controller
> specific implementation.
> 
> V1 Series can be referred here:
> https://edk2.groups.io/g/devel/message/60116?p=,,,20,0,0,0::relevance,,PCIe+Support,20,2,0,74395799
> 
> 
> Changes in V2:
> - Addressed review comments received on V1.
> 

Thanks Wasim

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>

I took some liberties with the PciSegmentLib code to get rid of the 
inline functions in Pcie.h - please double check whether that code is 
still correct, and rebase your code before sending new work that applies 
on top of these changes.

Also, I failed to spot this in review, but preprocessor macros that 
resolve to values that are used in arithmetic expressions should really 
all contain outer (), or you will be pulling your hair out figuring out 
where the unexpected values are coming from. I fixed this up while 
committing (all in Pcie.h)

Pushed as 7a4035e9efd8..7121691cfcbc


> Meenakshi Aggarwal (1):
>    Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
> 
> Wasim Khan (15):
>    Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
>    Silicon/NXP: LS1043A: Define PCIe related PCDs
>    Silicon/NXP: Implement PciHostBridgeLib support
>    Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS
>      Ctrl
>    Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU
>      Windows
>    Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
>    Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
>    Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
>    Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
>    Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS
>      Controller
>    Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
>    Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
>    Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
>    Platform/NXP: LS1043aRdbPkg: Enable PCIE support
>    Platform/NXP: LS1043aRdbPkg : Increase fv image size
> 
>   Silicon/NXP/NxpQoriqLs.dec                                |  12 +
>   Silicon/NXP/LS1043A/LS1043A.dsc.inc                       |   7 +
>   Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc              |  20 +
>   Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf              |  20 +-
>   Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf         |  40 +
>   Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf |  43 +
>   Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf       |  36 +
>   Silicon/NXP/Include/Pcie.h                                | 228 ++++++
>   Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c           | 628 +++++++++++++++
>   Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 830 ++++++++++++++++++++
>   Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c         | 699 +++++++++++++++++
>   11 files changed, 2560 insertions(+), 3 deletions(-)
>   create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
>   create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
>   create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
>   create mode 100755 Silicon/NXP/Include/Pcie.h
>   create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
>   create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
>   create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH edk2-platforms v2 00/16] Add PCIe Support
  2020-05-26  9:53 ` [PATCH edk2-platforms v2 00/16] Add PCIe Support Ard Biesheuvel
@ 2020-05-26 10:17   ` Ard Biesheuvel
  0 siblings, 0 replies; 19+ messages in thread
From: Ard Biesheuvel @ 2020-05-26 10:17 UTC (permalink / raw)
  To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
	leif, jon
  Cc: Wasim Khan

On 5/26/20 11:53 AM, Ard Biesheuvel wrote:
> On 5/26/20 10:37 AM, Wasim Khan wrote:
>> From: Wasim Khan <wasim.khan@nxp.com>
>>
>> Add PCIe Support for NXP Layerscape SoC which supports
>> different PCIe controllers.
>> Use generic PCIe drivers and wire up PciHostBridgeLib,
>> PciSegmentLib and PciCpuIo2Dxe driver for controller
>> specific implementation.
>>
>> V1 Series can be referred here:
>> https://edk2.groups.io/g/devel/message/60116?p=,,,20,0,0,0::relevance,,PCIe+Support,20,2,0,74395799 
>>
>>
>>
>> Changes in V2:
>> - Addressed review comments received on V1.
>>
> 
> Thanks Wasim
> 
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
> 
> I took some liberties with the PciSegmentLib code to get rid of the 
> inline functions in Pcie.h - please double check whether that code is 
> still correct, and rebase your code before sending new work that applies 
> on top of these changes.
> 
> Also, I failed to spot this in review, but preprocessor macros that 
> resolve to values that are used in arithmetic expressions should really 
> all contain outer (), or you will be pulling your hair out figuring out 
> where the unexpected values are coming from. I fixed this up while 
> committing (all in Pcie.h)
> 
> Pushed as 7a4035e9efd8..7121691cfcbc
> 

One thing I realized is that this method of accessing config space is 
not reentrant. This could potentially cause problems, e.g., when some 
notification callback accesses the PCI config space, and reprograms some 
of these windows. If such a callback interrupts an ordinary config space 
access between the time it programs the window and the time it does the 
access, you may be accessing the wrong part of config space.

The usual way of dealing with this is to raise the TPL (Thread Priority 
Level) to TPL_NOTIFY while performing the accesses. So please take this 
into consideration for a followup series.


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-05-26 10:18 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-26  8:37 [PATCH edk2-platforms v2 00/16] Add PCIe Support Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 02/16] Silicon/NXP: LS1043A: Define " Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451 Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support Wasim Khan
2020-05-26  8:37 ` [PATCH edk2-platforms v2 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
2020-05-26  9:53 ` [PATCH edk2-platforms v2 00/16] Add PCIe Support Ard Biesheuvel
2020-05-26 10:17   ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox