devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers
@ 2025-08-19 11:52 hans.zhang
  2025-08-19 11:52 ` [PATCH v8 01/15] PCI: cadence: Add module support for platform controller driver hans.zhang
                   ` (15 more replies)
  0 siblings, 16 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

---
Dear Maintainers,

This series is Cadence's HPA PCIe IP and the Root Port driver of our
CIX sky1. Please help review. Thank you very much.
---

Enhances the exiting Cadence PCIe controller drivers to support
HPA (High Performance Architecture) Cadence PCIe controllers.

The patch set enhances the Cadence PCIe driver for HPA support.
The header files are separated out for legacy and high performance
register maps, register address and bit definitions. The driver
read register and write register functions for HPA take the
updated offset stored from the platform driver to access the registers.
As part of refactoring of the code, few new files are added to the
driver by splitting the existing files.
This helps SoC vendor who change the address map within PCIe controller
in their designs. Setting the menuconfig appropriately will allow
selection between RP and/or EP PCIe controller support. The support
will include Legacy and HPA for the selected configuration.

The TI SoC continues to be supported with the changes incorporated.

The changes address the review comments in the previous patches where
the need to move away from "ops" pointers used in current implementation
and separate out the Legacy and HPA driver implementation was stressed.

The scripts/checkpatch.pl has been run on the patches with and without
--strict. With the --strict option, 4 checks are generated on 3 patch,
which can be ignored. There are no code fixes required for these checks.
All other checks generated by ./scripts/checkpatch.pl --strict can be 
ignored.

---
Changes for v8
        - Fixed the error issue of DT binding. (Rob and Krzysztof)
        - Optimization of CIX SKY1 Root Port driver. (Bjorn and Krzysztof)
        - Review comments fixed. (Bjorn and Krzysztof)
	      - All comments related fixes like single line comments, spaces
              between HPA or LGA, periods in single line, changes proposed
              in the description, etc are fixed. (Bjorn and Krzysztof)
        - Patches have been split to separate out code moves from
          update and fixes.
        - "cdns_...send_irq.." renamed to "cdns_..raise_irq.."

        The test log on the Orion O6 board is as follows:
        root@cix-localhost:~# lspci
        0000:c0:00.0 PCI bridge: Device 1f6c:0001
        0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
        0001:90:00.0 PCI bridge: Device 1f6c:0001
        0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller PM9A1/PM9A3/980PRO
        0002:60:00.0 PCI bridge: Device 1f6c:0001
        0002:61:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
        0003:00:00.0 PCI bridge: Device 1f6c:0001
        0003:01:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8852BE PCIe 802.11ax Wireless Network Controller
        0004:30:00.0 PCI bridge: Device 1f6c:0001
        0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)
        root@cix-localhost:~#
        root@cix-localhost:~# uname -a
        Linux cix-localhost 6.17.0-rc2-00043-gb2782ead460c #185 SMP PREEMPT Tue Aug 19 19:35:34 CST 2025 aarch64 GNU/Linux
        root@cix-localhost:~# cat /etc/issue
        Debian GNU/Linux 12 \n \l

Changes for v7
https://patchwork.kernel.org/project/linux-pci/cover/20250813042331.1258272-1-hans.zhang@cixtech.com/

        - Rebase to v6.17-rc1.
        - Fixed the error issue of cix,sky1-pcie-host.yaml make dt_binding_check.
        - CIX SKY1 Root Port driver compilation error issue: Add header
          file, Kconfig select PCI_ECAM.

Changes for v6
https://patchwork.kernel.org/project/linux-pci/cover/20250808072929.4090694-1-hans.zhang@cixtech.com/

        - The IP level DTS changes for HPA have been removed as the SoC
          level DTS is added
        - Virtual FPGA platform is also removed as the CiX SoC support is
          added
        - Fix the issue of dt bindings
        - Modify the order of PCIe node attributes in sky1-orion-o6.dts
          and delete unnecessary attributes.
        - Continue to simplify the RC driver.
        - The patch of the Cix Sky1 platform has been accepted and merged into the linux master branch.
        https://patchwork.kernel.org/project/linux-arm-kernel/cover/20250721144500.302202-1-peter.chen@cixtech.com/

Changes for v5
https://patchwork.kernel.org/project/linux-pci/cover/20250630041601.399921-1-hans.zhang@cixtech.com/

        - Header and code files separated for library functions(common
          functions used by both architectures) and Legacy and HPA.
        - Few new files added as part of refactoring
        - No checks for "is_hpa" as the functions have been separated
          out
        - Review comments from previous patches have been addressed
        - Add region 0 for ECAM and region 1 for message.
        - Add CIX sky1 PCIe drivers. Submissions based on the following v9 patches:
        https://patchwork.kernel.org/project/linux-arm-kernel/cover/20250609031627.1605851-1-peter.chen@cixtech.com/

        Cix Sky1 base dts review link to show its review status:
        https://lore.kernel.org/all/20250609031627.1605851-9-peter.chen@cixtech.com/

        The test log on the Orion O6 board is as follows:
        root@cix-localhost:~# lspci
        0000:c0:00.0 PCI bridge: Device 1f6c:0001
        0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
        0001:90:00.0 PCI bridge: Device 1f6c:0001
        0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller PM9A1/PM9A3/980PRO
        0002:60:00.0 PCI bridge: Device 1f6c:0001
        0002:61:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8852BE PCIe 802.11ax Wireless Network Controller
        0003:00:00.0 PCI bridge: Device 1f6c:0001
        0003:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
        0004:30:00.0 PCI bridge: Device 1f6c:0001
        0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
        root@cix-localhost:~# uname -a
        Linux cix-localhost 6.16.0-rc1-00023-gbaa962a95a28 #138 SMP PREEMPT Fri Jun 27 16:43:41 CST 2025 aarch64 GNU/Linux
        root@cix-localhost:~# cat /etc/issue
        Debian GNU/Linux 12 \n \l
 
Changes for v4
https://patchwork.kernel.org/project/linux-pci/cover/20250424010445.2260090-1-hans.zhang@cixtech.com/

        - Add header file bitfield.h to pcie-cadence.h
        - Addressed the following review comments
                Merged the TI patch as it
                Removed initialization of struct variables to '0'

Changes for v3
https://patchwork.kernel.org/project/linux-pci/patch/20250411103656.2740517-1-hans.zhang@cixtech.com/

        - Patch version v3 added to the subject
        - Use HPA tag for architecture descriptions
        - Remove bug related changes to be submitted later as a separate
          patch
        - Two patches merged from the last series to ensure readability to
          address the review comments
        - Fix several description related issues, coding style issues and
          some misleading comments
        - Remove cpu_addr_fixup() functions
---

Hans Zhang (6):
  dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings
  PCI: Add Cix Technology Vendor and Device ID
  PCI: sky1: Add PCIe host support for CIX Sky1
  MAINTAINERS: add entry for CIX Sky1 PCIe driver
  arm64: dts: cix: Add PCIe Root Complex on sky1
  arm64: dts: cix: Enable PCIe on the Orion O6 board

Manikandan K Pillai (9):
  PCI: cadence: Add module support for platform controller driver
  PCI: cadence: Split PCIe controller header file
  PCI: cadence: Add register definitions for High Perf Architecture
    (HPA)
  PCI: cadence: Add helper functions for supporting High Perf
    Architecture (HPA)
  PCI: cadence: Move PCIe EP common functions to a separate file
  PCI: cadence: Move PCIe RP common functions to a separate file
  PCI: cadence: Move PCIe controller common functions as a separate file
  PCI: cadence: Add support for High Perf Architecture (HPA) controller
  PCI: cadence: Update PCIe platform to use register offsets passed

 .../bindings/pci/cix,sky1-pcie-host.yaml      |  83 +++
 MAINTAINERS                                   |   7 +
 arch/arm64/boot/dts/cix/sky1-orion-o6.dts     |  20 +
 arch/arm64/boot/dts/cix/sky1.dtsi             | 126 ++++
 drivers/pci/controller/cadence/Kconfig        |  21 +-
 drivers/pci/controller/cadence/Makefile       |  11 +-
 drivers/pci/controller/cadence/pci-sky1.c     | 232 +++++++
 .../controller/cadence/pcie-cadence-common.c  | 141 +++++
 .../cadence/pcie-cadence-ep-common.c          | 251 ++++++++
 .../cadence/pcie-cadence-ep-common.h          |  36 ++
 .../controller/cadence/pcie-cadence-ep-hpa.c  | 528 ++++++++++++++++
 .../pci/controller/cadence/pcie-cadence-ep.c  | 233 +------
 .../cadence/pcie-cadence-host-common.c        | 179 ++++++
 .../cadence/pcie-cadence-host-common.h        |  24 +
 .../cadence/pcie-cadence-host-hpa.c           | 585 ++++++++++++++++++
 .../controller/cadence/pcie-cadence-host.c    | 156 +----
 .../cadence/pcie-cadence-hpa-regs.h           | 182 ++++++
 .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++
 .../cadence/pcie-cadence-lga-regs.h           | 228 +++++++
 .../controller/cadence/pcie-cadence-plat.c    |  20 +-
 drivers/pci/controller/cadence/pcie-cadence.c | 139 +----
 drivers/pci/controller/cadence/pcie-cadence.h | 412 ++++++------
 include/linux/pci_ids.h                       |   3 +
 23 files changed, 3056 insertions(+), 765 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml
 create mode 100644 drivers/pci/controller/cadence/pci-sky1.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-common.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-common.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-common.h
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.h
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-lga-regs.h


base-commit: be48bcf004f9d0c9207ff21d0edb3b42f253829e
-- 
2.49.0


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

* [PATCH v8 01/15] PCI: cadence: Add module support for platform controller driver
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 11:52 ` [PATCH v8 02/15] PCI: cadence: Split PCIe controller header file hans.zhang
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Add support for building PCI cadence platforms as a module.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 drivers/pci/controller/cadence/Kconfig             | 6 +++---
 drivers/pci/controller/cadence/pcie-cadence-plat.c | 5 ++++-
 drivers/pci/controller/cadence/pcie-cadence.c      | 1 +
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
index 666e16b6367f..117677a23d68 100644
--- a/drivers/pci/controller/cadence/Kconfig
+++ b/drivers/pci/controller/cadence/Kconfig
@@ -19,10 +19,10 @@ config PCIE_CADENCE_EP
 	select PCIE_CADENCE
 
 config PCIE_CADENCE_PLAT
-	bool
+	tristate
 
 config PCIE_CADENCE_PLAT_HOST
-	bool "Cadence platform PCIe controller (host mode)"
+	tristate "Cadence platform PCIe controller (host mode)"
 	depends on OF
 	select PCIE_CADENCE_HOST
 	select PCIE_CADENCE_PLAT
@@ -32,7 +32,7 @@ config PCIE_CADENCE_PLAT_HOST
 	  vendors SoCs.
 
 config PCIE_CADENCE_PLAT_EP
-	bool "Cadence platform PCIe controller (endpoint mode)"
+	tristate "Cadence platform PCIe controller (endpoint mode)"
 	depends on OF
 	depends on PCI_ENDPOINT
 	select PCIE_CADENCE_EP
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index 0456845dabb9..ebd5c3afdfcd 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -177,4 +177,7 @@ static struct platform_driver cdns_plat_pcie_driver = {
 	.probe = cdns_plat_pcie_probe,
 	.shutdown = cdns_plat_pcie_shutdown,
 };
-builtin_platform_driver(cdns_plat_pcie_driver);
+module_platform_driver(cdns_plat_pcie_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller platform driver");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index 70a19573440e..5603f214f4c7 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -279,6 +279,7 @@ const struct dev_pm_ops cdns_pcie_pm_ops = {
 	NOIRQ_SYSTEM_SLEEP_PM_OPS(cdns_pcie_suspend_noirq,
 				  cdns_pcie_resume_noirq)
 };
+EXPORT_SYMBOL_GPL(cdns_pcie_pm_ops);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Cadence PCIe controller driver");
-- 
2.49.0


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

* [PATCH v8 02/15] PCI: cadence: Split PCIe controller header file
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
  2025-08-19 11:52 ` [PATCH v8 01/15] PCI: cadence: Add module support for platform controller driver hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 11:52 ` [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA) hans.zhang
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Split the Cadence PCIe header file by moving the Legacy (LGA)
controller register definitions to a separate header file for
support of next generation PCIe controller architecture.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 .../cadence/pcie-cadence-lga-regs.h           | 228 ++++++++++++++++++
 drivers/pci/controller/cadence/pcie-cadence.h | 226 +----------------
 2 files changed, 229 insertions(+), 225 deletions(-)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-lga-regs.h

diff --git a/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h b/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
new file mode 100644
index 000000000000..afff0c35828a
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
@@ -0,0 +1,228 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#ifndef _PCIE_CADENCE_LGA_REGS_H
+#define _PCIE_CADENCE_LGA_REGS_H
+
+#include <linux/bitfield.h>
+
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES	10
+#define LINK_WAIT_USLEEP_MIN	90000
+#define LINK_WAIT_USLEEP_MAX	100000
+
+/* Local Management Registers */
+#define CDNS_PCIE_LM_BASE	0x00100000
+
+/* Vendor ID Register */
+#define CDNS_PCIE_LM_ID		(CDNS_PCIE_LM_BASE + 0x0044)
+#define  CDNS_PCIE_LM_ID_VENDOR_MASK	GENMASK(15, 0)
+#define  CDNS_PCIE_LM_ID_VENDOR_SHIFT	0
+#define  CDNS_PCIE_LM_ID_VENDOR(vid) \
+	(((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK)
+#define  CDNS_PCIE_LM_ID_SUBSYS_MASK	GENMASK(31, 16)
+#define  CDNS_PCIE_LM_ID_SUBSYS_SHIFT	16
+#define  CDNS_PCIE_LM_ID_SUBSYS(sub) \
+	(((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK)
+
+/* Root Port Requester ID Register */
+#define  CDNS_PCIE_LM_RP_RID		(CDNS_PCIE_LM_BASE + 0x0228)
+#define  CDNS_PCIE_LM_RP_RID_MASK	GENMASK(15, 0)
+#define  CDNS_PCIE_LM_RP_RID_SHIFT	0
+#define  CDNS_PCIE_LM_RP_RID_(rid) \
+	(((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK)
+
+/* Endpoint Bus and Device Number Register */
+#define  CDNS_PCIE_LM_EP_ID		(CDNS_PCIE_LM_BASE + 0x022C)
+#define  CDNS_PCIE_LM_EP_ID_DEV_MASK	GENMASK(4, 0)
+#define  CDNS_PCIE_LM_EP_ID_DEV_SHIFT	0
+#define  CDNS_PCIE_LM_EP_ID_BUS_MASK	GENMASK(15, 8)
+#define  CDNS_PCIE_LM_EP_ID_BUS_SHIFT	8
+
+/* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_4) ? CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_4) ? CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0280 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0284 + (fn) * 0x0008)
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
+	(GENMASK(4, 0) << ((b) * 8))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+	(((a) << ((b) * 8)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \
+	(GENMASK(7, 5) << ((b) * 8))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+	(((c) << ((b) * 8 + 5)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
+
+/* Endpoint Function Configuration Register */
+#define CDNS_PCIE_LM_EP_FUNC_CFG	(CDNS_PCIE_LM_BASE + 0x02C0)
+
+/* Root Complex BAR Configuration Register */
+#define CDNS_PCIE_LM_RC_BAR_CFG	(CDNS_PCIE_LM_BASE + 0x0300)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
+	(((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK		GENMASK(8, 6)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \
+	(((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK	GENMASK(13, 9)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
+	(((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK		GENMASK(16, 14)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \
+	(((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE	BIT(17)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS	0
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS	BIT(18)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE		BIT(19)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS		0
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS		BIT(20)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE		BIT(31)
+
+/* BAR control values applicable to both Endpoint Function and Root Complex */
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED		0x0
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS		0x1
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS		0x4
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS	0x5
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS		0x6
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS	0x7
+
+#define LM_RC_BAR_CFG_CTRL_DISABLED(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED << (((bar) * 8) + 6))
+#define LM_RC_BAR_CFG_CTRL_IO_32BITS(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS << (((bar) * 8) + 6))
+#define LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS << (((bar) * 8) + 6))
+#define LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar)	\
+	(CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS << (((bar) * 8) + 6))
+#define LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS << (((bar) * 8) + 6))
+#define LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar)	\
+	(CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS << (((bar) * 8) + 6))
+#define LM_RC_BAR_CFG_APERTURE(bar, aperture)		\
+					(((aperture) - 2) << ((bar) * 8))
+
+/* PTM Control Register */
+#define CDNS_PCIE_LM_PTM_CTRL		(CDNS_PCIE_LM_BASE + 0x0DA8)
+#define CDNS_PCIE_LM_TPM_CTRL_PTMRSEN	BIT(17)
+
+/*
+ * Endpoint Function Registers (PCI configuration space for endpoint functions)
+ */
+#define CDNS_PCIE_EP_FUNC_BASE(fn)	(((fn) << 12) & GENMASK(19, 12))
+
+#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
+#define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET	0xB0
+#define CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET	0xC0
+#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET	0x200
+
+/* Endpoint PF Registers */
+#define CDNS_PCIE_CORE_PF_I_ARI_CAP_AND_CTRL(fn)	(0x144 + (fn) * 0x1000)
+#define CDNS_PCIE_ARI_CAP_NFN_MASK			GENMASK(15, 8)
+
+/* Root Port Registers (PCI configuration space for the root port function) */
+#define CDNS_PCIE_RP_BASE	0x00200000
+#define CDNS_PCIE_RP_CAP_OFFSET 0xC0
+
+/* Address Translation Registers */
+#define CDNS_PCIE_AT_BASE	0x00400000
+
+/* Region r Outbound AXI to PCIe Address Translation Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
+	(CDNS_PCIE_AT_BASE + 0x0000 + ((r) & 0x1F) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \
+	(((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK	GENMASK(19, 12)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+	(((devfn) << 12) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK	GENMASK(27, 20)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+	(((bus) << 20) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
+
+/* Region r Outbound AXI to PCIe Address Translation Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
+	(CDNS_PCIE_AT_BASE + 0x0004 + ((r) & 0x1F) * 0x0020)
+
+/* Region r Outbound PCIe Descriptor Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_DESC0(r) \
+	(CDNS_PCIE_AT_BASE + 0x0008 + ((r) & 0x1F) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK		GENMASK(3, 0)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM		0x2
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO		0x6
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0	0xA
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1	0xB
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG	0xC
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_VENDOR_MSG	0xD
+/* Bit 23 MUST be set in RC mode. */
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID	BIT(23)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK	GENMASK(31, 24)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
+	(((devfn) << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
+
+/* Region r Outbound PCIe Descriptor Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_DESC1(r)	\
+	(CDNS_PCIE_AT_BASE + 0x000C + ((r) & 0x1F) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK	GENMASK(7, 0)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \
+	((bus) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK)
+
+/* Region r AXI Region Base Address Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
+	(CDNS_PCIE_AT_BASE + 0x0018 + ((r) & 0x1F) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \
+	(((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK)
+
+/* Region r AXI Region Base Address Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
+	(CDNS_PCIE_AT_BASE + 0x001C + ((r) & 0x1F) * 0x0020)
+
+/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \
+	(CDNS_PCIE_AT_BASE + 0x0800 + (bar) * 0x0008)
+#define  CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \
+	(((nbits) - 1) & CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \
+	(CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008)
+
+/* AXI link down register */
+#define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
+
+/* LTSSM Capabilities register */
+#define CDNS_PCIE_LTSSM_CONTROL_CAP		(CDNS_PCIE_LM_BASE + 0x0054)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK	GENMASK(2, 1)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 1
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay) \
+	 (((delay) << CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT) & \
+	 CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK)
+
+#define CDNS_PCIE_RP_MAX_IB	0x3
+#define CDNS_PCIE_MAX_OB	32
+
+/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+	(CDNS_PCIE_AT_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+	(CDNS_PCIE_AT_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
+
+/* Normal/Vendor specific message access: offset inside some outbound region */
+#define CDNS_PCIE_NORMAL_MSG_ROUTING_MASK	GENMASK(7, 5)
+#define CDNS_PCIE_NORMAL_MSG_ROUTING(route) \
+	(((route) << 5) & CDNS_PCIE_NORMAL_MSG_ROUTING_MASK)
+#define CDNS_PCIE_NORMAL_MSG_CODE_MASK		GENMASK(15, 8)
+#define CDNS_PCIE_NORMAL_MSG_CODE(code) \
+	(((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
+#define CDNS_PCIE_MSG_NO_DATA                   BIT(16)
+
+#endif /* _PCIE_CADENCE_LGA_REGS_H */
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 1d81c4bf6c6d..79df86117fde 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -10,213 +10,7 @@
 #include <linux/pci.h>
 #include <linux/pci-epf.h>
 #include <linux/phy/phy.h>
-
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES	10
-#define LINK_WAIT_USLEEP_MIN	90000
-#define LINK_WAIT_USLEEP_MAX	100000
-
-/*
- * Local Management Registers
- */
-#define CDNS_PCIE_LM_BASE	0x00100000
-
-/* Vendor ID Register */
-#define CDNS_PCIE_LM_ID		(CDNS_PCIE_LM_BASE + 0x0044)
-#define  CDNS_PCIE_LM_ID_VENDOR_MASK	GENMASK(15, 0)
-#define  CDNS_PCIE_LM_ID_VENDOR_SHIFT	0
-#define  CDNS_PCIE_LM_ID_VENDOR(vid) \
-	(((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK)
-#define  CDNS_PCIE_LM_ID_SUBSYS_MASK	GENMASK(31, 16)
-#define  CDNS_PCIE_LM_ID_SUBSYS_SHIFT	16
-#define  CDNS_PCIE_LM_ID_SUBSYS(sub) \
-	(((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK)
-
-/* Root Port Requester ID Register */
-#define CDNS_PCIE_LM_RP_RID	(CDNS_PCIE_LM_BASE + 0x0228)
-#define  CDNS_PCIE_LM_RP_RID_MASK	GENMASK(15, 0)
-#define  CDNS_PCIE_LM_RP_RID_SHIFT	0
-#define  CDNS_PCIE_LM_RP_RID_(rid) \
-	(((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK)
-
-/* Endpoint Bus and Device Number Register */
-#define CDNS_PCIE_LM_EP_ID	(CDNS_PCIE_LM_BASE + 0x022c)
-#define  CDNS_PCIE_LM_EP_ID_DEV_MASK	GENMASK(4, 0)
-#define  CDNS_PCIE_LM_EP_ID_DEV_SHIFT	0
-#define  CDNS_PCIE_LM_EP_ID_BUS_MASK	GENMASK(15, 8)
-#define  CDNS_PCIE_LM_EP_ID_BUS_SHIFT	8
-
-/* Endpoint Function f BAR b Configuration Registers */
-#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn) \
-	(((bar) < BAR_4) ? CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn))
-#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
-	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
-#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
-	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
-#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn) \
-	(((bar) < BAR_4) ? CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn))
-#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) \
-	(CDNS_PCIE_LM_BASE + 0x0280 + (fn) * 0x0008)
-#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn) \
-	(CDNS_PCIE_LM_BASE + 0x0284 + (fn) * 0x0008)
-#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
-	(GENMASK(4, 0) << ((b) * 8))
-#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
-	(((a) << ((b) * 8)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b))
-#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \
-	(GENMASK(7, 5) << ((b) * 8))
-#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
-	(((c) << ((b) * 8 + 5)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
-
-/* Endpoint Function Configuration Register */
-#define CDNS_PCIE_LM_EP_FUNC_CFG	(CDNS_PCIE_LM_BASE + 0x02c0)
-
-/* Root Complex BAR Configuration Register */
-#define CDNS_PCIE_LM_RC_BAR_CFG	(CDNS_PCIE_LM_BASE + 0x0300)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK	GENMASK(5, 0)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
-	(((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK		GENMASK(8, 6)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \
-	(((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK	GENMASK(13, 9)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
-	(((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK		GENMASK(16, 14)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \
-	(((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE	BIT(17)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS	0
-#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS	BIT(18)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE		BIT(19)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS		0
-#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS		BIT(20)
-#define  CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE		BIT(31)
-
-/* BAR control values applicable to both Endpoint Function and Root Complex */
-#define  CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED		0x0
-#define  CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS		0x1
-#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS		0x4
-#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS	0x5
-#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS		0x6
-#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS	0x7
-
-#define LM_RC_BAR_CFG_CTRL_DISABLED(bar)		\
-		(CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED << (((bar) * 8) + 6))
-#define LM_RC_BAR_CFG_CTRL_IO_32BITS(bar)		\
-		(CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS << (((bar) * 8) + 6))
-#define LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar)		\
-		(CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS << (((bar) * 8) + 6))
-#define LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar)	\
-	(CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS << (((bar) * 8) + 6))
-#define LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar)		\
-		(CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS << (((bar) * 8) + 6))
-#define LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar)	\
-	(CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS << (((bar) * 8) + 6))
-#define LM_RC_BAR_CFG_APERTURE(bar, aperture)		\
-					(((aperture) - 2) << ((bar) * 8))
-
-/* PTM Control Register */
-#define CDNS_PCIE_LM_PTM_CTRL 	(CDNS_PCIE_LM_BASE + 0x0da8)
-#define CDNS_PCIE_LM_TPM_CTRL_PTMRSEN 	BIT(17)
-
-/*
- * Endpoint Function Registers (PCI configuration space for endpoint functions)
- */
-#define CDNS_PCIE_EP_FUNC_BASE(fn)	(((fn) << 12) & GENMASK(19, 12))
-
-#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
-#define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET	0xb0
-#define CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET	0xc0
-#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET	0x200
-
-/*
- * Endpoint PF Registers
- */
-#define CDNS_PCIE_CORE_PF_I_ARI_CAP_AND_CTRL(fn)	(0x144 + (fn) * 0x1000)
-#define CDNS_PCIE_ARI_CAP_NFN_MASK			GENMASK(15, 8)
-
-/*
- * Root Port Registers (PCI configuration space for the root port function)
- */
-#define CDNS_PCIE_RP_BASE	0x00200000
-#define CDNS_PCIE_RP_CAP_OFFSET 0xc0
-
-/*
- * Address Translation Registers
- */
-#define CDNS_PCIE_AT_BASE	0x00400000
-
-/* Region r Outbound AXI to PCIe Address Translation Register 0 */
-#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
-	(CDNS_PCIE_AT_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
-#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK	GENMASK(5, 0)
-#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \
-	(((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK)
-#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK	GENMASK(19, 12)
-#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
-	(((devfn) << 12) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
-#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK	GENMASK(27, 20)
-#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
-	(((bus) << 20) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
-
-/* Region r Outbound AXI to PCIe Address Translation Register 1 */
-#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
-	(CDNS_PCIE_AT_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
-
-/* Region r Outbound PCIe Descriptor Register 0 */
-#define CDNS_PCIE_AT_OB_REGION_DESC0(r) \
-	(CDNS_PCIE_AT_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK		GENMASK(3, 0)
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM		0x2
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO		0x6
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0	0xa
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1	0xb
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG	0xc
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_VENDOR_MSG	0xd
-/* Bit 23 MUST be set in RC mode. */
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID	BIT(23)
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK	GENMASK(31, 24)
-#define  CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
-	(((devfn) << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
-
-/* Region r Outbound PCIe Descriptor Register 1 */
-#define CDNS_PCIE_AT_OB_REGION_DESC1(r)	\
-	(CDNS_PCIE_AT_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
-#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK	GENMASK(7, 0)
-#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \
-	((bus) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK)
-
-/* Region r AXI Region Base Address Register 0 */
-#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
-	(CDNS_PCIE_AT_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
-#define  CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK	GENMASK(5, 0)
-#define  CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \
-	(((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK)
-
-/* Region r AXI Region Base Address Register 1 */
-#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
-	(CDNS_PCIE_AT_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
-
-/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
-#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \
-	(CDNS_PCIE_AT_BASE + 0x0800 + (bar) * 0x0008)
-#define  CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK	GENMASK(5, 0)
-#define  CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \
-	(((nbits) - 1) & CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK)
-#define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \
-	(CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008)
-
-/* AXI link down register */
-#define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
-
-/* LTSSM Capabilities register */
-#define CDNS_PCIE_LTSSM_CONTROL_CAP             (CDNS_PCIE_LM_BASE + 0x0054)
-#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK  GENMASK(2, 1)
-#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 1
-#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay) \
-	 (((delay) << CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT) & \
-	 CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK)
+#include "pcie-cadence-lga-regs.h"
 
 enum cdns_pcie_rp_bar {
 	RP_BAR_UNDEFINED = -1,
@@ -225,29 +19,11 @@ enum cdns_pcie_rp_bar {
 	RP_NO_BAR
 };
 
-#define CDNS_PCIE_RP_MAX_IB	0x3
-#define CDNS_PCIE_MAX_OB	32
-
 struct cdns_pcie_rp_ib_bar {
 	u64 size;
 	bool free;
 };
 
-/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
-#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
-	(CDNS_PCIE_AT_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
-#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
-	(CDNS_PCIE_AT_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
-
-/* Normal/Vendor specific message access: offset inside some outbound region */
-#define CDNS_PCIE_NORMAL_MSG_ROUTING_MASK	GENMASK(7, 5)
-#define CDNS_PCIE_NORMAL_MSG_ROUTING(route) \
-	(((route) << 5) & CDNS_PCIE_NORMAL_MSG_ROUTING_MASK)
-#define CDNS_PCIE_NORMAL_MSG_CODE_MASK		GENMASK(15, 8)
-#define CDNS_PCIE_NORMAL_MSG_CODE(code) \
-	(((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
-#define CDNS_PCIE_MSG_DATA			BIT(16)
-
 struct cdns_pcie;
 
 struct cdns_pcie_ops {
-- 
2.49.0


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

* [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA)
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
  2025-08-19 11:52 ` [PATCH v8 01/15] PCI: cadence: Add module support for platform controller driver hans.zhang
  2025-08-19 11:52 ` [PATCH v8 02/15] PCI: cadence: Split PCIe controller header file hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 17:36   ` ALOK TIWARI
  2025-08-19 11:52 ` [PATCH v8 04/15] PCI: cadence: Add helper functions for supporting " hans.zhang
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Add the register offsets and register definitions for High Performance
Architecture (HPA) PCIe controllers from Cadence.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 .../cadence/pcie-cadence-hpa-regs.h           | 182 ++++++++++++++++++
 drivers/pci/controller/cadence/pcie-cadence.h |   1 +
 2 files changed, 183 insertions(+)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h

diff --git a/drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h b/drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h
new file mode 100644
index 000000000000..01c1bd94a34d
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Manikandan K Pillai <mpillai@cadence.com>
+
+#ifndef _PCIE_CADENCE_HPA_REGS_H
+#define _PCIE_CADENCE_HPA_REGS_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-epf.h>
+#include <linux/phy/phy.h>
+#include <linux/bitfield.h>
+
+/* High Performance Architecture (HPA) PCIe controller registers */
+#define CDNS_PCIE_HPA_IP_REG_BANK		0x01000000
+#define CDNS_PCIE_HPA_IP_CFG_CTRL_REG_BANK	0x01003C00
+#define CDNS_PCIE_HPA_IP_AXI_MASTER_COMMON	0x01020000
+
+/* Address Translation Registers */
+#define CDNS_PCIE_HPA_AXI_SLAVE                 0x03000000
+#define CDNS_PCIE_HPA_AXI_MASTER                0x03002000
+
+/* Root Port register base address */
+#define CDNS_PCIE_HPA_RP_BASE			0x0
+
+#define CDNS_PCIE_HPA_LM_ID			0x1420
+
+/* Endpoint Function BARs */
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_3) ? CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG0(fn) : \
+			CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG0(pfn) (0x4000 * (pfn))
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG1(pfn) ((0x4000 * (pfn)) + 0x04)
+#define CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_3) ? CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG0(fn) : \
+			CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG0(vfn) ((0x4000 * (vfn)) + 0x08)
+#define CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG1(vfn) ((0x4000 * (vfn)) + 0x0C)
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(f) \
+	(GENMASK(9, 4) << ((f) * 10))
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+	(((a) << (4 + ((b) * 10))) & (CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b)))
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(f) \
+	(GENMASK(3, 0) << ((f) * 10))
+#define CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+	(((c) << ((b) * 10)) & (CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)))
+
+/* Endpoint Function Configuration Register */
+#define CDNS_PCIE_HPA_LM_EP_FUNC_CFG		0x02C0
+
+/* Root Complex BAR Configuration Register */
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG                        0x14
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_APERTURE_MASK     GENMASK(9, 4)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
+	FIELD_PREP(CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_APERTURE_MASK, a)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_CTRL_MASK         GENMASK(3, 0)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_CTRL(c) \
+	FIELD_PREP(CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_CTRL_MASK, c)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_APERTURE_MASK     GENMASK(19, 14)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
+	FIELD_PREP(CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_APERTURE_MASK, a)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_CTRL_MASK         GENMASK(13, 10)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_CTRL(c) \
+	FIELD_PREP(CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_CTRL_MASK, c)
+
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE BIT(20)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS BIT(21)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_IO_ENABLE           BIT(22)
+#define CDNS_PCIE_HPA_LM_RC_BAR_CFG_IO_32BITS           BIT(23)
+
+/* BAR control values applicable to both Endpoint Function and Root Complex */
+#define CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_DISABLED              0x0
+#define CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_IO_32BITS             0x3
+#define CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_32BITS            0x1
+#define CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS   0x9
+#define CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_64BITS            0x5
+#define CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS   0xD
+
+#define HPA_LM_RC_BAR_CFG_CTRL_DISABLED(bar)                \
+		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_DISABLED << ((bar) * 10))
+#define HPA_LM_RC_BAR_CFG_CTRL_IO_32BITS(bar)               \
+		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_IO_32BITS << ((bar) * 10))
+#define HPA_LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar)              \
+		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_32BITS << ((bar) * 10))
+#define HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) \
+		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS << ((bar) * 10))
+#define HPA_LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar)              \
+		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_64BITS << ((bar) * 10))
+#define HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) \
+		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS << ((bar) * 10))
+#define HPA_LM_RC_BAR_CFG_APERTURE(bar, aperture)           \
+		(((aperture) - 7) << ((bar) * 10))
+
+#define CDNS_PCIE_HPA_LM_PTM_CTRL		0x0520
+#define CDNS_PCIE_HPA_LM_TPM_CTRL_PTMRSEN	BIT(17)
+
+/* Root Port Registers PCI config space for root port function */
+#define CDNS_PCIE_HPA_RP_CAP_OFFSET	0xC0
+
+/* Region r Outbound AXI to PCIe Address Translation Register 0 */
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(r)            (0x1010 + ((r) & 0x1F) * 0x0080)
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_NBITS_MASK    GENMASK(5, 0)
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_NBITS_MASK, ((nbits) - 1))
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK    GENMASK(23, 16)
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK, devfn)
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_BUS_MASK      GENMASK(31, 24)
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_BUS_MASK, bus)
+
+/* Region r Outbound AXI to PCIe Address Translation Register 1 */
+#define CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(r)            (0x1014 + ((r) & 0x1F) * 0x0080)
+
+/* Region r Outbound PCIe Descriptor Register */
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0(r)                (0x1008 + ((r) & 0x1F) * 0x0080)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MASK         GENMASK(28, 24)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MEM  \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MASK, 0x0)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_IO   \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MASK, 0x2)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0  \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MASK, 0x4)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1  \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MASK, 0x5)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG  \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MASK, 0x10)
+
+/* Region r Outbound PCIe Descriptor Register */
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC1(r)        (0x100C + ((r) & 0x1F) * 0x0080)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS_MASK  GENMASK(31, 24)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS(bus) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS_MASK, bus)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN_MASK    GENMASK(23, 16)
+#define CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(devfn) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN_MASK, devfn)
+
+#define CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(r)         (0x1018 + ((r) & 0x1F) * 0x0080)
+#define CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_BUS BIT(26)
+#define CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN BIT(25)
+
+/* Region r AXI Region Base Address Register 0 */
+#define CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(r)     (0x1000 + ((r) & 0x1F) * 0x0080)
+#define CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS_MASK    GENMASK(5, 0)
+#define CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS_MASK, ((nbits) - 1))
+
+/* Region r AXI Region Base Address Register 1 */
+#define CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(r)     (0x1004 + ((r) & 0x1F) * 0x0080)
+
+/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR0(bar)              (((bar) * 0x0008))
+#define CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR0_NBITS_MASK        GENMASK(5, 0)
+#define CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \
+	FIELD_PREP(CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR0_NBITS_MASK, ((nbits) - 1))
+#define CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR1(bar)              (0x04 + ((bar) * 0x0008))
+
+/* AXI link down register */
+#define CDNS_PCIE_HPA_AT_LINKDOWN 0x04
+
+/*
+ * Physical Layer Configuration Register 0
+ * This register contains the parameters required for functional setup
+ * of Physical Layer.
+ */
+#define CDNS_PCIE_HPA_PHY_LAYER_CFG0               0x0400
+#define CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY_MASK  GENMASK(26, 24)
+#define CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY(delay) \
+	FIELD_PREP(CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY_MASK, delay)
+#define CDNS_PCIE_HPA_LINK_TRNG_EN_MASK  GENMASK(27, 27)
+
+#define CDNS_PCIE_HPA_PHY_DBG_STS_REG0             0x0420
+
+#define CDNS_PCIE_HPA_RP_MAX_IB     0x3
+#define CDNS_PCIE_HPA_MAX_OB        15
+
+/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_HPA_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) (((fn) * 0x0040) + ((bar) * 0x0008))
+#define CDNS_PCIE_HPA_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) (0x4 + ((fn) * 0x0040) + ((bar) * 0x0008))
+
+#endif /* _PCIE_CADENCE_HPA_REGS_H */
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 79df86117fde..ddfc44f8d3ef 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -11,6 +11,7 @@
 #include <linux/pci-epf.h>
 #include <linux/phy/phy.h>
 #include "pcie-cadence-lga-regs.h"
+#include "pcie-cadence-hpa-regs.h"
 
 enum cdns_pcie_rp_bar {
 	RP_BAR_UNDEFINED = -1,
-- 
2.49.0


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

* [PATCH v8 04/15] PCI: cadence: Add helper functions for supporting High Perf Architecture (HPA)
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (2 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA) hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 11:52 ` [PATCH v8 05/15] PCI: cadence: Move PCIe EP common functions to a separate file hans.zhang
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Add helper functions, register read, register write functions and update
platform data structures for supporting High Performance Architecture
(HPA) PCIe controllers from Cadence.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 .../controller/cadence/pcie-cadence-plat.c    |   4 -
 drivers/pci/controller/cadence/pcie-cadence.h | 111 ++++++++++++++++--
 2 files changed, 103 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index ebd5c3afdfcd..b067a3296dd3 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -22,10 +22,6 @@ struct cdns_plat_pcie {
 	struct cdns_pcie        *pcie;
 };
 
-struct cdns_plat_pcie_of_data {
-	bool is_rc;
-};
-
 static const struct of_device_id cdns_plat_pcie_of_match[];
 
 static u64 cdns_plat_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index ddfc44f8d3ef..1174cf597bb0 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -26,6 +26,20 @@ struct cdns_pcie_rp_ib_bar {
 };
 
 struct cdns_pcie;
+struct cdns_pcie_rc;
+
+enum cdns_pcie_reg_bank {
+	REG_BANK_RP,
+	REG_BANK_IP_REG,
+	REG_BANK_IP_CFG_CTRL_REG,
+	REG_BANK_AXI_MASTER_COMMON,
+	REG_BANK_AXI_MASTER,
+	REG_BANK_AXI_SLAVE,
+	REG_BANK_AXI_HLS,
+	REG_BANK_AXI_RAS,
+	REG_BANK_AXI_DTI,
+	REG_BANKS_MAX,
+};
 
 struct cdns_pcie_ops {
 	int	(*start_link)(struct cdns_pcie *pcie);
@@ -34,6 +48,30 @@ struct cdns_pcie_ops {
 	u64     (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
 };
 
+/**
+ * struct cdns_plat_pcie_of_data - Register bank offset for a platform
+ * @is_rc: controller is a RC
+ * @ip_reg_bank_offset: ip register bank start offset
+ * @ip_cfg_ctrl_reg_offset: ip config control register start offset
+ * @axi_mstr_common_offset: AXI master common register start offset
+ * @axi_slave_offset: AXI slave start offset
+ * @axi_master_offset: AXI master start offset
+ * @axi_hls_offset: AXI HLS offset start
+ * @axi_ras_offset: AXI RAS offset
+ * @axi_dti_offset: AXI DTI offset
+ */
+struct cdns_plat_pcie_of_data {
+	u32 is_rc:1;
+	u32 ip_reg_bank_offset;
+	u32 ip_cfg_ctrl_reg_offset;
+	u32 axi_mstr_common_offset;
+	u32 axi_slave_offset;
+	u32 axi_master_offset;
+	u32 axi_hls_offset;
+	u32 axi_ras_offset;
+	u32 axi_dti_offset;
+};
+
 /**
  * struct cdns_pcie - private data for Cadence PCIe controller drivers
  * @reg_base: IO mapped register base
@@ -45,16 +83,18 @@ struct cdns_pcie_ops {
  * @link: list of pointers to corresponding device link representations
  * @ops: Platform-specific ops to control various inputs from Cadence PCIe
  *       wrapper
+ * @cdns_pcie_reg_offsets: Register bank offsets for different SoC
  */
 struct cdns_pcie {
-	void __iomem		*reg_base;
-	struct resource		*mem_res;
-	struct device		*dev;
-	bool			is_rc;
-	int			phy_count;
-	struct phy		**phy;
-	struct device_link	**link;
-	const struct cdns_pcie_ops *ops;
+	void __iomem		             *reg_base;
+	struct resource		             *mem_res;
+	struct device		             *dev;
+	bool			             is_rc;
+	int			             phy_count;
+	struct phy		             **phy;
+	struct device_link	             **link;
+	const  struct cdns_pcie_ops          *ops;
+	const  struct cdns_plat_pcie_of_data *cdns_pcie_reg_offsets;
 };
 
 /**
@@ -132,6 +172,40 @@ struct cdns_pcie_ep {
 	unsigned int		quirk_disable_flr:1;
 };
 
+static inline u32 cdns_reg_bank_to_off(struct cdns_pcie *pcie, enum cdns_pcie_reg_bank bank)
+{
+	u32 offset = 0x0;
+
+	switch (bank) {
+	case REG_BANK_IP_REG:
+		offset = pcie->cdns_pcie_reg_offsets->ip_reg_bank_offset;
+		break;
+	case REG_BANK_IP_CFG_CTRL_REG:
+		offset = pcie->cdns_pcie_reg_offsets->ip_cfg_ctrl_reg_offset;
+		break;
+	case REG_BANK_AXI_MASTER_COMMON:
+		offset = pcie->cdns_pcie_reg_offsets->axi_mstr_common_offset;
+		break;
+	case REG_BANK_AXI_MASTER:
+		offset = pcie->cdns_pcie_reg_offsets->axi_master_offset;
+		break;
+	case REG_BANK_AXI_SLAVE:
+		offset = pcie->cdns_pcie_reg_offsets->axi_slave_offset;
+		break;
+	case REG_BANK_AXI_HLS:
+		offset = pcie->cdns_pcie_reg_offsets->axi_hls_offset;
+		break;
+	case REG_BANK_AXI_RAS:
+		offset = pcie->cdns_pcie_reg_offsets->axi_ras_offset;
+		break;
+	case REG_BANK_AXI_DTI:
+		offset = pcie->cdns_pcie_reg_offsets->axi_dti_offset;
+		break;
+	default:
+		break;
+	};
+	return offset;
+}
 
 /* Register access */
 static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
@@ -144,6 +218,27 @@ static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
 	return readl(pcie->reg_base + reg);
 }
 
+static inline void cdns_pcie_hpa_writel(struct cdns_pcie *pcie,
+					enum cdns_pcie_reg_bank bank,
+					u32 reg,
+					u32 value)
+{
+	u32 offset = cdns_reg_bank_to_off(pcie, bank);
+
+	reg += offset;
+	writel(value, pcie->reg_base + reg);
+}
+
+static inline u32 cdns_pcie_hpa_readl(struct cdns_pcie *pcie,
+				      enum cdns_pcie_reg_bank bank,
+				      u32 reg)
+{
+	u32 offset = cdns_reg_bank_to_off(pcie, bank);
+
+	reg += offset;
+	return readl(pcie->reg_base + reg);
+}
+
 static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size)
 {
 	void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
-- 
2.49.0


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

* [PATCH v8 05/15] PCI: cadence: Move PCIe EP common functions to a separate file
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (3 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 04/15] PCI: cadence: Add helper functions for supporting " hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 17:46   ` ALOK TIWARI
  2025-08-19 11:52 ` [PATCH v8 06/15] PCI: cadence: Move PCIe RP " hans.zhang
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Move the Cadence PCIe controller EP common functions into a separate
file. The common library functions are split from legacy PCIe EP controller
functions.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 drivers/pci/controller/cadence/Makefile       |   2 +-
 .../cadence/pcie-cadence-ep-common.c          | 251 ++++++++++++++++++
 .../cadence/pcie-cadence-ep-common.h          |  36 +++
 .../pci/controller/cadence/pcie-cadence-ep.c  | 233 +---------------
 4 files changed, 289 insertions(+), 233 deletions(-)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-common.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-common.h

diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index 9bac5fb2f13d..80c1c4be7e80 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
 obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
-obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
+obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep-common.c b/drivers/pci/controller/cadence/pcie-cadence-ep-common.c
new file mode 100644
index 000000000000..2a3f01aacc46
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep-common.c
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe endpoint controller driver common
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/sizes.h>
+
+#include "pcie-cadence.h"
+#include "pcie-cadence-ep-common.h"
+
+u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn)
+{
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
+	u32 first_vf_offset, stride;
+
+	if (vfn == 0)
+		return fn;
+
+	first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET);
+	stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +  PCI_SRIOV_VF_STRIDE);
+	fn = fn + first_vf_offset + ((vfn - 1) * stride);
+
+	return fn;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_get_fn_from_vfn);
+
+int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
+			      struct pci_epf_header *hdr)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 reg;
+
+	if (vfn > 1) {
+		dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n");
+		return -EINVAL;
+	} else if (vfn == 1) {
+		reg = cap + PCI_SRIOV_VF_DID;
+		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
+		return 0;
+	}
+
+	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CLASS_PROG, hdr->progif_code);
+	cdns_pcie_ep_fn_writew(pcie, fn, PCI_CLASS_DEVICE,
+			       hdr->subclass_code | hdr->baseclass_code << 8);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CACHE_LINE_SIZE,
+			       hdr->cache_line_size);
+	cdns_pcie_ep_fn_writew(pcie, fn, PCI_SUBSYSTEM_ID, hdr->subsys_id);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_INTERRUPT_PIN, hdr->interrupt_pin);
+
+	/*
+	 * Vendor ID can only be modified from function 0, all other functions
+	 * use the same vendor ID as function 0.
+	 */
+	if (fn == 0) {
+		/* Update the vendor IDs. */
+		u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) |
+			 CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id);
+
+		cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_write_header);
+
+int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u16 flags;
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
+	/*
+	 * Set the Multiple Message Capable bitfield into the Message Control
+	 * register.
+	 */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	flags = (flags & ~PCI_MSI_FLAGS_QMASK) | (mmc << 1);
+	flags |= PCI_MSI_FLAGS_64BIT;
+	flags &= ~PCI_MSI_FLAGS_MASKBIT;
+	cdns_pcie_ep_fn_writew(pcie, fn, cap + PCI_MSI_FLAGS, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_set_msi);
+
+int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u16 flags, mme;
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
+	/* Validate that the MSI feature is actually enabled. */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	if (!(flags & PCI_MSI_FLAGS_ENABLE))
+		return -EINVAL;
+
+	/*
+	 * Get the Multiple Message Enable bitfield from the Message Control
+	 * register.
+	 */
+	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
+
+	return mme;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_get_msi);
+
+int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+	u32 val, reg;
+
+	func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no);
+
+	reg = cap + PCI_MSIX_FLAGS;
+	val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
+	if (!(val & PCI_MSIX_FLAGS_ENABLE))
+		return -EINVAL;
+
+	val &= PCI_MSIX_FLAGS_QSIZE;
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_get_msix);
+
+int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
+			  u16 interrupts, enum pci_barno bir,
+			  u32 offset)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+	u32 val, reg;
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
+	reg = cap + PCI_MSIX_FLAGS;
+	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
+	val &= ~PCI_MSIX_FLAGS_QSIZE;
+	val |= interrupts;
+	cdns_pcie_ep_fn_writew(pcie, fn, reg, val);
+
+	/* Set MSI-X BAR and offset */
+	reg = cap + PCI_MSIX_TABLE;
+	val = offset | bir;
+	cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
+
+	/* Set PBA BAR and offset.  BAR must match MSI-X BAR */
+	reg = cap + PCI_MSIX_PBA;
+	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
+	cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_set_msix);
+
+int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
+			     phys_addr_t addr, u8 interrupt_num,
+			     u32 entry_size, u32 *msi_data,
+			     u32 *msi_addr_offset)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	struct cdns_pcie *pcie = &ep->pcie;
+	u64 pci_addr, pci_addr_mask = 0xff;
+	u16 flags, mme, data, data_mask;
+	u8 msi_count;
+	int ret;
+	int i;
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
+	/* Check whether the MSI feature has been enabled by the PCI host. */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	if (!(flags & PCI_MSI_FLAGS_ENABLE))
+		return -EINVAL;
+
+	/* Get the number of enabled MSIs */
+	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
+	msi_count = 1 << mme;
+	if (!interrupt_num || interrupt_num > msi_count)
+		return -EINVAL;
+
+	/* Compute the data value to be written. */
+	data_mask = msi_count - 1;
+	data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
+	data = data & ~data_mask;
+
+	/* Get the PCI address where to write the data into. */
+	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
+	pci_addr <<= 32;
+	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
+	pci_addr &= GENMASK_ULL(63, 2);
+
+	for (i = 0; i < interrupt_num; i++) {
+		ret = epc->ops->map_addr(epc, fn, vfn, addr,
+					 pci_addr & ~pci_addr_mask,
+					 entry_size);
+		if (ret)
+			return ret;
+		addr = addr + entry_size;
+	}
+
+	*msi_data = data;
+	*msi_addr_offset = pci_addr & pci_addr_mask;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_map_msi_irq);
+
+static const struct pci_epc_features cdns_pcie_epc_vf_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = true,
+	.align = 65536,
+};
+
+static const struct pci_epc_features cdns_pcie_epc_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = true,
+	.align = 256,
+};
+
+const struct pci_epc_features*
+cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
+{
+	if (!vfunc_no)
+		return &cdns_pcie_epc_features;
+
+	return &cdns_pcie_epc_vf_features;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_ep_get_features);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller driver");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep-common.h b/drivers/pci/controller/cadence/pcie-cadence-ep-common.h
new file mode 100644
index 000000000000..9bc9f4b52427
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep-common.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2017 Cadence
+// Cadence PCIe Endpoint controller driver
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#ifndef _PCIE_CADENCE_EP_COMMON_H
+#define _PCIE_CADENCE_EP_COMMON_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-epf.h>
+#include <linux/pci-epc.h>
+#include "../../pci.h"
+
+#define CDNS_PCIE_EP_MIN_APERTURE		128	/* 128 bytes */
+#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
+#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
+
+u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn);
+int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
+			      struct pci_epf_header *hdr);
+int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc);
+int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn);
+int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
+			  u16 interrupts, enum pci_barno bir,
+			  u32 offset);
+int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
+			     phys_addr_t addr, u8 interrupt_num,
+			     u32 entry_size, u32 *msi_data,
+			     u32 *msi_addr_offset);
+const struct pci_epc_features *cdns_pcie_ep_get_features(struct pci_epc *epc,
+							 u8 func_no,
+							 u8 vfunc_no);
+
+#endif /* _PCIE_CADENCE_EP_COMMON_H */
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 77c5a19b2ab1..747d83ed2ad3 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -13,68 +13,7 @@
 #include <linux/sizes.h>
 
 #include "pcie-cadence.h"
-#include "../../pci.h"
-
-#define CDNS_PCIE_EP_MIN_APERTURE		128	/* 128 bytes */
-#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
-#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
-
-static u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn)
-{
-	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
-	u32 first_vf_offset, stride;
-
-	if (vfn == 0)
-		return fn;
-
-	first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET);
-	stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +  PCI_SRIOV_VF_STRIDE);
-	fn = fn + first_vf_offset + ((vfn - 1) * stride);
-
-	return fn;
-}
-
-static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
-				     struct pci_epf_header *hdr)
-{
-	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
-	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
-	struct cdns_pcie *pcie = &ep->pcie;
-	u32 reg;
-
-	if (vfn > 1) {
-		dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n");
-		return -EINVAL;
-	} else if (vfn == 1) {
-		reg = cap + PCI_SRIOV_VF_DID;
-		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
-		return 0;
-	}
-
-	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
-	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
-	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CLASS_PROG, hdr->progif_code);
-	cdns_pcie_ep_fn_writew(pcie, fn, PCI_CLASS_DEVICE,
-			       hdr->subclass_code | hdr->baseclass_code << 8);
-	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CACHE_LINE_SIZE,
-			       hdr->cache_line_size);
-	cdns_pcie_ep_fn_writew(pcie, fn, PCI_SUBSYSTEM_ID, hdr->subsys_id);
-	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_INTERRUPT_PIN, hdr->interrupt_pin);
-
-	/*
-	 * Vendor ID can only be modified from function 0, all other functions
-	 * use the same vendor ID as function 0.
-	 */
-	if (fn == 0) {
-		/* Update the vendor IDs. */
-		u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) |
-			 CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id);
-
-		cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id);
-	}
-
-	return 0;
-}
+#include "pcie-cadence-ep-common.h"
 
 static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				struct pci_epf_bar *epf_bar)
@@ -222,100 +161,6 @@ static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 nr_irqs)
-{
-	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
-	struct cdns_pcie *pcie = &ep->pcie;
-	u8 mmc = order_base_2(nr_irqs);
-	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
-	u16 flags;
-
-	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
-
-	/*
-	 * Set the Multiple Message Capable bitfield into the Message Control
-	 * register.
-	 */
-	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
-	flags = (flags & ~PCI_MSI_FLAGS_QMASK) | (mmc << 1);
-	flags |= PCI_MSI_FLAGS_64BIT;
-	flags &= ~PCI_MSI_FLAGS_MASKBIT;
-	cdns_pcie_ep_fn_writew(pcie, fn, cap + PCI_MSI_FLAGS, flags);
-
-	return 0;
-}
-
-static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
-{
-	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
-	struct cdns_pcie *pcie = &ep->pcie;
-	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
-	u16 flags, mme;
-
-	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
-
-	/* Validate that the MSI feature is actually enabled. */
-	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
-	if (!(flags & PCI_MSI_FLAGS_ENABLE))
-		return -EINVAL;
-
-	/*
-	 * Get the Multiple Message Enable bitfield from the Message Control
-	 * register.
-	 */
-	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
-
-	return 1 << mme;
-}
-
-static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
-{
-	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
-	struct cdns_pcie *pcie = &ep->pcie;
-	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
-	u32 val, reg;
-
-	func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no);
-
-	reg = cap + PCI_MSIX_FLAGS;
-	val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
-	if (!(val & PCI_MSIX_FLAGS_ENABLE))
-		return -EINVAL;
-
-	val &= PCI_MSIX_FLAGS_QSIZE;
-
-	return val + 1;
-}
-
-static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
-				 u16 nr_irqs, enum pci_barno bir, u32 offset)
-{
-	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
-	struct cdns_pcie *pcie = &ep->pcie;
-	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
-	u32 val, reg;
-
-	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
-
-	reg = cap + PCI_MSIX_FLAGS;
-	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
-	val &= ~PCI_MSIX_FLAGS_QSIZE;
-	val |= nr_irqs - 1; /* encoded as N-1 */
-	cdns_pcie_ep_fn_writew(pcie, fn, reg, val);
-
-	/* Set MSI-X BAR and offset */
-	reg = cap + PCI_MSIX_TABLE;
-	val = offset | bir;
-	cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
-
-	/* Set PBA BAR and offset.  BAR must match MSI-X BAR */
-	reg = cap + PCI_MSIX_PBA;
-	val = (offset + (nr_irqs * PCI_MSIX_ENTRY_SIZE)) | bir;
-	cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
-
-	return 0;
-}
-
 static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
 				     bool is_asserted)
 {
@@ -426,59 +271,6 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	return 0;
 }
 
-static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
-				    phys_addr_t addr, u8 interrupt_num,
-				    u32 entry_size, u32 *msi_data,
-				    u32 *msi_addr_offset)
-{
-	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
-	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
-	struct cdns_pcie *pcie = &ep->pcie;
-	u64 pci_addr, pci_addr_mask = 0xff;
-	u16 flags, mme, data, data_mask;
-	u8 msi_count;
-	int ret;
-	int i;
-
-	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
-
-	/* Check whether the MSI feature has been enabled by the PCI host. */
-	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
-	if (!(flags & PCI_MSI_FLAGS_ENABLE))
-		return -EINVAL;
-
-	/* Get the number of enabled MSIs */
-	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
-	msi_count = 1 << mme;
-	if (!interrupt_num || interrupt_num > msi_count)
-		return -EINVAL;
-
-	/* Compute the data value to be written. */
-	data_mask = msi_count - 1;
-	data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
-	data = data & ~data_mask;
-
-	/* Get the PCI address where to write the data into. */
-	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
-	pci_addr <<= 32;
-	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
-	pci_addr &= GENMASK_ULL(63, 2);
-
-	for (i = 0; i < interrupt_num; i++) {
-		ret = cdns_pcie_ep_map_addr(epc, fn, vfn, addr,
-					    pci_addr & ~pci_addr_mask,
-					    entry_size);
-		if (ret)
-			return ret;
-		addr = addr + entry_size;
-	}
-
-	*msi_data = data;
-	*msi_addr_offset = pci_addr & pci_addr_mask;
-
-	return 0;
-}
-
 static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				      u16 interrupt_num)
 {
@@ -607,29 +399,6 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
 	return 0;
 }
 
-static const struct pci_epc_features cdns_pcie_epc_vf_features = {
-	.linkup_notifier = false,
-	.msi_capable = true,
-	.msix_capable = true,
-	.align = 65536,
-};
-
-static const struct pci_epc_features cdns_pcie_epc_features = {
-	.linkup_notifier = false,
-	.msi_capable = true,
-	.msix_capable = true,
-	.align = 256,
-};
-
-static const struct pci_epc_features*
-cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
-{
-	if (!vfunc_no)
-		return &cdns_pcie_epc_features;
-
-	return &cdns_pcie_epc_vf_features;
-}
-
 static const struct pci_epc_ops cdns_pcie_epc_ops = {
 	.write_header	= cdns_pcie_ep_write_header,
 	.set_bar	= cdns_pcie_ep_set_bar,
-- 
2.49.0


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

* [PATCH v8 06/15] PCI: cadence: Move PCIe RP common functions to a separate file
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (4 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 05/15] PCI: cadence: Move PCIe EP common functions to a separate file hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-30 10:36   ` Manivannan Sadhasivam
  2025-08-19 11:52 ` [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as " hans.zhang
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Move the Cadence PCIe controller RP common functions into a separate
file. The common library functions are split from legacy PCIe RP controller
functions to a separate file.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 drivers/pci/controller/cadence/Makefile       |   2 +-
 .../cadence/pcie-cadence-host-common.c        | 179 ++++++++++++++++++
 .../cadence/pcie-cadence-host-common.h        |  24 +++
 .../controller/cadence/pcie-cadence-host.c    | 156 +--------------
 4 files changed, 205 insertions(+), 156 deletions(-)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.h

diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index 80c1c4be7e80..e45f72388bbb 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
-obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
+obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
new file mode 100644
index 000000000000..d34f8c7c49f0
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe host controller driver.
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/list_sort.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-cadence.h"
+#include "pcie-cadence-host-common.h"
+
+#define LINK_RETRAIN_TIMEOUT HZ
+
+u64 bar_max_size[] = {
+	[RP_BAR0] = _ULL(128 * SZ_2G),
+	[RP_BAR1] = SZ_2G,
+	[RP_NO_BAR] = _BITULL(63),
+};
+EXPORT_SYMBOL_GPL(bar_max_size);
+
+int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
+{
+	u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
+	unsigned long end_jiffies;
+	u16 lnk_stat;
+
+	/* Wait for link training to complete. Exit after timeout. */
+	end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
+	do {
+		lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
+		if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
+			break;
+		usleep_range(0, 1000);
+	} while (time_before(jiffies, end_jiffies));
+
+	if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
+		return 0;
+
+	return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_host_training_complete);
+
+int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
+{
+	struct device *dev = pcie->dev;
+	int retries;
+
+	/* Check if the link is up or not */
+	for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+		if (cdns_pcie_link_up(pcie)) {
+			dev_info(dev, "Link up\n");
+			return 0;
+		}
+		usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+	}
+
+	return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_host_wait_for_link);
+
+int cdns_pcie_retrain(struct cdns_pcie *pcie)
+{
+	u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
+	u16 lnk_stat, lnk_ctl;
+	int ret = 0;
+
+	/*
+	 * Set retrain bit if current speed is 2.5 GB/s,
+	 * but the PCIe root port support is > 2.5 GB/s.
+	 */
+
+	lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + pcie_cap_off +
+					     PCI_EXP_LNKCAP));
+	if ((lnk_cap_sls & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
+		return ret;
+
+	lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
+	if ((lnk_stat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
+		lnk_ctl = cdns_pcie_rp_readw(pcie,
+					     pcie_cap_off + PCI_EXP_LNKCTL);
+		lnk_ctl |= PCI_EXP_LNKCTL_RL;
+		cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
+				    lnk_ctl);
+
+		ret = cdns_pcie_host_training_complete(pcie);
+		if (ret)
+			return ret;
+
+		ret = cdns_pcie_host_wait_for_link(pcie);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_retrain);
+
+int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	int ret;
+
+	ret = cdns_pcie_host_wait_for_link(pcie);
+
+	/*
+	 * Retrain link for Gen2 training defect
+	 * if quirk flag is set.
+	 */
+	if (!ret && rc->quirk_retrain_flag)
+		ret = cdns_pcie_retrain(pcie);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_host_start_link);
+
+enum cdns_pcie_rp_bar
+cdns_pcie_host_find_min_bar(struct cdns_pcie_rc *rc, u64 size)
+{
+	enum cdns_pcie_rp_bar bar, sel_bar;
+
+	sel_bar = RP_BAR_UNDEFINED;
+	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) {
+		if (!rc->avail_ib_bar[bar])
+			continue;
+
+		if (size <= bar_max_size[bar]) {
+			if (sel_bar == RP_BAR_UNDEFINED) {
+				sel_bar = bar;
+				continue;
+			}
+
+			if (bar_max_size[bar] < bar_max_size[sel_bar])
+				sel_bar = bar;
+		}
+	}
+
+	return sel_bar;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_host_find_min_bar);
+
+enum cdns_pcie_rp_bar
+cdns_pcie_host_find_max_bar(struct cdns_pcie_rc *rc, u64 size)
+{
+	enum cdns_pcie_rp_bar bar, sel_bar;
+
+	sel_bar = RP_BAR_UNDEFINED;
+	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) {
+		if (!rc->avail_ib_bar[bar])
+			continue;
+
+		if (size >= bar_max_size[bar]) {
+			if (sel_bar == RP_BAR_UNDEFINED) {
+				sel_bar = bar;
+				continue;
+			}
+
+			if (bar_max_size[bar] > bar_max_size[sel_bar])
+				sel_bar = bar;
+		}
+	}
+
+	return sel_bar;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_host_find_max_bar);
+
+int cdns_pcie_host_dma_ranges_cmp(void *priv, const struct list_head *a,
+				  const struct list_head *b)
+{
+	struct resource_entry *entry1, *entry2;
+
+	entry1 = container_of(a, struct resource_entry, node);
+	entry2 = container_of(b, struct resource_entry, node);
+
+	return resource_size(entry2->res) - resource_size(entry1->res);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_host_dma_ranges_cmp);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller driver");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.h b/drivers/pci/controller/cadence/pcie-cadence-host-common.h
new file mode 100644
index 000000000000..7eaa853fdb5f
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2017 Cadence
+// Cadence PCIe Endpoint controller driver
+
+#ifndef _PCIE_CADENCE_HOST_COMMON_H
+#define _PCIE_CADENCE_HOST_COMMON_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+extern u64 bar_max_size[];
+
+int cdns_pcie_host_training_complete(struct cdns_pcie *pcie);
+int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie);
+int cdns_pcie_retrain(struct cdns_pcie *pcie);
+int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc);
+enum cdns_pcie_rp_bar
+cdns_pcie_host_find_min_bar(struct cdns_pcie_rc *rc, u64 size);
+enum cdns_pcie_rp_bar
+cdns_pcie_host_find_max_bar(struct cdns_pcie_rc *rc, u64 size);
+int cdns_pcie_host_dma_ranges_cmp(void *priv, const struct list_head *a,
+				  const struct list_head *b);
+
+#endif /* _PCIE_CADENCE_HOST_COMMON_H */
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 59a4631de79f..bfdd0f200cfb 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -12,14 +12,7 @@
 #include <linux/platform_device.h>
 
 #include "pcie-cadence.h"
-
-#define LINK_RETRAIN_TIMEOUT HZ
-
-static u64 bar_max_size[] = {
-	[RP_BAR0] = _ULL(128 * SZ_2G),
-	[RP_BAR1] = SZ_2G,
-	[RP_NO_BAR] = _BITULL(63),
-};
+#include "pcie-cadence-host-common.h"
 
 static u8 bar_aperture_mask[] = {
 	[RP_BAR0] = 0x1F,
@@ -81,77 +74,6 @@ static struct pci_ops cdns_pcie_host_ops = {
 	.write		= pci_generic_config_write,
 };
 
-static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
-{
-	u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
-	unsigned long end_jiffies;
-	u16 lnk_stat;
-
-	/* Wait for link training to complete. Exit after timeout. */
-	end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
-	do {
-		lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
-		if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
-			break;
-		usleep_range(0, 1000);
-	} while (time_before(jiffies, end_jiffies));
-
-	if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
-		return 0;
-
-	return -ETIMEDOUT;
-}
-
-static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
-{
-	struct device *dev = pcie->dev;
-	int retries;
-
-	/* Check if the link is up or not */
-	for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
-		if (cdns_pcie_link_up(pcie)) {
-			dev_info(dev, "Link up\n");
-			return 0;
-		}
-		usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int cdns_pcie_retrain(struct cdns_pcie *pcie)
-{
-	u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
-	u16 lnk_stat, lnk_ctl;
-	int ret = 0;
-
-	/*
-	 * Set retrain bit if current speed is 2.5 GB/s,
-	 * but the PCIe root port support is > 2.5 GB/s.
-	 */
-
-	lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + pcie_cap_off +
-					     PCI_EXP_LNKCAP));
-	if ((lnk_cap_sls & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
-		return ret;
-
-	lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
-	if ((lnk_stat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
-		lnk_ctl = cdns_pcie_rp_readw(pcie,
-					     pcie_cap_off + PCI_EXP_LNKCTL);
-		lnk_ctl |= PCI_EXP_LNKCTL_RL;
-		cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
-				    lnk_ctl);
-
-		ret = cdns_pcie_host_training_complete(pcie);
-		if (ret)
-			return ret;
-
-		ret = cdns_pcie_host_wait_for_link(pcie);
-	}
-	return ret;
-}
-
 static void cdns_pcie_host_disable_ptm_response(struct cdns_pcie *pcie)
 {
 	u32 val;
@@ -168,23 +90,6 @@ static void cdns_pcie_host_enable_ptm_response(struct cdns_pcie *pcie)
 	cdns_pcie_writel(pcie, CDNS_PCIE_LM_PTM_CTRL, val | CDNS_PCIE_LM_TPM_CTRL_PTMRSEN);
 }
 
-static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc)
-{
-	struct cdns_pcie *pcie = &rc->pcie;
-	int ret;
-
-	ret = cdns_pcie_host_wait_for_link(pcie);
-
-	/*
-	 * Retrain link for Gen2 training defect
-	 * if quirk flag is set.
-	 */
-	if (!ret && rc->quirk_retrain_flag)
-		ret = cdns_pcie_retrain(pcie);
-
-	return ret;
-}
-
 static void cdns_pcie_host_deinit_root_port(struct cdns_pcie_rc *rc)
 {
 	struct cdns_pcie *pcie = &rc->pcie;
@@ -290,54 +195,6 @@ static int cdns_pcie_host_bar_ib_config(struct cdns_pcie_rc *rc,
 	return 0;
 }
 
-static enum cdns_pcie_rp_bar
-cdns_pcie_host_find_min_bar(struct cdns_pcie_rc *rc, u64 size)
-{
-	enum cdns_pcie_rp_bar bar, sel_bar;
-
-	sel_bar = RP_BAR_UNDEFINED;
-	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) {
-		if (!rc->avail_ib_bar[bar])
-			continue;
-
-		if (size <= bar_max_size[bar]) {
-			if (sel_bar == RP_BAR_UNDEFINED) {
-				sel_bar = bar;
-				continue;
-			}
-
-			if (bar_max_size[bar] < bar_max_size[sel_bar])
-				sel_bar = bar;
-		}
-	}
-
-	return sel_bar;
-}
-
-static enum cdns_pcie_rp_bar
-cdns_pcie_host_find_max_bar(struct cdns_pcie_rc *rc, u64 size)
-{
-	enum cdns_pcie_rp_bar bar, sel_bar;
-
-	sel_bar = RP_BAR_UNDEFINED;
-	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) {
-		if (!rc->avail_ib_bar[bar])
-			continue;
-
-		if (size >= bar_max_size[bar]) {
-			if (sel_bar == RP_BAR_UNDEFINED) {
-				sel_bar = bar;
-				continue;
-			}
-
-			if (bar_max_size[bar] > bar_max_size[sel_bar])
-				sel_bar = bar;
-		}
-	}
-
-	return sel_bar;
-}
-
 static int cdns_pcie_host_bar_config(struct cdns_pcie_rc *rc,
 				     struct resource_entry *entry)
 {
@@ -410,17 +267,6 @@ static int cdns_pcie_host_bar_config(struct cdns_pcie_rc *rc,
 	return 0;
 }
 
-static int cdns_pcie_host_dma_ranges_cmp(void *priv, const struct list_head *a,
-					 const struct list_head *b)
-{
-	struct resource_entry *entry1, *entry2;
-
-        entry1 = container_of(a, struct resource_entry, node);
-        entry2 = container_of(b, struct resource_entry, node);
-
-        return resource_size(entry2->res) - resource_size(entry1->res);
-}
-
 static void cdns_pcie_host_unmap_dma_ranges(struct cdns_pcie_rc *rc)
 {
 	struct cdns_pcie *pcie = &rc->pcie;
-- 
2.49.0


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

* [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as a separate file
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (5 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 06/15] PCI: cadence: Move PCIe RP " hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-30 11:21   ` Manivannan Sadhasivam
  2025-08-19 11:52 ` [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller hans.zhang
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Move the functions for platform common tasks to a separate file. The
common library functions and functions specific to platform are
now in different files.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 drivers/pci/controller/cadence/Makefile       |   2 +-
 .../controller/cadence/pcie-cadence-common.c  | 141 ++++++++++++++++++
 drivers/pci/controller/cadence/pcie-cadence.c | 129 ----------------
 3 files changed, 142 insertions(+), 130 deletions(-)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-common.c

diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index e45f72388bbb..b104562fb86a 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
+obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
 obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
diff --git a/drivers/pci/controller/cadence/pcie-cadence-common.c b/drivers/pci/controller/cadence/pcie-cadence-common.c
new file mode 100644
index 000000000000..e14d53d64bf1
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-common.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "pcie-cadence.h"
+
+void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
+{
+	int i = pcie->phy_count;
+
+	while (i--) {
+		phy_power_off(pcie->phy[i]);
+		phy_exit(pcie->phy[i]);
+	}
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_disable_phy);
+
+int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < pcie->phy_count; i++) {
+		ret = phy_init(pcie->phy[i]);
+		if (ret < 0)
+			goto err_phy;
+
+		ret = phy_power_on(pcie->phy[i]);
+		if (ret < 0) {
+			phy_exit(pcie->phy[i]);
+			goto err_phy;
+		}
+	}
+
+	return 0;
+
+err_phy:
+	while (--i >= 0) {
+		phy_power_off(pcie->phy[i]);
+		phy_exit(pcie->phy[i]);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_enable_phy);
+
+int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
+{
+	struct device_node *np = dev->of_node;
+	int phy_count;
+	struct phy **phy;
+	struct device_link **link;
+	int i;
+	int ret;
+	const char *name;
+
+	phy_count = of_property_count_strings(np, "phy-names");
+	if (phy_count < 1) {
+		dev_info(dev, "no \"phy-names\" property found; PHY will not be initialized\n");
+		pcie->phy_count = 0;
+		return 0;
+	}
+
+	phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL);
+	if (!link)
+		return -ENOMEM;
+
+	for (i = 0; i < phy_count; i++) {
+		of_property_read_string_index(np, "phy-names", i, &name);
+		phy[i] = devm_phy_get(dev, name);
+		if (IS_ERR(phy[i])) {
+			ret = PTR_ERR(phy[i]);
+			goto err_phy;
+		}
+		link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
+		if (!link[i]) {
+			devm_phy_put(dev, phy[i]);
+			ret = -EINVAL;
+			goto err_phy;
+		}
+	}
+
+	pcie->phy_count = phy_count;
+	pcie->phy = phy;
+	pcie->link = link;
+
+	ret =  cdns_pcie_enable_phy(pcie);
+	if (ret)
+		goto err_phy;
+
+	return 0;
+
+err_phy:
+	while (--i >= 0) {
+		device_link_del(link[i]);
+		devm_phy_put(dev, phy[i]);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_init_phy);
+
+static int cdns_pcie_suspend_noirq(struct device *dev)
+{
+	struct cdns_pcie *pcie = dev_get_drvdata(dev);
+
+	cdns_pcie_disable_phy(pcie);
+
+	return 0;
+}
+
+static int cdns_pcie_resume_noirq(struct device *dev)
+{
+	struct cdns_pcie *pcie = dev_get_drvdata(dev);
+	int ret;
+
+	ret = cdns_pcie_enable_phy(pcie);
+	if (ret) {
+		dev_err(dev, "failed to enable PHY\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+const struct dev_pm_ops cdns_pcie_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(cdns_pcie_suspend_noirq,
+				  cdns_pcie_resume_noirq)
+};
+EXPORT_SYMBOL_GPL(cdns_pcie_pm_ops);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller driver");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index 5603f214f4c7..51c9bc4eb174 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -152,135 +152,6 @@ void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
 }
 EXPORT_SYMBOL_GPL(cdns_pcie_reset_outbound_region);
 
-void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
-{
-	int i = pcie->phy_count;
-
-	while (i--) {
-		phy_power_off(pcie->phy[i]);
-		phy_exit(pcie->phy[i]);
-	}
-}
-EXPORT_SYMBOL_GPL(cdns_pcie_disable_phy);
-
-int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
-{
-	int ret;
-	int i;
-
-	for (i = 0; i < pcie->phy_count; i++) {
-		ret = phy_init(pcie->phy[i]);
-		if (ret < 0)
-			goto err_phy;
-
-		ret = phy_power_on(pcie->phy[i]);
-		if (ret < 0) {
-			phy_exit(pcie->phy[i]);
-			goto err_phy;
-		}
-	}
-
-	return 0;
-
-err_phy:
-	while (--i >= 0) {
-		phy_power_off(pcie->phy[i]);
-		phy_exit(pcie->phy[i]);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(cdns_pcie_enable_phy);
-
-int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
-{
-	struct device_node *np = dev->of_node;
-	int phy_count;
-	struct phy **phy;
-	struct device_link **link;
-	int i;
-	int ret;
-	const char *name;
-
-	phy_count = of_property_count_strings(np, "phy-names");
-	if (phy_count < 1) {
-		dev_info(dev, "no \"phy-names\" property found; PHY will not be initialized\n");
-		pcie->phy_count = 0;
-		return 0;
-	}
-
-	phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL);
-	if (!phy)
-		return -ENOMEM;
-
-	link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL);
-	if (!link)
-		return -ENOMEM;
-
-	for (i = 0; i < phy_count; i++) {
-		of_property_read_string_index(np, "phy-names", i, &name);
-		phy[i] = devm_phy_get(dev, name);
-		if (IS_ERR(phy[i])) {
-			ret = PTR_ERR(phy[i]);
-			goto err_phy;
-		}
-		link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
-		if (!link[i]) {
-			devm_phy_put(dev, phy[i]);
-			ret = -EINVAL;
-			goto err_phy;
-		}
-	}
-
-	pcie->phy_count = phy_count;
-	pcie->phy = phy;
-	pcie->link = link;
-
-	ret =  cdns_pcie_enable_phy(pcie);
-	if (ret)
-		goto err_phy;
-
-	return 0;
-
-err_phy:
-	while (--i >= 0) {
-		device_link_del(link[i]);
-		devm_phy_put(dev, phy[i]);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(cdns_pcie_init_phy);
-
-static int cdns_pcie_suspend_noirq(struct device *dev)
-{
-	struct cdns_pcie *pcie = dev_get_drvdata(dev);
-
-	cdns_pcie_disable_phy(pcie);
-
-	return 0;
-}
-
-static int cdns_pcie_resume_noirq(struct device *dev)
-{
-	struct cdns_pcie *pcie = dev_get_drvdata(dev);
-	int ret;
-
-	ret = cdns_pcie_enable_phy(pcie);
-	if (ret) {
-		dev_err(dev, "failed to enable PHY\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-const struct dev_pm_ops cdns_pcie_pm_ops = {
-	NOIRQ_SYSTEM_SLEEP_PM_OPS(cdns_pcie_suspend_noirq,
-				  cdns_pcie_resume_noirq)
-};
-EXPORT_SYMBOL_GPL(cdns_pcie_pm_ops);
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Cadence PCIe controller driver");
 MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@free-electrons.com>");
-- 
2.49.0


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

* [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (6 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as " hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-26 12:08   ` kernel test robot
  2025-08-30 13:18   ` Manivannan Sadhasivam
  2025-08-19 11:52 ` [PATCH v8 09/15] PCI: cadence: Update PCIe platform to use register offsets passed hans.zhang
                   ` (7 subsequent siblings)
  15 siblings, 2 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Add support for Cadence PCIe RP and EP configuration for High
Performance Architecture (HPA) controllers.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 drivers/pci/controller/cadence/Makefile       |  10 +-
 .../controller/cadence/pcie-cadence-ep-hpa.c  | 528 ++++++++++++++++
 .../cadence/pcie-cadence-host-hpa.c           | 585 ++++++++++++++++++
 .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++
 drivers/pci/controller/cadence/pcie-cadence.c |  11 +
 drivers/pci/controller/cadence/pcie-cadence.h |  74 ++-
 6 files changed, 1403 insertions(+), 9 deletions(-)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c

diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index b104562fb86a..de4ddae7aca4 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -1,6 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
-obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
-obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
+pcie-cadence-mod-y := pcie-cadence-hpa.o pcie-cadence-common.o pcie-cadence.o
+pcie-cadence-host-mod-y := pcie-cadence-host-common.o pcie-cadence-host.o pcie-cadence-host-hpa.o
+pcie-cadence-ep-mod-y := pcie-cadence-ep-common.o pcie-cadence-ep.o pcie-cadence-ep-hpa.o
+
+obj-$(CONFIG_PCIE_CADENCE) = pcie-cadence-mod.o
+obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
+obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
new file mode 100644
index 000000000000..a5366ecec34f
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe endpoint controller driver.
+// Author: Manikandan K Pillai  <mpillai@cadence.com>
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci-epc.h>
+#include <linux/platform_device.h>
+#include <linux/sizes.h>
+
+#include "pcie-cadence.h"
+#include "pcie-cadence-ep-common.h"
+
+static int cdns_pcie_hpa_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
+				     phys_addr_t addr, u64 pci_addr, size_t size)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 r;
+
+	r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
+	if (r >= ep->max_regions - 1) {
+		dev_err(&epc->dev, "no free outbound region\n");
+		return -EINVAL;
+	}
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+	cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size);
+
+	set_bit(r, &ep->ob_region_map);
+	ep->ob_addr[r] = addr;
+
+	return 0;
+}
+
+static void cdns_pcie_hpa_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
+					phys_addr_t addr)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 r;
+
+	for (r = 0; r < ep->max_regions - 1; r++)
+		if (ep->ob_addr[r] == addr)
+			break;
+
+	if (r == ep->max_regions - 1)
+		return;
+
+	cdns_pcie_hpa_reset_outbound_region(pcie, r);
+
+	ep->ob_addr[r] = 0;
+	clear_bit(r, &ep->ob_region_map);
+}
+
+static void cdns_pcie_hpa_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
+					 bool assert)
+{
+	struct cdns_pcie *pcie = &ep->pcie;
+	unsigned long flags;
+	u32 offset;
+	u16 status;
+	u8 msg_code;
+
+	intx &= 3;
+
+	/* Set the outbound region if needed */
+	if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
+		     ep->irq_pci_fn != fn)) {
+		/* First region was reserved for IRQ writes */
+		cdns_pcie_hpa_set_outbound_region_for_normal_msg(pcie, 0, fn, 0, ep->irq_phys_addr);
+		ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
+		ep->irq_pci_fn = fn;
+	}
+
+	if (assert) {
+		ep->irq_pending |= BIT(intx);
+		msg_code = PCIE_MSG_CODE_ASSERT_INTA + intx;
+	} else {
+		ep->irq_pending &= ~BIT(intx);
+		msg_code = PCIE_MSG_CODE_DEASSERT_INTA + intx;
+	}
+
+	spin_lock_irqsave(&ep->lock, flags);
+	status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS);
+	if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) {
+		status ^= PCI_STATUS_INTERRUPT;
+		cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status);
+	}
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	offset = CDNS_PCIE_NORMAL_MSG_ROUTING(PCIE_MSG_TYPE_R_RC) |
+		 CDNS_PCIE_NORMAL_MSG_CODE(msg_code);
+	writel(0, ep->irq_cpu_addr + offset);
+}
+
+static int cdns_pcie_hpa_ep_raise_intx_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
+					   u8 intx)
+{
+	u16 cmd;
+
+	cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND);
+	if (cmd & PCI_COMMAND_INTX_DISABLE)
+		return -EINVAL;
+
+	cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, true);
+
+	/* The mdelay() value was taken from dra7xx_pcie_raise_intx_irq() */
+	mdelay(1);
+	cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, false);
+	return 0;
+}
+
+static int cdns_pcie_hpa_ep_raise_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
+					  u8 interrupt_num)
+{
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u16 flags, mme, data, data_mask;
+	u8 msi_count;
+	u64 pci_addr, pci_addr_mask = 0xff;
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
+	/* Check whether the MSI feature has been enabled by the PCI host */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	if (!(flags & PCI_MSI_FLAGS_ENABLE))
+		return -EINVAL;
+
+	/* Get the number of enabled MSIs */
+	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
+	msi_count = 1 << mme;
+	if (!interrupt_num || interrupt_num > msi_count)
+		return -EINVAL;
+
+	/* Compute the data value to be written */
+	data_mask = msi_count - 1;
+	data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
+	data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
+
+	/* Get the PCI address where to write the data into */
+	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
+	pci_addr <<= 32;
+	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
+	pci_addr &= GENMASK_ULL(63, 2);
+
+	/* Set the outbound region if needed */
+	if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
+		     ep->irq_pci_fn != fn)) {
+		/* First region was reserved for IRQ writes */
+		cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
+						  false,
+						  ep->irq_phys_addr,
+						  pci_addr & ~pci_addr_mask,
+						  pci_addr_mask + 1);
+		ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
+		ep->irq_pci_fn = fn;
+	}
+	writel(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
+
+	return 0;
+}
+
+static int cdns_pcie_hpa_ep_raise_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
+					   u16 interrupt_num)
+{
+	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+	u32 tbl_offset, msg_data, reg;
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct pci_epf_msix_tbl *msix_tbl;
+	struct cdns_pcie_epf *epf;
+	u64 pci_addr_mask = 0xff;
+	u64 msg_addr;
+	u16 flags;
+	u8 bir;
+
+	epf = &ep->epf[fn];
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
+	/* Check whether the MSI-X feature has been enabled by the PCI host */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
+	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
+		return -EINVAL;
+
+	reg = cap + PCI_MSIX_TABLE;
+	tbl_offset = cdns_pcie_ep_fn_readl(pcie, fn, reg);
+	bir = FIELD_GET(PCI_MSIX_TABLE_BIR, tbl_offset);
+	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
+
+	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
+	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
+	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
+
+	/* Set the outbound region if needed */
+	if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
+	    ep->irq_pci_fn != fn) {
+		/* First region was reserved for IRQ writes */
+		cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
+						  false,
+						  ep->irq_phys_addr,
+						  msg_addr & ~pci_addr_mask,
+						  pci_addr_mask + 1);
+		ep->irq_pci_addr = (msg_addr & ~pci_addr_mask);
+		ep->irq_pci_fn = fn;
+	}
+	writel(msg_data, ep->irq_cpu_addr + (msg_addr & pci_addr_mask));
+
+	return 0;
+}
+
+static int cdns_pcie_hpa_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
+				      unsigned int type, u16 interrupt_num)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct device *dev = pcie->dev;
+
+	switch (type) {
+	case PCI_IRQ_INTX:
+		if (vfn > 0) {
+			dev_err(dev, "Cannot raise INTX interrupts for VF\n");
+			return -EINVAL;
+		}
+		return cdns_pcie_hpa_ep_raise_intx_irq(ep, fn, vfn, 0);
+
+	case PCI_IRQ_MSI:
+		return cdns_pcie_hpa_ep_raise_msi_irq(ep, fn, vfn, interrupt_num);
+
+	case PCI_IRQ_MSIX:
+		return cdns_pcie_hpa_ep_raise_msix_irq(ep, fn, vfn, interrupt_num);
+
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int cdns_pcie_hpa_ep_start(struct pci_epc *epc)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct device *dev = pcie->dev;
+	int max_epfs = sizeof(epc->function_num_map) * 8;
+	int ret, epf, last_fn;
+	u32 reg, value;
+
+	/*
+	 * BIT(0) is hardwired to 1, hence function 0 is always enabled
+	 * and can't be disabled anyway
+	 */
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG,
+			     CDNS_PCIE_HPA_LM_EP_FUNC_CFG, epc->function_num_map);
+
+	/*
+	 * Next function field in ARI_CAP_AND_CTR register for last function
+	 * should be 0 and clear Next Function Number field for the last
+	 * function used
+	 */
+	last_fn = find_last_bit(&epc->function_num_map, BITS_PER_LONG);
+	reg = CDNS_PCIE_CORE_PF_I_ARI_CAP_AND_CTRL(last_fn);
+	value = cdns_pcie_readl(pcie, reg);
+	value &= ~CDNS_PCIE_ARI_CAP_NFN_MASK;
+	cdns_pcie_writel(pcie, reg, value);
+
+	if (ep->quirk_disable_flr) {
+		for (epf = 0; epf < max_epfs; epf++) {
+			if (!(epc->function_num_map & BIT(epf)))
+				continue;
+
+			value = cdns_pcie_ep_fn_readl(pcie, epf,
+						      CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET +
+						      PCI_EXP_DEVCAP);
+			value &= ~PCI_EXP_DEVCAP_FLR;
+			cdns_pcie_ep_fn_writel(pcie, epf,
+					       CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET +
+					       PCI_EXP_DEVCAP, value);
+		}
+	}
+
+	ret = cdns_pcie_start_link(pcie);
+	if (ret) {
+		dev_err(dev, "Failed to start link\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cdns_pcie_hpa_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
+				    struct pci_epf_bar *epf_bar)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie_epf *epf = &ep->epf[fn];
+	struct cdns_pcie *pcie = &ep->pcie;
+	dma_addr_t bar_phys = epf_bar->phys_addr;
+	enum pci_barno bar = epf_bar->barno;
+	int flags = epf_bar->flags;
+	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+	u64 sz;
+
+	/* BAR size is 2^(aperture + 7) */
+	sz = max_t(size_t, epf_bar->size, CDNS_PCIE_EP_MIN_APERTURE);
+
+	/*
+	 * roundup_pow_of_two() returns an unsigned long, which is not suited
+	 * for 64bit values
+	 */
+	sz = 1ULL << fls64(sz - 1);
+
+	/* 128B -> 0, 256B -> 1, 512B -> 2, ... */
+	aperture = ilog2(sz) - 7;
+
+	if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+		ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_IO_32BITS;
+	} else {
+		bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
+		bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
+
+		if (is_64bits && (bar & 1))
+			return -EINVAL;
+
+		if (is_64bits && is_prefetch)
+			ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
+		else if (is_prefetch)
+			ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS;
+		else if (is_64bits)
+			ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_64BITS;
+		else
+			ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_32BITS;
+	}
+
+	addr0 = lower_32_bits(bar_phys);
+	addr1 = upper_32_bits(bar_phys);
+
+	if (vfn == 1)
+		reg = CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG(bar, fn);
+	else
+		reg = CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
+
+	if (vfn == 0 || vfn == 1) {
+		cfg = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_CFG_CTRL_REG, reg);
+		cfg &= ~(CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= (CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+			CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+		cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG, reg, cfg);
+	}
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_MASTER_COMMON,
+			     CDNS_PCIE_HPA_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), addr0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_MASTER_COMMON,
+			     CDNS_PCIE_HPA_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), addr1);
+
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
+	epf->epf_bar[bar] = epf_bar;
+
+	return 0;
+}
+
+static void cdns_pcie_hpa_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
+				       struct pci_epf_bar *epf_bar)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie_epf *epf = &ep->epf[fn];
+	struct cdns_pcie *pcie = &ep->pcie;
+	enum pci_barno bar = epf_bar->barno;
+	u32 reg, cfg, b, ctrl;
+
+	if (vfn == 1)
+		reg = CDNS_PCIE_HPA_LM_EP_VFUNC_BAR_CFG(bar, fn);
+	else
+		reg = CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
+
+	if (vfn == 0 || vfn == 1) {
+		ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_DISABLED;
+		cfg = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_CFG_CTRL_REG, reg);
+		cfg &= ~(CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= CDNS_PCIE_HPA_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+		cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG, reg, cfg);
+	}
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_MASTER_COMMON,
+			     CDNS_PCIE_HPA_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_MASTER_COMMON,
+			     CDNS_PCIE_HPA_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
+
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
+	epf->epf_bar[bar] = NULL;
+}
+
+static const struct pci_epc_ops cdns_pcie_hpa_epc_ops = {
+	.write_header	= cdns_pcie_ep_write_header,
+	.set_bar	= cdns_pcie_hpa_ep_set_bar,
+	.clear_bar	= cdns_pcie_hpa_ep_clear_bar,
+	.map_addr	= cdns_pcie_hpa_ep_map_addr,
+	.unmap_addr	= cdns_pcie_hpa_ep_unmap_addr,
+	.set_msi	= cdns_pcie_ep_set_msi,
+	.get_msi	= cdns_pcie_ep_get_msi,
+	.set_msix	= cdns_pcie_ep_set_msix,
+	.get_msix	= cdns_pcie_ep_get_msix,
+	.raise_irq	= cdns_pcie_hpa_ep_raise_irq,
+	.map_msi_irq	= cdns_pcie_ep_map_msi_irq,
+	.start		= cdns_pcie_hpa_ep_start,
+	.get_features	= cdns_pcie_ep_get_features,
+};
+
+int cdns_pcie_hpa_ep_setup(struct cdns_pcie_ep *ep)
+{
+	struct device *dev = ep->pcie.dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct device_node *np = dev->of_node;
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct cdns_pcie_epf *epf;
+	struct resource *res;
+	struct pci_epc *epc;
+	int ret;
+	int i;
+
+	pcie->is_rc = false;
+
+	pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg");
+	if (IS_ERR(pcie->reg_base)) {
+		dev_err(dev, "missing \"reg\"\n");
+		return PTR_ERR(pcie->reg_base);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
+	if (!res) {
+		dev_err(dev, "missing \"mem\"\n");
+		return -EINVAL;
+	}
+	pcie->mem_res = res;
+
+	ep->max_regions = CDNS_PCIE_MAX_OB;
+	of_property_read_u32(np, "cdns,max-outbound-regions", &ep->max_regions);
+
+	ep->ob_addr = devm_kcalloc(dev,
+				   ep->max_regions, sizeof(*ep->ob_addr),
+				   GFP_KERNEL);
+	if (!ep->ob_addr)
+		return -ENOMEM;
+
+	epc = devm_pci_epc_create(dev, &cdns_pcie_hpa_epc_ops);
+	if (IS_ERR(epc)) {
+		dev_err(dev, "failed to create epc device\n");
+		return PTR_ERR(epc);
+	}
+
+	epc_set_drvdata(epc, ep);
+
+	if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0)
+		epc->max_functions = 1;
+
+	ep->epf = devm_kcalloc(dev, epc->max_functions, sizeof(*ep->epf),
+			       GFP_KERNEL);
+	if (!ep->epf)
+		return -ENOMEM;
+
+	epc->max_vfs = devm_kcalloc(dev, epc->max_functions,
+				    sizeof(*epc->max_vfs), GFP_KERNEL);
+	if (!epc->max_vfs)
+		return -ENOMEM;
+
+	ret = of_property_read_u8_array(np, "max-virtual-functions",
+					epc->max_vfs, epc->max_functions);
+	if (ret == 0) {
+		for (i = 0; i < epc->max_functions; i++) {
+			epf = &ep->epf[i];
+			if (epc->max_vfs[i] == 0)
+				continue;
+			epf->epf = devm_kcalloc(dev, epc->max_vfs[i],
+						sizeof(*ep->epf), GFP_KERNEL);
+			if (!epf->epf)
+				return -ENOMEM;
+		}
+	}
+
+	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
+			       resource_size(pcie->mem_res), PAGE_SIZE);
+	if (ret < 0) {
+		dev_err(dev, "failed to initialize the memory space\n");
+		return ret;
+	}
+
+	ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
+						  SZ_128K);
+	if (!ep->irq_cpu_addr) {
+		dev_err(dev, "failed to reserve memory space for MSI\n");
+		ret = -ENOMEM;
+		goto free_epc_mem;
+	}
+	ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
+	/* Reserve region 0 for IRQs */
+	set_bit(0, &ep->ob_region_map);
+
+	if (ep->quirk_detect_quiet_flag)
+		cdns_pcie_hpa_detect_quiet_min_delay_set(&ep->pcie);
+
+	spin_lock_init(&ep->lock);
+
+	pci_epc_init_notify(epc);
+
+	return 0;
+
+ free_epc_mem:
+	pci_epc_mem_exit(epc);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_ep_setup);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller driver");
+MODULE_AUTHOR("Manikandan K Pillai <mpillai@cadence.com>");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
new file mode 100644
index 000000000000..b2e570f2c047
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
@@ -0,0 +1,585 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe host controller driver.
+// Author: Manikandan K Pillai <mpillai@cadence.com>
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/list_sort.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-cadence.h"
+#include "pcie-cadence-host-common.h"
+
+static u8 bar_aperture_mask[] = {
+	[RP_BAR0] = 0x1F,
+	[RP_BAR1] = 0xF,
+};
+
+void __iomem *cdns_pci_hpa_map_bus(struct pci_bus *bus, unsigned int devfn,
+				   int where)
+{
+	struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+	struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
+	struct cdns_pcie *pcie = &rc->pcie;
+	unsigned int busn = bus->number;
+	u32 addr0, desc0, desc1, ctrl0;
+	u32 regval;
+
+	if (pci_is_root_bus(bus)) {
+		/*
+		 * Only the root port (devfn == 0) is connected to this bus.
+		 * All other PCI devices are behind some bridge hence on another
+		 * bus.
+		 */
+		if (devfn)
+			return NULL;
+
+		return pcie->reg_base + (where & 0xfff);
+	}
+
+	/* Clear AXI link-down status */
+	regval = cdns_pcie_hpa_readl(pcie, REG_BANK_AXI_SLAVE, CDNS_PCIE_HPA_AT_LINKDOWN);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, CDNS_PCIE_HPA_AT_LINKDOWN,
+			     (regval & ~GENMASK(0, 0)));
+
+	desc0 = 0;
+	desc1 = 0;
+	ctrl0 = 0;
+
+	/* Update Output registers for AXI region 0 */
+	addr0 = CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
+		CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) |
+		CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_BUS(busn);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(0), addr0);
+
+	desc1 = cdns_pcie_hpa_readl(pcie, REG_BANK_AXI_SLAVE,
+				    CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0));
+	desc1 &= ~CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN_MASK;
+	desc1 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(0);
+	ctrl0 = CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_BUS |
+		CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN;
+
+	if (busn == bridge->busnr + 1)
+		desc0 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0;
+	else
+		desc0 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1;
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(0), desc0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0), desc1);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(0), ctrl0);
+
+	return rc->cfg_base + (where & 0xfff);
+}
+
+int cdns_pcie_hpa_host_wait_for_link(struct cdns_pcie *pcie)
+{
+	struct device *dev = pcie->dev;
+	int retries;
+
+	/* Check if the link is up or not */
+	for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+		if (cdns_pcie_hpa_link_up(pcie)) {
+			dev_info(dev, "Link up\n");
+			return 0;
+		}
+		usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+	}
+	return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_wait_for_link);
+
+int cdns_pcie_hpa_host_start_link(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	int ret;
+
+	ret = cdns_pcie_hpa_host_wait_for_link(pcie);
+
+	/* Retrain link for Gen2 training defect if quirk flag is set */
+	if (!ret && rc->quirk_retrain_flag)
+		ret = cdns_pcie_retrain(pcie);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_start_link);
+
+static struct pci_ops cdns_pcie_hpa_host_ops = {
+	.map_bus	= cdns_pci_hpa_map_bus,
+	.read		= pci_generic_config_read,
+	.write		= pci_generic_config_write,
+};
+
+static void cdns_pcie_hpa_host_enable_ptm_response(struct cdns_pcie *pcie)
+{
+	u32 val;
+
+	val = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_LM_PTM_CTRL);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_LM_PTM_CTRL,
+			     val | CDNS_PCIE_HPA_LM_TPM_CTRL_PTMRSEN);
+}
+
+static int cdns_pcie_hpa_host_bar_ib_config(struct cdns_pcie_rc *rc,
+					    enum cdns_pcie_rp_bar bar,
+					    u64 cpu_addr, u64 size,
+					    unsigned long flags)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	u32 addr0, addr1, aperture, value;
+
+	if (!rc->avail_ib_bar[bar])
+		return -EBUSY;
+
+	rc->avail_ib_bar[bar] = false;
+
+	aperture = ilog2(size);
+	addr0 = CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR0_NBITS(aperture) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_MASTER,
+			     CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR0(bar), addr0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_MASTER,
+			     CDNS_PCIE_HPA_AT_IB_RP_BAR_ADDR1(bar), addr1);
+
+	if (bar == RP_NO_BAR)
+		return 0;
+
+	value = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_CFG_CTRL_REG, CDNS_PCIE_HPA_LM_RC_BAR_CFG);
+	value &= ~(HPA_LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar) |
+		   HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) |
+		   HPA_LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar) |
+		   HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) |
+		   HPA_LM_RC_BAR_CFG_APERTURE(bar, bar_aperture_mask[bar] + 2));
+	if (size + cpu_addr >= SZ_4G) {
+		if (!(flags & IORESOURCE_PREFETCH))
+			value |= HPA_LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar);
+		value |= HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar);
+	} else {
+		if (!(flags & IORESOURCE_PREFETCH))
+			value |= HPA_LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar);
+		value |= HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar);
+	}
+
+	value |= HPA_LM_RC_BAR_CFG_APERTURE(bar, aperture);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG, CDNS_PCIE_HPA_LM_RC_BAR_CFG, value);
+
+	return 0;
+}
+
+static int cdns_pcie_hpa_host_bar_config(struct cdns_pcie_rc *rc,
+					 struct resource_entry *entry)
+{
+	u64 cpu_addr, pci_addr, size, winsize;
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct device *dev = pcie->dev;
+	enum cdns_pcie_rp_bar bar;
+	unsigned long flags;
+	int ret;
+
+	cpu_addr = entry->res->start;
+	pci_addr = entry->res->start - entry->offset;
+	flags = entry->res->flags;
+	size = resource_size(entry->res);
+
+	if (entry->offset) {
+		dev_err(dev, "PCI addr: %llx must be equal to CPU addr: %llx\n",
+			pci_addr, cpu_addr);
+		return -EINVAL;
+	}
+
+	while (size > 0) {
+		/*
+		 * Try to find a minimum BAR whose size is greater than
+		 * or equal to the remaining resource_entry size. This will
+		 * fail if the size of each of the available BARs is less than
+		 * the remaining resource_entry size.
+		 *
+		 * If a minimum BAR is found, IB ATU will be configured and
+		 * exited.
+		 */
+		bar = cdns_pcie_host_find_min_bar(rc, size);
+		if (bar != RP_BAR_UNDEFINED) {
+			ret = cdns_pcie_hpa_host_bar_ib_config(rc, bar, cpu_addr,
+							       size, flags);
+			if (ret)
+				dev_err(dev, "IB BAR: %d config failed\n", bar);
+			return ret;
+		}
+
+		/*
+		 * If the control reaches here, it would mean the remaining
+		 * resource_entry size cannot be fitted in a single BAR. So we
+		 * find a maximum BAR whose size is less than or equal to the
+		 * remaining resource_entry size and split the resource entry
+		 * so that part of resource entry is fitted inside the maximum
+		 * BAR. The remaining size would be fitted during the next
+		 * iteration of the loop.
+		 *
+		 * If a maximum BAR is not found, there is no way we can fit
+		 * this resource_entry, so we error out.
+		 */
+		bar = cdns_pcie_host_find_max_bar(rc, size);
+		if (bar == RP_BAR_UNDEFINED) {
+			dev_err(dev, "No free BAR to map cpu_addr %llx\n",
+				cpu_addr);
+			return -EINVAL;
+		}
+
+		winsize = bar_max_size[bar];
+		ret = cdns_pcie_hpa_host_bar_ib_config(rc, bar, cpu_addr, winsize, flags);
+		if (ret) {
+			dev_err(dev, "IB BAR: %d config failed\n", bar);
+			return ret;
+		}
+
+		size -= winsize;
+		cpu_addr += winsize;
+	}
+
+	return 0;
+}
+
+static int cdns_pcie_hpa_host_map_dma_ranges(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct device *dev = pcie->dev;
+	struct device_node *np = dev->of_node;
+	struct pci_host_bridge *bridge;
+	struct resource_entry *entry;
+	u32 no_bar_nbits = 32;
+	int err;
+
+	bridge = pci_host_bridge_from_priv(rc);
+	if (!bridge)
+		return -ENOMEM;
+
+	if (list_empty(&bridge->dma_ranges)) {
+		of_property_read_u32(np, "cdns,no-bar-match-nbits",
+				     &no_bar_nbits);
+		err = cdns_pcie_hpa_host_bar_ib_config(rc, RP_NO_BAR, 0x0,
+						       (u64)1 << no_bar_nbits, 0);
+		if (err)
+			dev_err(dev, "IB BAR: %d config failed\n", RP_NO_BAR);
+		return err;
+	}
+
+	list_sort(NULL, &bridge->dma_ranges, cdns_pcie_host_dma_ranges_cmp);
+
+	resource_list_for_each_entry(entry, &bridge->dma_ranges) {
+		err = cdns_pcie_hpa_host_bar_config(rc, entry);
+		if (err) {
+			dev_err(dev, "Fail to configure IB using dma-ranges\n");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int cdns_pcie_hpa_host_init_root_port(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	u32 value, ctrl;
+
+	/*
+	 * Set the root complex BAR configuration register:
+	 * - disable both BAR0 and BAR1
+	 * - enable Prefetchable Memory Base and Limit registers in type 1
+	 *   config space (64 bits)
+	 * - enable IO Base and Limit registers in type 1 config
+	 *   space (32 bits)
+	 */
+
+	ctrl = CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_DISABLED;
+	value = CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR0_CTRL(ctrl) |
+		CDNS_PCIE_HPA_LM_RC_BAR_CFG_BAR1_CTRL(ctrl) |
+		CDNS_PCIE_HPA_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE |
+		CDNS_PCIE_HPA_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS |
+		CDNS_PCIE_HPA_LM_RC_BAR_CFG_IO_ENABLE |
+		CDNS_PCIE_HPA_LM_RC_BAR_CFG_IO_32BITS;
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG,
+			     CDNS_PCIE_HPA_LM_RC_BAR_CFG, value);
+
+	if (rc->vendor_id != 0xffff)
+		cdns_pcie_hpa_rp_writew(pcie, PCI_VENDOR_ID, rc->vendor_id);
+
+	if (rc->device_id != 0xffff)
+		cdns_pcie_hpa_rp_writew(pcie, PCI_DEVICE_ID, rc->device_id);
+
+	cdns_pcie_hpa_rp_writeb(pcie, PCI_CLASS_REVISION, 0);
+	cdns_pcie_hpa_rp_writeb(pcie, PCI_CLASS_PROG, 0);
+	cdns_pcie_hpa_rp_writew(pcie, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
+
+	return 0;
+}
+
+static void cdns_pcie_hpa_create_region_for_ecam(struct cdns_pcie_rc *rc)
+{
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
+	struct resource *cfg_res = rc->cfg_res;
+	struct cdns_pcie *pcie = &rc->pcie;
+	u32 value, root_port_req_id_reg, pcie_bus_number_reg;
+	u32 ecam_addr_0, region_size_0, request_id_0;
+	int busnr = 0, secbus = 0, subbus = 0;
+	struct resource_entry *entry;
+	resource_size_t size;
+	u32 axi_address_low;
+	int nbits;
+	u64 sz;
+
+	entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+	if (entry) {
+		busnr = entry->res->start;
+		secbus = (busnr < 0xff) ? (busnr + 1) : 0xff;
+		subbus = entry->res->end;
+	}
+	size = resource_size(cfg_res);
+	sz = 1ULL << fls64(size - 1);
+	nbits = ilog2(sz);
+	if (nbits < 8)
+		nbits = 8;
+
+	root_port_req_id_reg = ((busnr & 0xff) << 8);
+	pcie_bus_number_reg = ((subbus & 0xff) << 16) | ((secbus & 0xff) << 8) |
+			      (busnr & 0xff);
+	ecam_addr_0 = cfg_res->start;
+	region_size_0 = nbits - 1;
+	request_id_0 = ((busnr & 0xff) << 8);
+
+#define CDNS_PCIE_HPA_TAG_MANAGEMENT (0x0)
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_TAG_MANAGEMENT, 0x200000);
+
+	/* Taking slave err as OKAY */
+#define CDNS_PCIE_HPA_SLAVE_RESP (0x100)
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, CDNS_PCIE_HPA_SLAVE_RESP,
+			     0x0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_SLAVE_RESP + 0x4, 0x0);
+
+	/* Program the register "i_root_port_req_id_reg" with RP's BDF */
+#define I_ROOT_PORT_REQ_ID_REG (0x141c)
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, I_ROOT_PORT_REQ_ID_REG,
+			     root_port_req_id_reg);
+
+	/**
+	 * Program the register "i_pcie_bus_numbers" with Primary(RP's bus number),
+	 * secondary and subordinate bus numbers
+	 */
+#define I_PCIE_BUS_NUMBERS (CDNS_PCIE_HPA_RP_BASE + 0x18)
+	cdns_pcie_hpa_writel(pcie, REG_BANK_RP, I_PCIE_BUS_NUMBERS,
+			     pcie_bus_number_reg);
+
+	/* Program the register "lm_hal_sbsa_ctrl[0]" to enable the sbsa */
+#define LM_HAL_SBSA_CTRL (0x1170)
+	value = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL);
+	value |= BIT(0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL, value);
+
+	/* Program region[0] for ECAM */
+	axi_address_low = (ecam_addr_0 & 0xfff00000) | region_size_0;
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(0),
+			     axi_address_low);
+
+	/* rc0-high-axi-address */
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(0), 0x0);
+	/* Type-1 CFG */
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(0), 0x05000000);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0),
+			     (request_id_0 << 16));
+
+	/* All AXI bits pass through PCIe */
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(0), 0x1b);
+	/* PCIe address-high */
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(0), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(0), 0x06000000);
+}
+
+static void cdns_pcie_hpa_create_region_for_cfg(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
+	struct resource *cfg_res = rc->cfg_res;
+	struct resource_entry *entry;
+	u64 cpu_addr = cfg_res->start;
+	u32 addr0, addr1, desc1;
+	int busnr = 0;
+
+	entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+	if (entry)
+		busnr = entry->res->start;
+
+	/*
+	 * Reserve region 0 for PCI configure space accesses:
+	 * OB_REGION_PCI_ADDR0 and OB_REGION_DESC0 are updated dynamically by
+	 * cdns_pci_map_bus(), other region registers are set here once for all
+	 */
+	addr1 = 0;
+	desc1 = CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS(busnr);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(0), addr1);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0), desc1);
+
+	addr0 = CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(0), addr0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(0), addr1);
+}
+
+static int cdns_pcie_hpa_host_init_address_translation(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
+	struct resource_entry *entry;
+	int r = 0, busnr = 0;
+
+	if (rc->ecam_support_flag)
+		cdns_pcie_hpa_create_region_for_ecam(rc);
+	else
+		cdns_pcie_hpa_create_region_for_cfg(rc);
+
+	entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+	if (entry)
+		busnr = entry->res->start;
+
+	r++;
+	if (pcie->msg_res)
+		cdns_pcie_hpa_set_outbound_region_for_normal_msg(pcie, busnr, 0, r,
+								 pcie->msg_res->start);
+
+	r++;
+	resource_list_for_each_entry(entry, &bridge->windows) {
+		struct resource *res = entry->res;
+		u64 pci_addr = res->start - entry->offset;
+
+		if (resource_type(res) == IORESOURCE_IO)
+			cdns_pcie_hpa_set_outbound_region(pcie, busnr, 0, r,
+							  true,
+							  pci_pio_to_address(res->start),
+							  pci_addr,
+							  resource_size(res));
+		else
+			cdns_pcie_hpa_set_outbound_region(pcie, busnr, 0, r,
+							  false,
+							  res->start,
+							  pci_addr,
+							  resource_size(res));
+
+		r++;
+	}
+
+	if (rc->no_inbound_flag)
+		return 0;
+	else
+		return cdns_pcie_hpa_host_map_dma_ranges(rc);
+}
+
+int cdns_pcie_hpa_host_init(struct cdns_pcie_rc *rc)
+{
+	int err;
+
+	err = cdns_pcie_hpa_host_init_root_port(rc);
+	if (err)
+		return err;
+
+	return cdns_pcie_hpa_host_init_address_translation(rc);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_init);
+
+int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct device *dev = rc->pcie.dev;
+	int ret;
+
+	if (rc->quirk_detect_quiet_flag)
+		cdns_pcie_hpa_detect_quiet_min_delay_set(&rc->pcie);
+
+	cdns_pcie_hpa_host_enable_ptm_response(pcie);
+
+	ret = cdns_pcie_start_link(pcie);
+	if (ret) {
+		dev_err(dev, "Failed to start link\n");
+		return ret;
+	}
+
+	ret = cdns_pcie_hpa_host_start_link(rc);
+	if (ret)
+		dev_dbg(dev, "PCIe link never came up\n");
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_link_setup);
+
+int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
+{
+	struct device *dev = rc->pcie.dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pci_host_bridge *bridge;
+	enum cdns_pcie_rp_bar bar;
+	struct cdns_pcie *pcie;
+	struct resource *res;
+	int ret;
+
+	bridge = pci_host_bridge_from_priv(rc);
+	if (!bridge)
+		return -ENOMEM;
+
+	pcie = &rc->pcie;
+	pcie->is_rc = true;
+
+	if (!pcie->reg_base) {
+		pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg");
+		if (IS_ERR(pcie->reg_base)) {
+			dev_err(dev, "missing \"reg\"\n");
+			return PTR_ERR(pcie->reg_base);
+		}
+	}
+
+	/* ECAM config space is remapped at glue layer */
+	if (!rc->cfg_base) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+		rc->cfg_base = devm_pci_remap_cfg_resource(dev, res);
+		if (IS_ERR(rc->cfg_base))
+			return PTR_ERR(rc->cfg_base);
+		rc->cfg_res = res;
+	}
+
+	ret = cdns_pcie_hpa_host_link_setup(rc);
+	if (ret)
+		return ret;
+
+	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
+		rc->avail_ib_bar[bar] = true;
+
+	ret = cdns_pcie_hpa_host_init(rc);
+	if (ret)
+		return ret;
+
+	if (!bridge->ops)
+		bridge->ops = &cdns_pcie_hpa_host_ops;
+
+	return pci_host_probe(bridge);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_setup);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller driver");
+MODULE_AUTHOR("Manikandan K Pillai <mpillai@cadence.com>");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-hpa.c
new file mode 100644
index 000000000000..f8c0de4b7881
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-hpa.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver
+// Author: Manikandan K Pillai <mpillai@cadence.com>
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "pcie-cadence.h"
+
+bool cdns_pcie_hpa_link_up(struct cdns_pcie *pcie)
+{
+	u32 pl_reg_val;
+
+	pl_reg_val = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_PHY_DBG_STS_REG0);
+	if (pl_reg_val & GENMASK(0, 0))
+		return true;
+	return false;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_link_up);
+
+int cdns_pcie_hpa_start_link(struct cdns_pcie *pcie)
+{
+	u32 pl_reg_val;
+
+	pl_reg_val = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_PHY_LAYER_CFG0);
+	pl_reg_val |= CDNS_PCIE_HPA_LINK_TRNG_EN_MASK;
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_PHY_LAYER_CFG0, pl_reg_val);
+	return 0;
+}
+
+void cdns_pcie_hpa_stop_link(struct cdns_pcie *pcie)
+{
+	u32 pl_reg_val;
+
+	pl_reg_val = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_PHY_LAYER_CFG0);
+	pl_reg_val &= ~CDNS_PCIE_HPA_LINK_TRNG_EN_MASK;
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_PHY_LAYER_CFG0, pl_reg_val);
+}
+
+void cdns_pcie_hpa_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
+{
+	u32 delay = 0x3;
+	u32 ltssm_control_cap;
+
+	/* Set the LTSSM Detect Quiet state min. delay to 2ms */
+	ltssm_control_cap = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG,
+						CDNS_PCIE_HPA_PHY_LAYER_CFG0);
+	ltssm_control_cap = ((ltssm_control_cap &
+			    ~CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY_MASK) |
+			    CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY(delay));
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG,
+			     CDNS_PCIE_HPA_PHY_LAYER_CFG0, ltssm_control_cap);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_detect_quiet_min_delay_set);
+
+void cdns_pcie_hpa_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
+				       u32 r, bool is_io,
+				       u64 cpu_addr, u64 pci_addr, size_t size)
+{
+	/*
+	 * roundup_pow_of_two() returns an unsigned long, which is not suited
+	 * for 64bit values
+	 */
+	u64 sz = 1ULL << fls64(size - 1);
+	int nbits = ilog2(sz);
+	u32 addr0, addr1, desc0, desc1, ctrl0;
+
+	if (nbits < 8)
+		nbits = 8;
+
+	/* Set the PCI address */
+	addr0 = CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) |
+		(lower_32_bits(pci_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(pci_addr);
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(r), addr0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(r), addr1);
+
+	/* Set the PCIe header descriptor */
+	if (is_io)
+		desc0 = CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_IO;
+	else
+		desc0 = CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MEM;
+	desc1 = 0;
+	ctrl0 = 0;
+
+	/*
+	 * Whether Bit [26] is set or not inside DESC0 register of the outbound
+	 * PCIe descriptor, the PCI function number must be set into
+	 * Bits [31:24] of DESC1 anyway.
+	 *
+	 * In Root Complex mode, the function number is always 0 but in Endpoint
+	 * mode, the PCIe controller may support more than one function. This
+	 * function number needs to be set properly into the outbound PCIe
+	 * descriptor.
+	 *
+	 * Besides, setting Bit [26] is mandatory when in Root Complex mode:
+	 * then the driver must provide the bus, resp. device, number in
+	 * Bits [31:24] of DESC1, resp. Bits[23:16] of DESC0. Like the function
+	 * number, the device number is always 0 in Root Complex mode.
+	 *
+	 * However when in Endpoint mode, we can clear Bit [26] of DESC0, hence
+	 * the PCIe controller will use the captured values for the bus and
+	 * device numbers.
+	 */
+	if (pcie->is_rc) {
+		/* The device and function numbers are always 0 */
+		desc1 = CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS(busnr) |
+			CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(0);
+		ctrl0 = CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_BUS |
+			CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN;
+	} else {
+		/*
+		 * Use captured values for bus and device numbers but still
+		 * need to set the function number
+		 */
+		desc1 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(fn);
+	}
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(r), desc0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(r), desc1);
+
+	addr0 = CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(r), addr0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(r), addr1);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(r), ctrl0);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_set_outbound_region);
+
+void cdns_pcie_hpa_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
+						      u8 busnr, u8 fn,
+						      u32 r, u64 cpu_addr)
+{
+	u32 addr0, addr1, desc0, desc1, ctrl0;
+
+	desc0 = CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG;
+	desc1 = 0;
+	ctrl0 = 0;
+
+	/* See cdns_pcie_set_outbound_region() comments above */
+	if (pcie->is_rc) {
+		desc1 = CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS(busnr) |
+			CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(0);
+		ctrl0 = CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_BUS |
+			CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN;
+	} else {
+		desc1 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(fn);
+	}
+
+	addr0 = CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(r), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(r), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(r), desc0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(r), desc1);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(r), addr0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(r), addr1);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(r), ctrl0);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_set_outbound_region_for_normal_msg);
+
+void cdns_pcie_hpa_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
+{
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(r), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(r), 0);
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(r), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(r), 0);
+
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(r), 0);
+	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
+			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(r), 0);
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_hpa_reset_outbound_region);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cadence PCIe controller driver");
+MODULE_AUTHOR("Manikandan K Pillai <mpillai@cadence.com>");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index 51c9bc4eb174..aaf921ea70e0 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -9,6 +9,17 @@
 
 #include "pcie-cadence.h"
 
+bool cdns_pcie_linkup(struct cdns_pcie *pcie)
+{
+	u32 pl_reg_val;
+
+	pl_reg_val = cdns_pcie_readl(pcie, CDNS_PCIE_LM_BASE);
+	if (pl_reg_val & GENMASK(0, 0))
+		return true;
+	return false;
+}
+EXPORT_SYMBOL_GPL(cdns_pcie_linkup);
+
 void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
 {
 	u32 delay = 0x3;
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 1174cf597bb0..f2eb3f09b21a 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -7,6 +7,7 @@
 #define _PCIE_CADENCE_H
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pci-epf.h>
 #include <linux/phy/phy.h>
@@ -42,9 +43,9 @@ enum cdns_pcie_reg_bank {
 };
 
 struct cdns_pcie_ops {
-	int	(*start_link)(struct cdns_pcie *pcie);
-	void	(*stop_link)(struct cdns_pcie *pcie);
-	bool	(*link_up)(struct cdns_pcie *pcie);
+	int     (*start_link)(struct cdns_pcie *pcie);
+	void    (*stop_link)(struct cdns_pcie *pcie);
+	bool    (*link_up)(struct cdns_pcie *pcie);
 	u64     (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
 };
 
@@ -76,6 +77,7 @@ struct cdns_plat_pcie_of_data {
  * struct cdns_pcie - private data for Cadence PCIe controller drivers
  * @reg_base: IO mapped register base
  * @mem_res: start/end offsets in the physical system memory to map PCI accesses
+ * @msg_res: Region for send message to map PCI accesses
  * @dev: PCIe controller
  * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
  * @phy_count: number of supported PHY devices
@@ -88,6 +90,7 @@ struct cdns_plat_pcie_of_data {
 struct cdns_pcie {
 	void __iomem		             *reg_base;
 	struct resource		             *mem_res;
+	struct resource                      *msg_res;
 	struct device		             *dev;
 	bool			             is_rc;
 	int			             phy_count;
@@ -110,6 +113,7 @@ struct cdns_pcie {
  *                available
  * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
  * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
+ * @ecam_support_flag: Whether the ECAM flag is supported
  */
 struct cdns_pcie_rc {
 	struct cdns_pcie	pcie;
@@ -120,6 +124,8 @@ struct cdns_pcie_rc {
 	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
 	unsigned int		quirk_retrain_flag:1;
 	unsigned int		quirk_detect_quiet_flag:1;
+	unsigned int            ecam_support_flag:1;
+	unsigned int		no_inbound_flag:1;
 };
 
 /**
@@ -303,6 +309,29 @@ static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg)
 	return cdns_pcie_read_sz(addr, 0x2);
 }
 
+static inline void cdns_pcie_hpa_rp_writeb(struct cdns_pcie *pcie,
+					   u32 reg, u8 value)
+{
+	void __iomem *addr = pcie->reg_base + CDNS_PCIE_HPA_RP_BASE + reg;
+
+	cdns_pcie_write_sz(addr, 0x1, value);
+}
+
+static inline void cdns_pcie_hpa_rp_writew(struct cdns_pcie *pcie,
+					   u32 reg, u16 value)
+{
+	void __iomem *addr = pcie->reg_base + CDNS_PCIE_HPA_RP_BASE + reg;
+
+	cdns_pcie_write_sz(addr, 0x2, value);
+}
+
+static inline u16 cdns_pcie_hpa_rp_readw(struct cdns_pcie *pcie, u32 reg)
+{
+	void __iomem *addr = pcie->reg_base + CDNS_PCIE_HPA_RP_BASE + reg;
+
+	return cdns_pcie_read_sz(addr, 0x2);
+}
+
 /* Endpoint Function register access */
 static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
 					  u32 reg, u8 value)
@@ -367,6 +396,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
 void cdns_pcie_host_disable(struct cdns_pcie_rc *rc);
 void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 			       int where);
+int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc);
 #else
 static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
 {
@@ -383,6 +413,11 @@ static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 	return 0;
 }
 
+static inline int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
+{
+	return 0;
+}
+
 static inline void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
 {
 }
@@ -397,6 +432,7 @@ static inline void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int d
 #if IS_ENABLED(CONFIG_PCIE_CADENCE_EP)
 int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep);
 void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep);
+int cdns_pcie_hpa_ep_setup(struct cdns_pcie_ep *ep);
 #else
 static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 {
@@ -406,8 +442,16 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 static inline void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep)
 {
 }
-#endif
 
+static inline int cdns_pcie_hpa_ep_setup(struct cdns_pcie_ep *ep)
+{
+	return 0;
+}
+
+#endif
+bool cdns_pcie_linkup(struct cdns_pcie *pcie);
+int  cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie);
+int  cdns_pcie_host_start_link(struct cdns_pcie_rc *rc);
 void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
 
 void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
@@ -420,8 +464,26 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
 
 void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
 void cdns_pcie_disable_phy(struct cdns_pcie *pcie);
-int cdns_pcie_enable_phy(struct cdns_pcie *pcie);
-int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie);
+int  cdns_pcie_enable_phy(struct cdns_pcie *pcie);
+int  cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie);
+void cdns_pcie_hpa_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
+void cdns_pcie_hpa_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
+				       u32 r, bool is_io,
+				       u64 cpu_addr, u64 pci_addr, size_t size);
+void cdns_pcie_hpa_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
+						      u8 busnr, u8 fn,
+						      u32 r, u64 cpu_addr);
+void cdns_pcie_hpa_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
+int  cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc);
+int  cdns_pcie_hpa_host_init(struct cdns_pcie_rc *rc);
+void __iomem *cdns_pci_hpa_map_bus(struct pci_bus *bus, unsigned int devfn,
+				   int where);
+int  cdns_pcie_hpa_host_wait_for_link(struct cdns_pcie *pcie);
+int  cdns_pcie_hpa_host_start_link(struct cdns_pcie_rc *rc);
+int  cdns_pcie_hpa_start_link(struct cdns_pcie *pcie);
+void cdns_pcie_hpa_stop_link(struct cdns_pcie *pcie);
+bool cdns_pcie_hpa_link_up(struct cdns_pcie *pcie);
+
 extern const struct dev_pm_ops cdns_pcie_pm_ops;
 
 #endif /* _PCIE_CADENCE_H */
-- 
2.49.0


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

* [PATCH v8 09/15] PCI: cadence: Update PCIe platform to use register offsets passed
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (7 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 11:52 ` [PATCH v8 10/15] dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings hans.zhang
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Manikandan K Pillai <mpillai@cadence.com>

Update the PCIe Cadence platform to use register offsets that
are passed during probe of the platform.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 drivers/pci/controller/cadence/pcie-cadence-plat.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index b067a3296dd3..927ab5b8477c 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -31,6 +31,7 @@ static u64 cdns_plat_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
 
 static const struct cdns_pcie_ops cdns_plat_ops = {
 	.cpu_addr_fixup = cdns_plat_cpu_addr_fixup,
+	.link_up = cdns_pcie_linkup,
 };
 
 static int cdns_plat_pcie_probe(struct platform_device *pdev)
@@ -68,6 +69,11 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
 		rc = pci_host_bridge_priv(bridge);
 		rc->pcie.dev = dev;
 		rc->pcie.ops = &cdns_plat_ops;
+		rc->pcie.is_rc = data->is_rc;
+
+		/* Store the register bank offsets pointer */
+		rc->pcie.cdns_pcie_reg_offsets = data;
+
 		cdns_plat_pcie->pcie = &rc->pcie;
 
 		ret = cdns_pcie_init_phy(dev, cdns_plat_pcie->pcie);
@@ -95,6 +101,11 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
 
 		ep->pcie.dev = dev;
 		ep->pcie.ops = &cdns_plat_ops;
+		ep->pcie.is_rc = data->is_rc;
+
+		/* Store the register bank offset pointer */
+		ep->pcie.cdns_pcie_reg_offsets = data;
+
 		cdns_plat_pcie->pcie = &ep->pcie;
 
 		ret = cdns_pcie_init_phy(dev, cdns_plat_pcie->pcie);
-- 
2.49.0


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

* [PATCH v8 10/15] dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (8 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 09/15] PCI: cadence: Update PCIe platform to use register offsets passed hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-20  7:23   ` Krzysztof Kozlowski
  2025-08-19 11:52 ` [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID hans.zhang
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

Document the bindings for CIX Sky1 PCIe Controller configured in
root complex mode with five root port.

Supports 4 INTx, MSI and MSI-x interrupts from the ARM GICv3 controller.

Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
Changes for v8:
- Fixed the error issue of DT binding. (Rob and Krzysztof)
- The rcsu register is split into two parts: rcsu_strap and rcsu_status.
---
 .../bindings/pci/cix,sky1-pcie-host.yaml      | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml

diff --git a/Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml b/Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml
new file mode 100644
index 000000000000..b910a42e0843
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/cix,sky1-pcie-host.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CIX Sky1 PCIe Root Complex
+
+maintainers:
+  - Hans Zhang <hans.zhang@cixtech.com>
+
+description:
+  PCIe root complex controller based on the Cadence PCIe core.
+
+allOf:
+  - $ref: /schemas/pci/pci-host-bridge.yaml#
+
+properties:
+  compatible:
+    const: cix,sky1-pcie-host
+
+  reg:
+    items:
+      - description: PCIe controller registers.
+      - description: ECAM registers.
+      - description: Remote CIX System Unit strap registers.
+      - description: Remote CIX System Unit status registers.
+      - description: Region for sending messages registers.
+
+  reg-names:
+    items:
+      - const: reg
+      - const: cfg
+      - const: rcsu_strap
+      - const: rcsu_status
+      - const: msg
+
+  ranges:
+    maxItems: 3
+
+required:
+  - compatible
+  - ranges
+  - bus-range
+  - device_type
+  - interrupt-map
+  - interrupt-map-mask
+  - msi-map
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@a010000 {
+            compatible = "cix,sky1-pcie-host";
+            reg = <0x00 0x0a010000 0x00 0x10000>,
+                  <0x00 0x2c000000 0x00 0x4000000>,
+                  <0x00 0x0a000300 0x00 0x100>,
+                  <0x00 0x0a000400 0x00 0x100>,
+                  <0x00 0x60000000 0x00 0x00100000>;
+            reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
+            ranges = <0x01000000 0x00 0x60100000 0x00 0x60100000 0x00 0x00100000>,
+                     <0x02000000 0x00 0x60200000 0x00 0x60200000 0x00 0x1fe00000>,
+                     <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>;
+            #address-cells = <3>;
+            #size-cells = <2>;
+            bus-range = <0xc0 0xff>;
+            device_type = "pci";
+            #interrupt-cells = <1>;
+            interrupt-map-mask = <0 0 0 0x7>;
+            interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <0 0 0 2 &gic 0 0 GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <0 0 0 3 &gic 0 0 GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <0 0 0 4 &gic 0 0 GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH 0>;
+            msi-map = <0xc000 &gic_its 0xc000 0x4000>;
+        };
+    };
-- 
2.49.0


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

* [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (9 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 10/15] dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-30 13:20   ` Manivannan Sadhasivam
  2025-08-30 13:21   ` Manivannan Sadhasivam
  2025-08-19 11:52 ` [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1 hans.zhang
                   ` (4 subsequent siblings)
  15 siblings, 2 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

Add Cixtech P1 (internal name sky1) as a vendor and device ID for PCI
devices. This ID will be used by the CIX Sky1 PCIe host controller driver.

Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 include/linux/pci_ids.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 92ffc4373f6d..24b04d085920 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2631,6 +2631,9 @@
 
 #define PCI_VENDOR_ID_CXL		0x1e98
 
+#define PCI_VENDOR_ID_CIX		0x1f6c
+#define PCI_DEVICE_ID_CIX_SKY1		0x0001
+
 #define PCI_VENDOR_ID_TEHUTI		0x1fc9
 #define PCI_DEVICE_ID_TEHUTI_3009	0x3009
 #define PCI_DEVICE_ID_TEHUTI_3010	0x3010
-- 
2.49.0


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

* [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (10 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-30 13:29   ` Manivannan Sadhasivam
  2025-08-19 11:52 ` [PATCH v8 13/15] MAINTAINERS: add entry for CIX Sky1 PCIe driver hans.zhang
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

Add driver for the CIX Sky1 SoC PCIe Gen4 16 GT/s controller based
on the Cadence PCIe core.

Supports MSI/MSI-x via GICv3, Single Virtual Channel, Single Function.

Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
Changes for v8:
- Optimization of CIX SKY1 Root Port driver. (Bjorn and Krzysztof)
- Use devm_platform_ioremap_resource_byname.
---
 drivers/pci/controller/cadence/Kconfig    |  15 ++
 drivers/pci/controller/cadence/Makefile   |   1 +
 drivers/pci/controller/cadence/pci-sky1.c | 232 ++++++++++++++++++++++
 3 files changed, 248 insertions(+)
 create mode 100644 drivers/pci/controller/cadence/pci-sky1.c

diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
index 117677a23d68..26a248cdc78a 100644
--- a/drivers/pci/controller/cadence/Kconfig
+++ b/drivers/pci/controller/cadence/Kconfig
@@ -42,6 +42,21 @@ config PCIE_CADENCE_PLAT_EP
 	  endpoint mode. This PCIe controller may be embedded into many
 	  different vendors SoCs.
 
+config PCI_SKY1_HOST
+	tristate "CIX SKY1 PCIe controller (host mode)"
+	depends on OF
+	select PCIE_CADENCE_HOST
+	select PCI_ECAM
+	help
+	  Say Y here if you want to support the CIX SKY1 PCIe platform
+	  controller in host mode. CIX SKY1 PCIe controller uses Cadence
+	  HPA (High Performance Architecture IP [Second generation of
+	  Cadence PCIe IP])
+
+	  This driver requires Cadence PCIe core infrastructure
+	  (PCIE_CADENCE_HOST) and hardware platform adaptation layer
+	  to function.
+
 config PCI_J721E
 	tristate
 	select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index de4ddae7aca4..40d7c6e98b4d 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
+obj-$(CONFIG_PCI_SKY1_HOST) += pci-sky1.o
diff --git a/drivers/pci/controller/cadence/pci-sky1.c b/drivers/pci/controller/cadence/pci-sky1.c
new file mode 100644
index 000000000000..7dd3546275c5
--- /dev/null
+++ b/drivers/pci/controller/cadence/pci-sky1.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe controller driver for CIX's sky1 SoCs
+ *
+ * Author: Hans Zhang <hans.zhang@cixtech.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pci.h>
+#include <linux/pci-ecam.h>
+#include <linux/pci_ids.h>
+
+#include "pcie-cadence.h"
+#include "pcie-cadence-host-common.h"
+
+#define STRAP_REG(n)			((n) * 0x04)
+#define STATUS_REG(n)			((n) * 0x04)
+#define  LINK_TRAINING_ENABLE		BIT(0)
+#define  LINK_COMPLETE			BIT(0)
+
+#define SKY1_IP_REG_BANK		0x1000
+#define SKY1_IP_CFG_CTRL_REG_BANK	0x4c00
+#define SKY1_IP_AXI_MASTER_COMMON	0xf000
+#define SKY1_AXI_SLAVE			0x9000
+#define SKY1_AXI_MASTER			0xb000
+#define SKY1_AXI_HLS_REGISTERS		0xc000
+#define SKY1_AXI_RAS_REGISTERS		0xe000
+#define SKY1_DTI_REGISTERS		0xd000
+
+#define IP_REG_I_DBG_STS_0		0x420
+
+struct sky1_pcie {
+	struct cdns_pcie *cdns_pcie;
+	struct cdns_pcie_rc *cdns_pcie_rc;
+
+	struct resource *cfg_res;
+	struct resource *msg_res;
+	struct pci_config_window *cfg;
+	void __iomem *strap_base;
+	void __iomem *status_base;
+	void __iomem *reg_base;
+	void __iomem *cfg_base;
+	void __iomem *msg_base;
+};
+
+static int sky1_pcie_resource_get(struct platform_device *pdev,
+				  struct sky1_pcie *pcie)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource_byname(pdev, "reg");
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "unable to find reg registers\n");
+	pcie->reg_base = base;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+	if (!res)
+		return dev_err_probe(dev, ENXIO, "unable to get cfg resource\n");
+	pcie->cfg_res = res;
+
+	base = devm_platform_ioremap_resource_byname(pdev, "rcsu_strap");
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "unable to find rcsu strap registers\n");
+	pcie->strap_base = base;
+
+	base = devm_platform_ioremap_resource_byname(pdev, "rcsu_status");
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "unable to find rcsu status registers\n");
+	pcie->status_base = base;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "msg");
+	if (!res)
+		return dev_err_probe(dev, ENXIO, "unable to get msg resource\n");
+	pcie->msg_res = res;
+	pcie->msg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(pcie->msg_base)) {
+		return dev_err_probe(dev, PTR_ERR(pcie->msg_base),
+				     "unable to ioremap msg resource\n");
+	}
+
+	return 0;
+}
+
+static int sky1_pcie_start_link(struct cdns_pcie *cdns_pcie)
+{
+	struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
+	u32 val;
+
+	val = readl(pcie->strap_base + STRAP_REG(1));
+	val |= LINK_TRAINING_ENABLE;
+	writel(val, pcie->strap_base + STRAP_REG(1));
+
+	return 0;
+}
+
+static void sky1_pcie_stop_link(struct cdns_pcie *cdns_pcie)
+{
+	struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
+	u32 val;
+
+	val = readl(pcie->strap_base + STRAP_REG(1));
+	val &= ~LINK_TRAINING_ENABLE;
+	writel(val, pcie->strap_base + STRAP_REG(1));
+}
+
+static bool sky1_pcie_link_up(struct cdns_pcie *cdns_pcie)
+{
+	u32 val;
+
+	val = cdns_pcie_hpa_readl(cdns_pcie, REG_BANK_IP_REG,
+				  IP_REG_I_DBG_STS_0);
+	return val & LINK_COMPLETE;
+}
+
+static const struct cdns_pcie_ops sky1_pcie_ops = {
+	.start_link = sky1_pcie_start_link,
+	.stop_link = sky1_pcie_stop_link,
+	.link_up = sky1_pcie_link_up,
+};
+
+static int sky1_pcie_probe(struct platform_device *pdev)
+{
+	struct cdns_plat_pcie_of_data *reg_off;
+	struct device *dev = &pdev->dev;
+	struct pci_host_bridge *bridge;
+	struct cdns_pcie *cdns_pcie;
+	struct resource_entry *bus;
+	struct cdns_pcie_rc *rc;
+	struct sky1_pcie *pcie;
+	int ret;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge)
+		return -ENOMEM;
+
+	ret = sky1_pcie_resource_get(pdev, pcie);
+	if (ret < 0)
+		return -ENXIO;
+
+	bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+	if (!bus)
+		return -ENODEV;
+
+	pcie->cfg = pci_ecam_create(dev, pcie->cfg_res, bus->res,
+				    &pci_generic_ecam_ops);
+	if (IS_ERR(pcie->cfg))
+		return PTR_ERR(pcie->cfg);
+
+	bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops;
+	rc = pci_host_bridge_priv(bridge);
+	rc->ecam_support_flag = 1;
+	rc->cfg_base = pcie->cfg->win;
+	rc->cfg_res = &pcie->cfg->res;
+
+	cdns_pcie = &rc->pcie;
+	cdns_pcie->dev = dev;
+	cdns_pcie->ops = &sky1_pcie_ops;
+	cdns_pcie->reg_base = pcie->reg_base;
+	cdns_pcie->msg_res = pcie->msg_res;
+	cdns_pcie->is_rc = 1;
+
+	reg_off = devm_kzalloc(dev, sizeof(*reg_off), GFP_KERNEL);
+	if (!reg_off)
+		return -ENOMEM;
+
+	reg_off->ip_reg_bank_offset = SKY1_IP_REG_BANK;
+	reg_off->ip_cfg_ctrl_reg_offset = SKY1_IP_CFG_CTRL_REG_BANK;
+	reg_off->axi_mstr_common_offset = SKY1_IP_AXI_MASTER_COMMON;
+	reg_off->axi_slave_offset = SKY1_AXI_SLAVE;
+	reg_off->axi_master_offset = SKY1_AXI_MASTER;
+	reg_off->axi_hls_offset = SKY1_AXI_HLS_REGISTERS;
+	reg_off->axi_ras_offset = SKY1_AXI_RAS_REGISTERS;
+	reg_off->axi_dti_offset = SKY1_DTI_REGISTERS;
+	cdns_pcie->cdns_pcie_reg_offsets = reg_off;
+
+	pcie->cdns_pcie = cdns_pcie;
+	pcie->cdns_pcie_rc = rc;
+	pcie->cfg_base = rc->cfg_base;
+	bridge->sysdata = pcie->cfg;
+
+	rc->vendor_id = PCI_VENDOR_ID_CIX;
+	rc->device_id = PCI_DEVICE_ID_CIX_SKY1;
+	rc->no_inbound_flag = 1;
+
+	dev_set_drvdata(dev, pcie);
+
+	ret = cdns_pcie_hpa_host_setup(rc);
+	if (ret < 0) {
+		pci_ecam_free(pcie->cfg);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id of_sky1_pcie_match[] = {
+	{ .compatible = "cix,sky1-pcie-host", },
+	{},
+};
+
+static void sky1_pcie_remove(struct platform_device *pdev)
+{
+	struct sky1_pcie *pcie = platform_get_drvdata(pdev);
+
+	pci_ecam_free(pcie->cfg);
+}
+
+static struct platform_driver sky1_pcie_driver = {
+	.probe  = sky1_pcie_probe,
+	.remove = sky1_pcie_remove,
+	.driver = {
+		.name = "sky1-pcie",
+		.of_match_table = of_sky1_pcie_match,
+	},
+};
+module_platform_driver(sky1_pcie_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCIe controller driver for CIX's sky1 SoCs");
+MODULE_AUTHOR("Hans Zhang <hans.zhang@cixtech.com>");
-- 
2.49.0


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

* [PATCH v8 13/15] MAINTAINERS: add entry for CIX Sky1 PCIe driver
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (11 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1 hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-19 11:52 ` [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1 hans.zhang
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

Add myself as maintainer of Sky1 PCIe host driver

Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index daf520a13bdf..95c6acbbdda5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19251,6 +19251,13 @@ S:	Orphan
 F:	Documentation/devicetree/bindings/pci/cdns,*
 F:	drivers/pci/controller/cadence/*cadence*
 
+PCI DRIVER FOR CIX Sky1
+M:	Hans Zhang <hans.zhang@cixtech.com>
+L:	linux-pci@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/cix,sky1-pcie-*.yaml
+F:	drivers/pci/controller/cadence/*sky1*
+
 PCI DRIVER FOR FREESCALE LAYERSCAPE
 M:	Minghuan Lian <minghuan.Lian@nxp.com>
 M:	Mingkai Hu <mingkai.hu@nxp.com>
-- 
2.49.0


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

* [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (12 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 13/15] MAINTAINERS: add entry for CIX Sky1 PCIe driver hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-30 13:31   ` Manivannan Sadhasivam
  2025-08-19 11:52 ` [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board hans.zhang
  2025-08-30 13:38 ` [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers Manivannan Sadhasivam
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

Add pcie_x*_rc node to support Sky1 PCIe driver based on the
Cadence PCIe core.

Supports Gen1/Gen2/Gen3/Gen4, 1/2/4/8 lane, MSI/MSI-x interrupts
using the ARM GICv3.

Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
Changes for v8:
- The rcsu register is split into two parts: rcsu_strap and rcsu_status.
---
 arch/arm64/boot/dts/cix/sky1.dtsi | 126 ++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi
index 7dfe7677e649..26c325d8d934 100644
--- a/arch/arm64/boot/dts/cix/sky1.dtsi
+++ b/arch/arm64/boot/dts/cix/sky1.dtsi
@@ -288,6 +288,132 @@ mbox_ap2sfh: mailbox@80a0000 {
 			cix,mbox-dir = "tx";
 		};
 
+		pcie_x8_rc: pcie@a010000 {
+			compatible = "cix,sky1-pcie-host";
+			reg = <0x00 0x0a010000 0x00 0x10000>,
+			      <0x00 0x2c000000 0x00 0x4000000>,
+			      <0x00 0x0a000300 0x00 0x100>,
+			      <0x00 0x0a000400 0x00 0x100>,
+			      <0x00 0x60000000 0x00 0x00100000>;
+			reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
+			ranges = <0x01000000 0x0 0x60100000 0x0 0x60100000 0x0 0x00100000>,
+				 <0x02000000 0x0 0x60200000 0x0 0x60200000 0x0 0x1fe00000>,
+				 <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0xc0 0xff>;
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 2 &gic 0 0 GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 3 &gic 0 0 GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 4 &gic 0 0 GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH 0>;
+			msi-map = <0xc000 &gic_its 0xc000 0x4000>;
+			status = "disabled";
+		};
+
+		pcie_x4_rc: pcie@a070000 {
+			compatible = "cix,sky1-pcie-host";
+			reg = <0x00 0x0a070000 0x00 0x10000>,
+			      <0x00 0x29000000 0x00 0x3000000>,
+			      <0x00 0x0a060300 0x00 0x40>,
+			      <0x00 0x0a060400 0x00 0x40>,
+			      <0x00 0x50000000 0x00 0x00100000>;
+			reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
+			ranges = <0x01000000 0x00 0x50100000 0x00 0x50100000 0x00 0x00100000>,
+				 <0x02000000 0x00 0x50200000 0x00 0x50200000 0x00 0x0fe00000>,
+				 <0x43000000 0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x90 0xbf>;
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 2 &gic 0 0 GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 3 &gic 0 0 GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 4 &gic 0 0 GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH 0>;
+			msi-map = <0x9000 &gic_its 0x9000 0x3000>;
+			status = "disabled";
+		};
+
+		pcie_x2_rc: pcie@a0c0000 {
+			compatible = "cix,sky1-pcie-host";
+			reg = <0x00 0x0a0c0000 0x00 0x10000>,
+			      <0x00 0x26000000 0x00 0x3000000>,
+			      <0x00 0x0a0600340 0x00 0x20>,
+			      <0x00 0x0a0600440 0x00 0x20>,
+			      <0x00 0x40000000 0x00 0x00100000>;
+			reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
+			ranges = <0x01000000 0x0 0x40100000 0x0 0x40100000 0x0 0x00100000>,
+				 <0x02000000 0x0 0x40200000 0x0 0x40200000 0x0 0x0fe00000>,
+				 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x04 0x00000000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x60 0x8f>;
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 2 &gic 0 0 GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 3 &gic 0 0 GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 4 &gic 0 0 GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH 0>;
+			msi-map = <0x6000 &gic_its 0x6000 0x3000>;
+			status = "disabled";
+		};
+
+		pcie_x1_0_rc: pcie@a0d0000 {
+			compatible = "cix,sky1-pcie-host";
+			reg = <0x00 0x0a0d0000 0x00 0x10000>,
+			      <0x00 0x20000000 0x00 0x3000000>,
+			      <0x00 0x0a060360 0x00 0x20>,
+			      <0x00 0x0a060460 0x00 0x20>,
+			      <0x00 0x30000000 0x00 0x00100000>;
+			reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
+			ranges = <0x01000000 0x0 0x30100000 0x0 0x30100000 0x0 0x00100000>,
+				 <0x02000000 0x0 0x30200000 0x0 0x30200000 0x0 0x07e00000>,
+				 <0x43000000 0x08 0x00000000 0x08 0x00000000 0x04 0x00000000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0x2f>;
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 2 &gic 0 0 GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 3 &gic 0 0 GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 4 &gic 0 0 GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH 0>;
+			msi-map = <0x0000 &gic_its 0x0000 0x3000>;
+			status = "disabled";
+		};
+
+		pcie_x1_1_rc: pcie@a0e0000 {
+			compatible = "cix,sky1-pcie-host";
+			reg = <0x00 0x0a0e0000 0x00 0x10000>,
+			      <0x00 0x23000000 0x00 0x3000000>,
+			      <0x00 0x0a060380 0x00 0x20>,
+			      <0x00 0x0a060480 0x00 0x20>,
+			      <0x00 0x38000000 0x00 0x00100000>;
+			reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
+			ranges = <0x01000000 0x0 0x38100000 0x0 0x38100000 0x0 0x00100000>,
+				 <0x02000000 0x0 0x38200000 0x0 0x38200000 0x0 0x07e00000>,
+				 <0x43000000 0x0C 0x00000000 0x0C 0x00000000 0x04 0x00000000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x30 0x5f>;
+			device_type = "pci";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 2 &gic 0 0 GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 3 &gic 0 0 GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH 0>,
+					<0 0 0 4 &gic 0 0 GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH 0>;
+			msi-map = <0x3000 &gic_its 0x3000 0x3000>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller@e010000 {
 			compatible = "arm,gic-v3";
 			reg = <0x0 0x0e010000 0 0x10000>,	/* GICD */
-- 
2.49.0


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

* [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (13 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1 hans.zhang
@ 2025-08-19 11:52 ` hans.zhang
  2025-08-30 13:33   ` Manivannan Sadhasivam
  2025-08-30 13:38 ` [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers Manivannan Sadhasivam
  15 siblings, 1 reply; 39+ messages in thread
From: hans.zhang @ 2025-08-19 11:52 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

From: Hans Zhang <hans.zhang@cixtech.com>

Add PCIe RC support on Orion O6 board.

Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
Dear Krzysztof,

Due to the fact that the GPIO, PINCTRL and other modules of our platform are
not yet ready for upstream. Attributes that PCIe depends on, such as reset-gpios
and pinctrl*, have not been added for the time being. It will be added gradually
in the future.

The following are Arnd's previous comments. We can go to upsteam separately.
https://lore.kernel.org/all/422deb4d-db29-48c1-b0c9-7915951df500@app.fastmail.com/
---
 arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
index d74964d53c3b..be3ec4f5d11e 100644
--- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
+++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
@@ -34,6 +34,26 @@ linux,cma {
 
 };
 
+&pcie_x8_rc {
+	status = "okay";
+};
+
+&pcie_x4_rc {
+	status = "okay";
+};
+
+&pcie_x2_rc {
+	status = "okay";
+};
+
+&pcie_x1_0_rc {
+	status = "okay";
+};
+
+&pcie_x1_1_rc {
+	status = "okay";
+};
+
 &uart2 {
 	status = "okay";
 };
-- 
2.49.0


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

* Re: [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA)
  2025-08-19 11:52 ` [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA) hans.zhang
@ 2025-08-19 17:36   ` ALOK TIWARI
  2025-08-20  8:14     ` Manikandan Karunakaran Pillai
  0 siblings, 1 reply; 39+ messages in thread
From: ALOK TIWARI @ 2025-08-19 17:36 UTC (permalink / raw)
  To: hans.zhang, bhelgaas, lpieralisi, kw, mani, robh, kwilczynski,
	krzk+dt, conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 8/19/2025 5:22 PM, hans.zhang@cixtech.com wrote:
> +#define HPA_LM_RC_BAR_CFG_CTRL_DISABLED(bar)                \
> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_DISABLED << ((bar) * 10))
> +#define HPA_LM_RC_BAR_CFG_CTRL_IO_32BITS(bar)               \
> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_IO_32BITS << ((bar) * 10))
> +#define HPA_LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar)              \
> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_32BITS << ((bar) * 10))
> +#define HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) \
> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS << ((bar) * 10))
> +#define HPA_LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar)              \
> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_64BITS << ((bar) * 10))
> +#define HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) \
> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS << ((bar) * 10))
> +#define HPA_LM_RC_BAR_CFG_APERTURE(bar, aperture)           \
> +		(((aperture) - 7) << ((bar) * 10))
> +
> +#define CDNS_PCIE_HPA_LM_PTM_CTRL		0x0520
> +#define CDNS_PCIE_HPA_LM_TPM_CTRL_PTMRSEN	BIT(17)

Is that TPM intentional or a typo?

Thanks,
Alok

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

* Re: [PATCH v8 05/15] PCI: cadence: Move PCIe EP common functions to a separate file
  2025-08-19 11:52 ` [PATCH v8 05/15] PCI: cadence: Move PCIe EP common functions to a separate file hans.zhang
@ 2025-08-19 17:46   ` ALOK TIWARI
  0 siblings, 0 replies; 39+ messages in thread
From: ALOK TIWARI @ 2025-08-19 17:46 UTC (permalink / raw)
  To: hans.zhang, bhelgaas, lpieralisi, kw, mani, robh, kwilczynski,
	krzk+dt, conor+dt
  Cc: mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 8/19/2025 5:22 PM, hans.zhang@cixtech.com wrote:
> +u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn)
> +{
> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
> +	u32 first_vf_offset, stride;
> +
> +	if (vfn == 0)
> +		return fn;
> +
> +	first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET);
> +	stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +  PCI_SRIOV_VF_STRIDE);

extra space before PCI_SRIOV_VF_STRIDE.
It is from old code, but since this line is touched, better to remove it.

> +	fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +
> +	return fn;
> +}


Thanks,
Alok

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

* Re: [PATCH v8 10/15] dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings
  2025-08-19 11:52 ` [PATCH v8 10/15] dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings hans.zhang
@ 2025-08-20  7:23   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 39+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-20  7:23 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, mani, robh, kwilczynski, krzk+dt,
	conor+dt, mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:34PM +0800, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> Document the bindings for CIX Sky1 PCIe Controller configured in
> root complex mode with five root port.
> 
> Supports 4 INTx, MSI and MSI-x interrupts from the ARM GICv3 controller.
> 
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
> Changes for v8:
> - Fixed the error issue of DT binding. (Rob and Krzysztof)
> - The rcsu register is split into two parts: rcsu_strap and rcsu_status.
> ---
>  .../bindings/pci/cix,sky1-pcie-host.yaml      | 83 +++++++++++++++++++
>  1 file changed, 83 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


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

* RE: [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA)
  2025-08-19 17:36   ` ALOK TIWARI
@ 2025-08-20  8:14     ` Manikandan Karunakaran Pillai
  0 siblings, 0 replies; 39+ messages in thread
From: Manikandan Karunakaran Pillai @ 2025-08-20  8:14 UTC (permalink / raw)
  To: ALOK TIWARI, hans.zhang@cixtech.com, bhelgaas@google.com,
	lpieralisi@kernel.org, kw@linux.com, mani@kernel.org,
	robh@kernel.org, kwilczynski@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org
  Cc: fugang.duan@cixtech.com, guoyin.chen@cixtech.com,
	peter.chen@cixtech.com, cix-kernel-upstream@cixtech.com,
	linux-pci@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org

>
>
>
>On 8/19/2025 5:22 PM, hans.zhang@cixtech.com wrote:
>> +#define HPA_LM_RC_BAR_CFG_CTRL_DISABLED(bar)                \
>> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_DISABLED << ((bar) *
>10))
>> +#define HPA_LM_RC_BAR_CFG_CTRL_IO_32BITS(bar)               \
>> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_IO_32BITS << ((bar) *
>10))
>> +#define HPA_LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar)              \
>> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_32BITS << ((bar)
>* 10))
>> +#define HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) \
>> +
>	(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS <<
>((bar) * 10))
>> +#define HPA_LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar)              \
>> +		(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_MEM_64BITS << ((bar)
>* 10))
>> +#define HPA_LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) \
>> +
>	(CDNS_PCIE_HPA_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS <<
>((bar) * 10))
>> +#define HPA_LM_RC_BAR_CFG_APERTURE(bar, aperture)           \
>> +		(((aperture) - 7) << ((bar) * 10))
>> +
>> +#define CDNS_PCIE_HPA_LM_PTM_CTRL		0x0520
>> +#define CDNS_PCIE_HPA_LM_TPM_CTRL_PTMRSEN	BIT(17)
>
>Is that TPM intentional or a typo?
>

Thanks Alok for your comments. It is not intentional but it was copied from an earlier available code 
and is used across HPA and Legacy code. I will submit a bug fix patch later for fixing this issue. 

>Thanks,
>Alok

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

* Re: [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller
  2025-08-19 11:52 ` [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller hans.zhang
@ 2025-08-26 12:08   ` kernel test robot
  2025-08-30 13:18   ` Manivannan Sadhasivam
  1 sibling, 0 replies; 39+ messages in thread
From: kernel test robot @ 2025-08-26 12:08 UTC (permalink / raw)
  To: hans.zhang, bhelgaas, lpieralisi, kw, mani, robh, kwilczynski,
	krzk+dt, conor+dt
  Cc: oe-kbuild-all, mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel,
	Hans Zhang

Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on be48bcf004f9d0c9207ff21d0edb3b42f253829e]

url:    https://github.com/intel-lab-lkp/linux/commits/hans-zhang-cixtech-com/PCI-cadence-Add-module-support-for-platform-controller-driver/20250819-200002
base:   be48bcf004f9d0c9207ff21d0edb3b42f253829e
patch link:    https://lore.kernel.org/r/20250819115239.4170604-9-hans.zhang%40cixtech.com
patch subject: [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller
config: powerpc-randconfig-001-20250826 (https://download.01.org/0day-ci/archive/20250826/202508261955.U9IomdXb-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250826/202508261955.U9IomdXb-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508261955.U9IomdXb-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from <command-line>:
   drivers/pci/controller/cadence/pcie-cadence-hpa.c: In function 'cdns_pcie_hpa_set_outbound_region':
>> include/linux/compiler_types.h:572:38: error: call to '__compiletime_assert_488' declared with attribute error: FIELD_PREP: value too large for the field
     _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                                         ^
   include/linux/compiler_types.h:553:4: note: in definition of macro '__compiletime_assert'
       prefix ## suffix();    \
       ^~~~~~
   include/linux/compiler_types.h:572:2: note: in expansion of macro '_compiletime_assert'
     _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
     ^~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
    #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
                                        ^~~~~~~~~~~~~~~~~~
   include/linux/bitfield.h:68:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
      BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?  \
      ^~~~~~~~~~~~~~~~
   include/linux/bitfield.h:115:3: note: in expansion of macro '__BF_FIELD_CHECK'
      __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
      ^~~~~~~~~~~~~~~~
   drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h:147:2: note: in expansion of macro 'FIELD_PREP'
     FIELD_PREP(CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS_MASK, ((nbits) - 1))
     ^~~~~~~~~~
   drivers/pci/controller/cadence/pcie-cadence-hpa.c:129:10: note: in expansion of macro 'CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS'
     addr0 = CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/__compiletime_assert_488 +572 include/linux/compiler_types.h

eb5c2d4b45e3d2 Will Deacon 2020-07-21  558  
eb5c2d4b45e3d2 Will Deacon 2020-07-21  559  #define _compiletime_assert(condition, msg, prefix, suffix) \
eb5c2d4b45e3d2 Will Deacon 2020-07-21  560  	__compiletime_assert(condition, msg, prefix, suffix)
eb5c2d4b45e3d2 Will Deacon 2020-07-21  561  
eb5c2d4b45e3d2 Will Deacon 2020-07-21  562  /**
eb5c2d4b45e3d2 Will Deacon 2020-07-21  563   * compiletime_assert - break build and emit msg if condition is false
eb5c2d4b45e3d2 Will Deacon 2020-07-21  564   * @condition: a compile-time constant condition to check
eb5c2d4b45e3d2 Will Deacon 2020-07-21  565   * @msg:       a message to emit if condition is false
eb5c2d4b45e3d2 Will Deacon 2020-07-21  566   *
eb5c2d4b45e3d2 Will Deacon 2020-07-21  567   * In tradition of POSIX assert, this macro will break the build if the
eb5c2d4b45e3d2 Will Deacon 2020-07-21  568   * supplied condition is *false*, emitting the supplied error message if the
eb5c2d4b45e3d2 Will Deacon 2020-07-21  569   * compiler has support to do so.
eb5c2d4b45e3d2 Will Deacon 2020-07-21  570   */
eb5c2d4b45e3d2 Will Deacon 2020-07-21  571  #define compiletime_assert(condition, msg) \
eb5c2d4b45e3d2 Will Deacon 2020-07-21 @572  	_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
eb5c2d4b45e3d2 Will Deacon 2020-07-21  573  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v8 06/15] PCI: cadence: Move PCIe RP common functions to a separate file
  2025-08-19 11:52 ` [PATCH v8 06/15] PCI: cadence: Move PCIe RP " hans.zhang
@ 2025-08-30 10:36   ` Manivannan Sadhasivam
  2025-09-01  4:30     ` Manikandan Karunakaran Pillai
  0 siblings, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 10:36 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:30PM GMT, hans.zhang@cixtech.com wrote:
> From: Manikandan K Pillai <mpillai@cadence.com>
> 
> Move the Cadence PCIe controller RP common functions into a separate
> file. The common library functions are split from legacy PCIe RP controller
> functions to a separate file.
> 
> Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
> Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
>  drivers/pci/controller/cadence/Makefile       |   2 +-
>  .../cadence/pcie-cadence-host-common.c        | 179 ++++++++++++++++++
>  .../cadence/pcie-cadence-host-common.h        |  24 +++
>  .../controller/cadence/pcie-cadence-host.c    | 156 +--------------
>  4 files changed, 205 insertions(+), 156 deletions(-)
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.h
> 
> diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
> index 80c1c4be7e80..e45f72388bbb 100644
> --- a/drivers/pci/controller/cadence/Makefile
> +++ b/drivers/pci/controller/cadence/Makefile
> @@ -1,6 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
> -obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
>  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>  obj-$(CONFIG_PCI_J721E) += pci-j721e.o
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
> new file mode 100644
> index 000000000000..d34f8c7c49f0
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
> @@ -0,0 +1,179 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe host controller driver.

This should be changed to 'Cadence PCIe host controller library'. For
completeness, you should add the 'Author' tag also.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as a separate file
  2025-08-19 11:52 ` [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as " hans.zhang
@ 2025-08-30 11:21   ` Manivannan Sadhasivam
  2025-09-01  4:30     ` Manikandan Karunakaran Pillai
  0 siblings, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 11:21 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:31PM GMT, hans.zhang@cixtech.com wrote:
> From: Manikandan K Pillai <mpillai@cadence.com>
> 
> Move the functions for platform common tasks to a separate file. The
> common library functions and functions specific to platform are
> now in different files.
> 

Why do we have too many library files? What is the need to split
pcie-cadence-common.c which itself is a library?

> Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
> Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
>  drivers/pci/controller/cadence/Makefile       |   2 +-
>  .../controller/cadence/pcie-cadence-common.c  | 141 ++++++++++++++++++
>  drivers/pci/controller/cadence/pcie-cadence.c | 129 ----------------
>  3 files changed, 142 insertions(+), 130 deletions(-)
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-common.c
> 
> diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
> index e45f72388bbb..b104562fb86a 100644
> --- a/drivers/pci/controller/cadence/Makefile
> +++ b/drivers/pci/controller/cadence/Makefile
> @@ -1,5 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
> +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
>  obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
>  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-common.c b/drivers/pci/controller/cadence/pcie-cadence-common.c
> new file mode 100644
> index 000000000000..e14d53d64bf1
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pcie-cadence-common.c
> @@ -0,0 +1,141 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe controller driver.
> +// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>

We use below style for multi line comments:

	/*
	 *
	 */

So even though this style existed, you should change it in all new files.

> +
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +
> +#include "pcie-cadence.h"
> +
> +void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
> +{
> +	int i = pcie->phy_count;
> +
> +	while (i--) {
> +		phy_power_off(pcie->phy[i]);
> +		phy_exit(pcie->phy[i]);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(cdns_pcie_disable_phy);
> +
> +int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
> +{
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < pcie->phy_count; i++) {
> +		ret = phy_init(pcie->phy[i]);
> +		if (ret < 0)
> +			goto err_phy;
> +
> +		ret = phy_power_on(pcie->phy[i]);
> +		if (ret < 0) {
> +			phy_exit(pcie->phy[i]);
> +			goto err_phy;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_phy:
> +	while (--i >= 0) {
> +		phy_power_off(pcie->phy[i]);
> +		phy_exit(pcie->phy[i]);
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(cdns_pcie_enable_phy);
> +
> +int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
> +{
> +	struct device_node *np = dev->of_node;
> +	int phy_count;
> +	struct phy **phy;
> +	struct device_link **link;
> +	int i;
> +	int ret;
> +	const char *name;
> +
> +	phy_count = of_property_count_strings(np, "phy-names");
> +	if (phy_count < 1) {
> +		dev_info(dev, "no \"phy-names\" property found; PHY will not be initialized\n");
> +		pcie->phy_count = 0;
> +		return 0;
> +	}
> +
> +	phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL);
> +	if (!phy)
> +		return -ENOMEM;
> +
> +	link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL);
> +	if (!link)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < phy_count; i++) {
> +		of_property_read_string_index(np, "phy-names", i, &name);
> +		phy[i] = devm_phy_get(dev, name);
> +		if (IS_ERR(phy[i])) {
> +			ret = PTR_ERR(phy[i]);
> +			goto err_phy;
> +		}
> +		link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
> +		if (!link[i]) {
> +			devm_phy_put(dev, phy[i]);
> +			ret = -EINVAL;
> +			goto err_phy;
> +		}
> +	}
> +
> +	pcie->phy_count = phy_count;
> +	pcie->phy = phy;
> +	pcie->link = link;
> +
> +	ret =  cdns_pcie_enable_phy(pcie);

Double space after =

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller
  2025-08-19 11:52 ` [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller hans.zhang
  2025-08-26 12:08   ` kernel test robot
@ 2025-08-30 13:18   ` Manivannan Sadhasivam
  2025-09-01  4:34     ` Manikandan Karunakaran Pillai
  1 sibling, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:18 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:32PM GMT, hans.zhang@cixtech.com wrote:
> From: Manikandan K Pillai <mpillai@cadence.com>
> 
> Add support for Cadence PCIe RP and EP configuration for High
> Performance Architecture (HPA) controllers.
> 

Add more info about the controller.

> Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
> Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
>  drivers/pci/controller/cadence/Makefile       |  10 +-
>  .../controller/cadence/pcie-cadence-ep-hpa.c  | 528 ++++++++++++++++
>  .../cadence/pcie-cadence-host-hpa.c           | 585 ++++++++++++++++++
>  .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++

That's a combined 1200+ loc in a single patch, which is very difficult to
review. You should've split it into atleast two.

>  drivers/pci/controller/cadence/pcie-cadence.c |  11 +
>  drivers/pci/controller/cadence/pcie-cadence.h |  74 ++-
>  6 files changed, 1403 insertions(+), 9 deletions(-)
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c
> 
> diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
> index b104562fb86a..de4ddae7aca4 100644
> --- a/drivers/pci/controller/cadence/Makefile
> +++ b/drivers/pci/controller/cadence/Makefile
> @@ -1,6 +1,10 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
> -obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
> -obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
> +pcie-cadence-mod-y := pcie-cadence-hpa.o pcie-cadence-common.o pcie-cadence.o
> +pcie-cadence-host-mod-y := pcie-cadence-host-common.o pcie-cadence-host.o pcie-cadence-host-hpa.o
> +pcie-cadence-ep-mod-y := pcie-cadence-ep-common.o pcie-cadence-ep.o pcie-cadence-ep-hpa.o
> +
> +obj-$(CONFIG_PCIE_CADENCE) = pcie-cadence-mod.o
> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
> +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>  obj-$(CONFIG_PCI_J721E) += pci-j721e.o
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
> new file mode 100644
> index 000000000000..a5366ecec34f
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
> @@ -0,0 +1,528 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe endpoint controller driver.
> +// Author: Manikandan K Pillai  <mpillai@cadence.com>
> +
> +#include <linux/bitfield.h>
> +#include <linux/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +#include <linux/pci-epc.h>
> +#include <linux/platform_device.h>
> +#include <linux/sizes.h>
> +
> +#include "pcie-cadence.h"
> +#include "pcie-cadence-ep-common.h"
> +
> +static int cdns_pcie_hpa_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
> +				     phys_addr_t addr, u64 pci_addr, size_t size)
> +{
> +	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 r;
> +
> +	r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
> +	if (r >= ep->max_regions - 1) {
> +		dev_err(&epc->dev, "no free outbound region\n");
> +		return -EINVAL;

-ENOSPC

> +	}
> +
> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> +	cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size);
> +
> +	set_bit(r, &ep->ob_region_map);
> +	ep->ob_addr[r] = addr;
> +
> +	return 0;
> +}
> +
> +static void cdns_pcie_hpa_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
> +					phys_addr_t addr)
> +{
> +	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 r;
> +
> +	for (r = 0; r < ep->max_regions - 1; r++)
> +		if (ep->ob_addr[r] == addr)
> +			break;
> +
> +	if (r == ep->max_regions - 1)
> +		return;
> +
> +	cdns_pcie_hpa_reset_outbound_region(pcie, r);
> +
> +	ep->ob_addr[r] = 0;
> +	clear_bit(r, &ep->ob_region_map);
> +}
> +
> +static void cdns_pcie_hpa_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
> +					 bool assert)
> +{
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	unsigned long flags;
> +	u32 offset;
> +	u16 status;
> +	u8 msg_code;
> +
> +	intx &= 3;
> +
> +	/* Set the outbound region if needed */
> +	if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
> +		     ep->irq_pci_fn != fn)) {
> +		/* First region was reserved for IRQ writes */
> +		cdns_pcie_hpa_set_outbound_region_for_normal_msg(pcie, 0, fn, 0, ep->irq_phys_addr);
> +		ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
> +		ep->irq_pci_fn = fn;
> +	}
> +
> +	if (assert) {
> +		ep->irq_pending |= BIT(intx);
> +		msg_code = PCIE_MSG_CODE_ASSERT_INTA + intx;
> +	} else {
> +		ep->irq_pending &= ~BIT(intx);
> +		msg_code = PCIE_MSG_CODE_DEASSERT_INTA + intx;
> +	}
> +
> +	spin_lock_irqsave(&ep->lock, flags);
> +	status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS);
> +	if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) {
> +		status ^= PCI_STATUS_INTERRUPT;
> +		cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status);
> +	}
> +	spin_unlock_irqrestore(&ep->lock, flags);
> +
> +	offset = CDNS_PCIE_NORMAL_MSG_ROUTING(PCIE_MSG_TYPE_R_RC) |
> +		 CDNS_PCIE_NORMAL_MSG_CODE(msg_code);
> +	writel(0, ep->irq_cpu_addr + offset);
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_intx_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
> +					   u8 intx)
> +{
> +	u16 cmd;
> +
> +	cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND);
> +	if (cmd & PCI_COMMAND_INTX_DISABLE)
> +		return -EINVAL;
> +
> +	cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, true);
> +
> +	/* The mdelay() value was taken from dra7xx_pcie_raise_intx_irq() */
> +	mdelay(1);

AFAIK, this 1ms delay is not fixed per the PCIe spec. It depends on how the host
interrupt controller detects the level triggered interrupt. So I don't think
this 1ms delay will work with all host systems.

> +	cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, false);
> +	return 0;
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
> +					  u8 interrupt_num)
> +{
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
> +	u16 flags, mme, data, data_mask;
> +	u8 msi_count;
> +	u64 pci_addr, pci_addr_mask = 0xff;
> +
> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> +
> +	/* Check whether the MSI feature has been enabled by the PCI host */
> +	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
> +	if (!(flags & PCI_MSI_FLAGS_ENABLE))
> +		return -EINVAL;

-EOPNOTSUPP

> +
> +	/* Get the number of enabled MSIs */
> +	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
> +	msi_count = 1 << mme;
> +	if (!interrupt_num || interrupt_num > msi_count)
> +		return -EINVAL;
> +
> +	/* Compute the data value to be written */
> +	data_mask = msi_count - 1;
> +	data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
> +	data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
> +
> +	/* Get the PCI address where to write the data into */
> +	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
> +	pci_addr <<= 32;
> +	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
> +	pci_addr &= GENMASK_ULL(63, 2);
> +
> +	/* Set the outbound region if needed */
> +	if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
> +		     ep->irq_pci_fn != fn)) {
> +		/* First region was reserved for IRQ writes */
> +		cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
> +						  false,
> +						  ep->irq_phys_addr,
> +						  pci_addr & ~pci_addr_mask,
> +						  pci_addr_mask + 1);
> +		ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
> +		ep->irq_pci_fn = fn;
> +	}
> +	writel(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
> +
> +	return 0;
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
> +					   u16 interrupt_num)
> +{
> +	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
> +	u32 tbl_offset, msg_data, reg;
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	struct pci_epf_msix_tbl *msix_tbl;
> +	struct cdns_pcie_epf *epf;
> +	u64 pci_addr_mask = 0xff;
> +	u64 msg_addr;
> +	u16 flags;
> +	u8 bir;
> +
> +	epf = &ep->epf[fn];
> +	if (vfn > 0)
> +		epf = &epf->epf[vfn - 1];
> +
> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> +
> +	/* Check whether the MSI-X feature has been enabled by the PCI host */
> +	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
> +	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
> +		return -EINVAL;

-EOPNOTSUPP

> +
> +	reg = cap + PCI_MSIX_TABLE;
> +	tbl_offset = cdns_pcie_ep_fn_readl(pcie, fn, reg);
> +	bir = FIELD_GET(PCI_MSIX_TABLE_BIR, tbl_offset);
> +	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
> +
> +	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
> +	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
> +	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
> +
> +	/* Set the outbound region if needed */
> +	if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
> +	    ep->irq_pci_fn != fn) {
> +		/* First region was reserved for IRQ writes */
> +		cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
> +						  false,
> +						  ep->irq_phys_addr,
> +						  msg_addr & ~pci_addr_mask,
> +						  pci_addr_mask + 1);
> +		ep->irq_pci_addr = (msg_addr & ~pci_addr_mask);
> +		ep->irq_pci_fn = fn;
> +	}
> +	writel(msg_data, ep->irq_cpu_addr + (msg_addr & pci_addr_mask));
> +
> +	return 0;
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
> +				      unsigned int type, u16 interrupt_num)
> +{
> +	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	struct device *dev = pcie->dev;
> +
> +	switch (type) {
> +	case PCI_IRQ_INTX:
> +		if (vfn > 0) {
> +			dev_err(dev, "Cannot raise INTX interrupts for VF\n");
> +			return -EINVAL;

-EOPNOTSUPP

> +		}
> +		return cdns_pcie_hpa_ep_raise_intx_irq(ep, fn, vfn, 0);
> +

No need of newline

> +	case PCI_IRQ_MSI:
> +		return cdns_pcie_hpa_ep_raise_msi_irq(ep, fn, vfn, interrupt_num);
> +
> +	case PCI_IRQ_MSIX:
> +		return cdns_pcie_hpa_ep_raise_msix_irq(ep, fn, vfn, interrupt_num);
> +
> +	default:
> +		break;
> +	}
> +
> +	return -EINVAL;
> +}
> +

[...]

> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
> new file mode 100644
> index 000000000000..b2e570f2c047
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
> @@ -0,0 +1,585 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe host controller driver.
> +// Author: Manikandan K Pillai <mpillai@cadence.com>
> +
> +#include <linux/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/list_sort.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
> +#include <linux/platform_device.h>
> +
> +#include "pcie-cadence.h"
> +#include "pcie-cadence-host-common.h"
> +
> +static u8 bar_aperture_mask[] = {
> +	[RP_BAR0] = 0x1F,
> +	[RP_BAR1] = 0xF,

Use lowercase for hex.

> +};
> +

[...]

> +static void cdns_pcie_hpa_create_region_for_ecam(struct cdns_pcie_rc *rc)
> +{
> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
> +	struct resource *cfg_res = rc->cfg_res;
> +	struct cdns_pcie *pcie = &rc->pcie;
> +	u32 value, root_port_req_id_reg, pcie_bus_number_reg;
> +	u32 ecam_addr_0, region_size_0, request_id_0;
> +	int busnr = 0, secbus = 0, subbus = 0;
> +	struct resource_entry *entry;
> +	resource_size_t size;
> +	u32 axi_address_low;
> +	int nbits;
> +	u64 sz;
> +
> +	entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
> +	if (entry) {
> +		busnr = entry->res->start;
> +		secbus = (busnr < 0xff) ? (busnr + 1) : 0xff;
> +		subbus = entry->res->end;
> +	}
> +	size = resource_size(cfg_res);
> +	sz = 1ULL << fls64(size - 1);
> +	nbits = ilog2(sz);
> +	if (nbits < 8)
> +		nbits = 8;
> +
> +	root_port_req_id_reg = ((busnr & 0xff) << 8);
> +	pcie_bus_number_reg = ((subbus & 0xff) << 16) | ((secbus & 0xff) << 8) |
> +			      (busnr & 0xff);
> +	ecam_addr_0 = cfg_res->start;
> +	region_size_0 = nbits - 1;
> +	request_id_0 = ((busnr & 0xff) << 8);
> +
> +#define CDNS_PCIE_HPA_TAG_MANAGEMENT (0x0)

Do not use inline definitions. Define them at the start of the file.

> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_TAG_MANAGEMENT, 0x200000);
> +
> +	/* Taking slave err as OKAY */
> +#define CDNS_PCIE_HPA_SLAVE_RESP (0x100)
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, CDNS_PCIE_HPA_SLAVE_RESP,
> +			     0x0);
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_SLAVE_RESP + 0x4, 0x0);
> +
> +	/* Program the register "i_root_port_req_id_reg" with RP's BDF */
> +#define I_ROOT_PORT_REQ_ID_REG (0x141c)
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, I_ROOT_PORT_REQ_ID_REG,
> +			     root_port_req_id_reg);
> +
> +	/**
> +	 * Program the register "i_pcie_bus_numbers" with Primary(RP's bus number),
> +	 * secondary and subordinate bus numbers
> +	 */
> +#define I_PCIE_BUS_NUMBERS (CDNS_PCIE_HPA_RP_BASE + 0x18)
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_RP, I_PCIE_BUS_NUMBERS,
> +			     pcie_bus_number_reg);
> +
> +	/* Program the register "lm_hal_sbsa_ctrl[0]" to enable the sbsa */
> +#define LM_HAL_SBSA_CTRL (0x1170)
> +	value = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL);
> +	value |= BIT(0);
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL, value);
> +
> +	/* Program region[0] for ECAM */
> +	axi_address_low = (ecam_addr_0 & 0xfff00000) | region_size_0;
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(0),
> +			     axi_address_low);
> +
> +	/* rc0-high-axi-address */
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(0), 0x0);
> +	/* Type-1 CFG */
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(0), 0x05000000);
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0),
> +			     (request_id_0 << 16));
> +
> +	/* All AXI bits pass through PCIe */
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(0), 0x1b);
> +	/* PCIe address-high */
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(0), 0);
> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> +			     CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(0), 0x06000000);
> +}

[...]

> +int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc)
> +{
> +	struct cdns_pcie *pcie = &rc->pcie;
> +	struct device *dev = rc->pcie.dev;
> +	int ret;
> +
> +	if (rc->quirk_detect_quiet_flag)
> +		cdns_pcie_hpa_detect_quiet_min_delay_set(&rc->pcie);
> +
> +	cdns_pcie_hpa_host_enable_ptm_response(pcie);
> +
> +	ret = cdns_pcie_start_link(pcie);
> +	if (ret) {
> +		dev_err(dev, "Failed to start link\n");
> +		return ret;
> +	}
> +
> +	ret = cdns_pcie_hpa_host_start_link(rc);
> +	if (ret)
> +		dev_dbg(dev, "PCIe link never came up\n");

You are not supposed to fail the probe if link doesn't come up.

> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_link_setup);
> +

[...]

> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index 1174cf597bb0..f2eb3f09b21a 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -7,6 +7,7 @@
>  #define _PCIE_CADENCE_H
>  
>  #include <linux/kernel.h>
> +#include <linux/module.h>
>  #include <linux/pci.h>
>  #include <linux/pci-epf.h>
>  #include <linux/phy/phy.h>
> @@ -42,9 +43,9 @@ enum cdns_pcie_reg_bank {
>  };
>  
>  struct cdns_pcie_ops {
> -	int	(*start_link)(struct cdns_pcie *pcie);
> -	void	(*stop_link)(struct cdns_pcie *pcie);
> -	bool	(*link_up)(struct cdns_pcie *pcie);
> +	int     (*start_link)(struct cdns_pcie *pcie);
> +	void    (*stop_link)(struct cdns_pcie *pcie);
> +	bool    (*link_up)(struct cdns_pcie *pcie);
>  	u64     (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
>  };
>  
> @@ -76,6 +77,7 @@ struct cdns_plat_pcie_of_data {
>   * struct cdns_pcie - private data for Cadence PCIe controller drivers
>   * @reg_base: IO mapped register base
>   * @mem_res: start/end offsets in the physical system memory to map PCI accesses
> + * @msg_res: Region for send message to map PCI accesses
>   * @dev: PCIe controller
>   * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
>   * @phy_count: number of supported PHY devices
> @@ -88,6 +90,7 @@ struct cdns_plat_pcie_of_data {
>  struct cdns_pcie {
>  	void __iomem		             *reg_base;
>  	struct resource		             *mem_res;
> +	struct resource                      *msg_res;
>  	struct device		             *dev;
>  	bool			             is_rc;
>  	int			             phy_count;
> @@ -110,6 +113,7 @@ struct cdns_pcie {
>   *                available
>   * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
>   * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
> + * @ecam_support_flag: Whether the ECAM flag is supported
>   */
>  struct cdns_pcie_rc {
>  	struct cdns_pcie	pcie;
> @@ -120,6 +124,8 @@ struct cdns_pcie_rc {
>  	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
>  	unsigned int		quirk_retrain_flag:1;
>  	unsigned int		quirk_detect_quiet_flag:1;
> +	unsigned int            ecam_support_flag:1;

ecam_supported

> +	unsigned int		no_inbound_flag:1;

no_inbound_map

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID
  2025-08-19 11:52 ` [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID hans.zhang
@ 2025-08-30 13:20   ` Manivannan Sadhasivam
  2025-08-30 13:21   ` Manivannan Sadhasivam
  1 sibling, 0 replies; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:20 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:35PM GMT, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> Add Cixtech P1 (internal name sky1) as a vendor and device ID for PCI
> devices. This ID will be used by the CIX Sky1 PCIe host controller driver.
> 
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>

Acked-by: Manivannan Sadhasivam <mani@kernel.org>

- Mani

> ---
>  include/linux/pci_ids.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> index 92ffc4373f6d..24b04d085920 100644
> --- a/include/linux/pci_ids.h
> +++ b/include/linux/pci_ids.h
> @@ -2631,6 +2631,9 @@
>  
>  #define PCI_VENDOR_ID_CXL		0x1e98
>  
> +#define PCI_VENDOR_ID_CIX		0x1f6c
> +#define PCI_DEVICE_ID_CIX_SKY1		0x0001
> +
>  #define PCI_VENDOR_ID_TEHUTI		0x1fc9
>  #define PCI_DEVICE_ID_TEHUTI_3009	0x3009
>  #define PCI_DEVICE_ID_TEHUTI_3010	0x3010
> -- 
> 2.49.0
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID
  2025-08-19 11:52 ` [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID hans.zhang
  2025-08-30 13:20   ` Manivannan Sadhasivam
@ 2025-08-30 13:21   ` Manivannan Sadhasivam
  2025-09-01  3:03     ` Hans Zhang
  1 sibling, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:21 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:35PM GMT, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> Add Cixtech P1 (internal name sky1) as a vendor and device ID for PCI
> devices. This ID will be used by the CIX Sky1 PCIe host controller driver.

Nit: Use CIX everywhere.

- Mani

> 
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
>  include/linux/pci_ids.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> index 92ffc4373f6d..24b04d085920 100644
> --- a/include/linux/pci_ids.h
> +++ b/include/linux/pci_ids.h
> @@ -2631,6 +2631,9 @@
>  
>  #define PCI_VENDOR_ID_CXL		0x1e98
>  
> +#define PCI_VENDOR_ID_CIX		0x1f6c
> +#define PCI_DEVICE_ID_CIX_SKY1		0x0001
> +
>  #define PCI_VENDOR_ID_TEHUTI		0x1fc9
>  #define PCI_DEVICE_ID_TEHUTI_3009	0x3009
>  #define PCI_DEVICE_ID_TEHUTI_3010	0x3010
> -- 
> 2.49.0
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1
  2025-08-19 11:52 ` [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1 hans.zhang
@ 2025-08-30 13:29   ` Manivannan Sadhasivam
  2025-09-01  3:04     ` Hans Zhang
  0 siblings, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:29 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:36PM GMT, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> Add driver for the CIX Sky1 SoC PCIe Gen4 16 GT/s controller based
> on the Cadence PCIe core.
> 
> Supports MSI/MSI-x via GICv3, Single Virtual Channel, Single Function.
> 
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
> Changes for v8:
> - Optimization of CIX SKY1 Root Port driver. (Bjorn and Krzysztof)
> - Use devm_platform_ioremap_resource_byname.
> ---
>  drivers/pci/controller/cadence/Kconfig    |  15 ++
>  drivers/pci/controller/cadence/Makefile   |   1 +
>  drivers/pci/controller/cadence/pci-sky1.c | 232 ++++++++++++++++++++++
>  3 files changed, 248 insertions(+)
>  create mode 100644 drivers/pci/controller/cadence/pci-sky1.c
> 
> diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
> index 117677a23d68..26a248cdc78a 100644
> --- a/drivers/pci/controller/cadence/Kconfig
> +++ b/drivers/pci/controller/cadence/Kconfig
> @@ -42,6 +42,21 @@ config PCIE_CADENCE_PLAT_EP
>  	  endpoint mode. This PCIe controller may be embedded into many
>  	  different vendors SoCs.
>  
> +config PCI_SKY1_HOST
> +	tristate "CIX SKY1 PCIe controller (host mode)"
> +	depends on OF
> +	select PCIE_CADENCE_HOST
> +	select PCI_ECAM
> +	help
> +	  Say Y here if you want to support the CIX SKY1 PCIe platform
> +	  controller in host mode. CIX SKY1 PCIe controller uses Cadence
> +	  HPA (High Performance Architecture IP [Second generation of
> +	  Cadence PCIe IP])
> +
> +	  This driver requires Cadence PCIe core infrastructure
> +	  (PCIE_CADENCE_HOST) and hardware platform adaptation layer
> +	  to function.
> +
>  config PCI_J721E
>  	tristate
>  	select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
> diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
> index de4ddae7aca4..40d7c6e98b4d 100644
> --- a/drivers/pci/controller/cadence/Makefile
> +++ b/drivers/pci/controller/cadence/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
>  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>  obj-$(CONFIG_PCI_J721E) += pci-j721e.o
> +obj-$(CONFIG_PCI_SKY1_HOST) += pci-sky1.o
> diff --git a/drivers/pci/controller/cadence/pci-sky1.c b/drivers/pci/controller/cadence/pci-sky1.c
> new file mode 100644
> index 000000000000..7dd3546275c5
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pci-sky1.c
> @@ -0,0 +1,232 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe controller driver for CIX's sky1 SoCs
> + *

No copyright for CIX tech?

> + * Author: Hans Zhang <hans.zhang@cixtech.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/pci.h>
> +#include <linux/pci-ecam.h>
> +#include <linux/pci_ids.h>
> +
> +#include "pcie-cadence.h"
> +#include "pcie-cadence-host-common.h"
> +
> +#define STRAP_REG(n)			((n) * 0x04)
> +#define STATUS_REG(n)			((n) * 0x04)
> +#define  LINK_TRAINING_ENABLE		BIT(0)
> +#define  LINK_COMPLETE			BIT(0)

Extra space.

> +
> +#define SKY1_IP_REG_BANK		0x1000
> +#define SKY1_IP_CFG_CTRL_REG_BANK	0x4c00
> +#define SKY1_IP_AXI_MASTER_COMMON	0xf000
> +#define SKY1_AXI_SLAVE			0x9000
> +#define SKY1_AXI_MASTER			0xb000
> +#define SKY1_AXI_HLS_REGISTERS		0xc000
> +#define SKY1_AXI_RAS_REGISTERS		0xe000
> +#define SKY1_DTI_REGISTERS		0xd000
> +
> +#define IP_REG_I_DBG_STS_0		0x420
> +
> +struct sky1_pcie {
> +	struct cdns_pcie *cdns_pcie;
> +	struct cdns_pcie_rc *cdns_pcie_rc;
> +
> +	struct resource *cfg_res;
> +	struct resource *msg_res;
> +	struct pci_config_window *cfg;
> +	void __iomem *strap_base;
> +	void __iomem *status_base;
> +	void __iomem *reg_base;
> +	void __iomem *cfg_base;
> +	void __iomem *msg_base;
> +};
> +
> +static int sky1_pcie_resource_get(struct platform_device *pdev,
> +				  struct sky1_pcie *pcie)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	void __iomem *base;
> +
> +	base = devm_platform_ioremap_resource_byname(pdev, "reg");
> +	if (IS_ERR(base))
> +		return dev_err_probe(dev, PTR_ERR(base),
> +				     "unable to find reg registers\n");

"unable to find \"reg\" registers". Same for below prints.

> +	pcie->reg_base = base;
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
> +	if (!res)
> +		return dev_err_probe(dev, ENXIO, "unable to get cfg resource\n");
> +	pcie->cfg_res = res;
> +
> +	base = devm_platform_ioremap_resource_byname(pdev, "rcsu_strap");
> +	if (IS_ERR(base))
> +		return dev_err_probe(dev, PTR_ERR(base),
> +				     "unable to find rcsu strap registers\n");
> +	pcie->strap_base = base;
> +
> +	base = devm_platform_ioremap_resource_byname(pdev, "rcsu_status");
> +	if (IS_ERR(base))
> +		return dev_err_probe(dev, PTR_ERR(base),
> +				     "unable to find rcsu status registers\n");
> +	pcie->status_base = base;
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "msg");
> +	if (!res)
> +		return dev_err_probe(dev, ENXIO, "unable to get msg resource\n");
> +	pcie->msg_res = res;
> +	pcie->msg_base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(pcie->msg_base)) {
> +		return dev_err_probe(dev, PTR_ERR(pcie->msg_base),
> +				     "unable to ioremap msg resource\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static int sky1_pcie_start_link(struct cdns_pcie *cdns_pcie)
> +{
> +	struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
> +	u32 val;
> +
> +	val = readl(pcie->strap_base + STRAP_REG(1));
> +	val |= LINK_TRAINING_ENABLE;
> +	writel(val, pcie->strap_base + STRAP_REG(1));
> +
> +	return 0;
> +}
> +
> +static void sky1_pcie_stop_link(struct cdns_pcie *cdns_pcie)
> +{
> +	struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
> +	u32 val;
> +
> +	val = readl(pcie->strap_base + STRAP_REG(1));
> +	val &= ~LINK_TRAINING_ENABLE;
> +	writel(val, pcie->strap_base + STRAP_REG(1));
> +}
> +
> +static bool sky1_pcie_link_up(struct cdns_pcie *cdns_pcie)
> +{
> +	u32 val;
> +
> +	val = cdns_pcie_hpa_readl(cdns_pcie, REG_BANK_IP_REG,
> +				  IP_REG_I_DBG_STS_0);
> +	return val & LINK_COMPLETE;
> +}
> +
> +static const struct cdns_pcie_ops sky1_pcie_ops = {
> +	.start_link = sky1_pcie_start_link,
> +	.stop_link = sky1_pcie_stop_link,
> +	.link_up = sky1_pcie_link_up,
> +};
> +
> +static int sky1_pcie_probe(struct platform_device *pdev)
> +{
> +	struct cdns_plat_pcie_of_data *reg_off;
> +	struct device *dev = &pdev->dev;
> +	struct pci_host_bridge *bridge;
> +	struct cdns_pcie *cdns_pcie;
> +	struct resource_entry *bus;
> +	struct cdns_pcie_rc *rc;
> +	struct sky1_pcie *pcie;
> +	int ret;
> +
> +	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
> +	if (!bridge)
> +		return -ENOMEM;
> +
> +	ret = sky1_pcie_resource_get(pdev, pcie);
> +	if (ret < 0)
> +		return -ENXIO;

return ret;

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1
  2025-08-19 11:52 ` [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1 hans.zhang
@ 2025-08-30 13:31   ` Manivannan Sadhasivam
  2025-09-01  3:09     ` Hans Zhang
  0 siblings, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:31 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:38PM GMT, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> Add pcie_x*_rc node to support Sky1 PCIe driver based on the
> Cadence PCIe core.
> 
> Supports Gen1/Gen2/Gen3/Gen4, 1/2/4/8 lane, MSI/MSI-x interrupts
> using the ARM GICv3.
> 
> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
> Changes for v8:
> - The rcsu register is split into two parts: rcsu_strap and rcsu_status.
> ---
>  arch/arm64/boot/dts/cix/sky1.dtsi | 126 ++++++++++++++++++++++++++++++
>  1 file changed, 126 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi
> index 7dfe7677e649..26c325d8d934 100644
> --- a/arch/arm64/boot/dts/cix/sky1.dtsi
> +++ b/arch/arm64/boot/dts/cix/sky1.dtsi
> @@ -288,6 +288,132 @@ mbox_ap2sfh: mailbox@80a0000 {
>  			cix,mbox-dir = "tx";
>  		};
>  
> +		pcie_x8_rc: pcie@a010000 {
> +			compatible = "cix,sky1-pcie-host";
> +			reg = <0x00 0x0a010000 0x00 0x10000>,
> +			      <0x00 0x2c000000 0x00 0x4000000>,
> +			      <0x00 0x0a000300 0x00 0x100>,
> +			      <0x00 0x0a000400 0x00 0x100>,
> +			      <0x00 0x60000000 0x00 0x00100000>;
> +			reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
> +			ranges = <0x01000000 0x0 0x60100000 0x0 0x60100000 0x0 0x00100000>,
> +				 <0x02000000 0x0 0x60200000 0x0 0x60200000 0x0 0x1fe00000>,
> +				 <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>;
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			bus-range = <0xc0 0xff>;

Isn't each controller in separate domain? Or as per the hw design, all
controllers are under a single domain sharing the busses?

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board
  2025-08-19 11:52 ` [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board hans.zhang
@ 2025-08-30 13:33   ` Manivannan Sadhasivam
  2025-09-01  3:14     ` Hans Zhang
  0 siblings, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:33 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:39PM GMT, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> Add PCIe RC support on Orion O6 board.
> 

So with this patch (and dependencies), the endpoints are detected and usable?
Any limitation with not supporting the GPIO and pinctrl should be documented in
the description.

- Mani

> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
> ---
> Dear Krzysztof,
> 
> Due to the fact that the GPIO, PINCTRL and other modules of our platform are
> not yet ready for upstream. Attributes that PCIe depends on, such as reset-gpios
> and pinctrl*, have not been added for the time being. It will be added gradually
> in the future.
> 
> The following are Arnd's previous comments. We can go to upsteam separately.
> https://lore.kernel.org/all/422deb4d-db29-48c1-b0c9-7915951df500@app.fastmail.com/
> ---
>  arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> index d74964d53c3b..be3ec4f5d11e 100644
> --- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> @@ -34,6 +34,26 @@ linux,cma {
>  
>  };
>  
> +&pcie_x8_rc {
> +	status = "okay";
> +};
> +
> +&pcie_x4_rc {
> +	status = "okay";
> +};
> +
> +&pcie_x2_rc {
> +	status = "okay";
> +};
> +
> +&pcie_x1_0_rc {
> +	status = "okay";
> +};
> +
> +&pcie_x1_1_rc {
> +	status = "okay";
> +};
> +
>  &uart2 {
>  	status = "okay";
>  };
> -- 
> 2.49.0
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers
  2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
                   ` (14 preceding siblings ...)
  2025-08-19 11:52 ` [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board hans.zhang
@ 2025-08-30 13:38 ` Manivannan Sadhasivam
  2025-09-01  4:28   ` Manikandan Karunakaran Pillai
  15 siblings, 1 reply; 39+ messages in thread
From: Manivannan Sadhasivam @ 2025-08-30 13:38 UTC (permalink / raw)
  To: hans.zhang
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel

On Tue, Aug 19, 2025 at 07:52:24PM GMT, hans.zhang@cixtech.com wrote:
> From: Hans Zhang <hans.zhang@cixtech.com>
> 
> ---
> Dear Maintainers,
> 
> This series is Cadence's HPA PCIe IP and the Root Port driver of our
> CIX sky1. Please help review. Thank you very much.

IIUC, sky1 only supports RC mode of the Cadence HPA architecture and not EP. But
you have added the library functions for EP mode also and it is currently
unused. So you should drop those EP related code from this series and add
whenever the corresponding platform driver is added. It also makes patch 8
smaller.

- Mani

> ---
> 
> Enhances the exiting Cadence PCIe controller drivers to support
> HPA (High Performance Architecture) Cadence PCIe controllers.
> 
> The patch set enhances the Cadence PCIe driver for HPA support.
> The header files are separated out for legacy and high performance
> register maps, register address and bit definitions. The driver
> read register and write register functions for HPA take the
> updated offset stored from the platform driver to access the registers.
> As part of refactoring of the code, few new files are added to the
> driver by splitting the existing files.
> This helps SoC vendor who change the address map within PCIe controller
> in their designs. Setting the menuconfig appropriately will allow
> selection between RP and/or EP PCIe controller support. The support
> will include Legacy and HPA for the selected configuration.
> 
> The TI SoC continues to be supported with the changes incorporated.
> 
> The changes address the review comments in the previous patches where
> the need to move away from "ops" pointers used in current implementation
> and separate out the Legacy and HPA driver implementation was stressed.
> 
> The scripts/checkpatch.pl has been run on the patches with and without
> --strict. With the --strict option, 4 checks are generated on 3 patch,
> which can be ignored. There are no code fixes required for these checks.
> All other checks generated by ./scripts/checkpatch.pl --strict can be 
> ignored.
> 
> ---
> Changes for v8
>         - Fixed the error issue of DT binding. (Rob and Krzysztof)
>         - Optimization of CIX SKY1 Root Port driver. (Bjorn and Krzysztof)
>         - Review comments fixed. (Bjorn and Krzysztof)
> 	      - All comments related fixes like single line comments, spaces
>               between HPA or LGA, periods in single line, changes proposed
>               in the description, etc are fixed. (Bjorn and Krzysztof)
>         - Patches have been split to separate out code moves from
>           update and fixes.
>         - "cdns_...send_irq.." renamed to "cdns_..raise_irq.."
> 
>         The test log on the Orion O6 board is as follows:
>         root@cix-localhost:~# lspci
>         0000:c0:00.0 PCI bridge: Device 1f6c:0001
>         0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
>         0001:90:00.0 PCI bridge: Device 1f6c:0001
>         0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller PM9A1/PM9A3/980PRO
>         0002:60:00.0 PCI bridge: Device 1f6c:0001
>         0002:61:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
>         0003:00:00.0 PCI bridge: Device 1f6c:0001
>         0003:01:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8852BE PCIe 802.11ax Wireless Network Controller
>         0004:30:00.0 PCI bridge: Device 1f6c:0001
>         0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)
>         root@cix-localhost:~#
>         root@cix-localhost:~# uname -a
>         Linux cix-localhost 6.17.0-rc2-00043-gb2782ead460c #185 SMP PREEMPT Tue Aug 19 19:35:34 CST 2025 aarch64 GNU/Linux
>         root@cix-localhost:~# cat /etc/issue
>         Debian GNU/Linux 12 \n \l
> 
> Changes for v7
> https://patchwork.kernel.org/project/linux-pci/cover/20250813042331.1258272-1-hans.zhang@cixtech.com/
> 
>         - Rebase to v6.17-rc1.
>         - Fixed the error issue of cix,sky1-pcie-host.yaml make dt_binding_check.
>         - CIX SKY1 Root Port driver compilation error issue: Add header
>           file, Kconfig select PCI_ECAM.
> 
> Changes for v6
> https://patchwork.kernel.org/project/linux-pci/cover/20250808072929.4090694-1-hans.zhang@cixtech.com/
> 
>         - The IP level DTS changes for HPA have been removed as the SoC
>           level DTS is added
>         - Virtual FPGA platform is also removed as the CiX SoC support is
>           added
>         - Fix the issue of dt bindings
>         - Modify the order of PCIe node attributes in sky1-orion-o6.dts
>           and delete unnecessary attributes.
>         - Continue to simplify the RC driver.
>         - The patch of the Cix Sky1 platform has been accepted and merged into the linux master branch.
>         https://patchwork.kernel.org/project/linux-arm-kernel/cover/20250721144500.302202-1-peter.chen@cixtech.com/
> 
> Changes for v5
> https://patchwork.kernel.org/project/linux-pci/cover/20250630041601.399921-1-hans.zhang@cixtech.com/
> 
>         - Header and code files separated for library functions(common
>           functions used by both architectures) and Legacy and HPA.
>         - Few new files added as part of refactoring
>         - No checks for "is_hpa" as the functions have been separated
>           out
>         - Review comments from previous patches have been addressed
>         - Add region 0 for ECAM and region 1 for message.
>         - Add CIX sky1 PCIe drivers. Submissions based on the following v9 patches:
>         https://patchwork.kernel.org/project/linux-arm-kernel/cover/20250609031627.1605851-1-peter.chen@cixtech.com/
> 
>         Cix Sky1 base dts review link to show its review status:
>         https://lore.kernel.org/all/20250609031627.1605851-9-peter.chen@cixtech.com/
> 
>         The test log on the Orion O6 board is as follows:
>         root@cix-localhost:~# lspci
>         0000:c0:00.0 PCI bridge: Device 1f6c:0001
>         0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
>         0001:90:00.0 PCI bridge: Device 1f6c:0001
>         0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller PM9A1/PM9A3/980PRO
>         0002:60:00.0 PCI bridge: Device 1f6c:0001
>         0002:61:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8852BE PCIe 802.11ax Wireless Network Controller
>         0003:00:00.0 PCI bridge: Device 1f6c:0001
>         0003:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
>         0004:30:00.0 PCI bridge: Device 1f6c:0001
>         0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8126 (rev 01)
>         root@cix-localhost:~# uname -a
>         Linux cix-localhost 6.16.0-rc1-00023-gbaa962a95a28 #138 SMP PREEMPT Fri Jun 27 16:43:41 CST 2025 aarch64 GNU/Linux
>         root@cix-localhost:~# cat /etc/issue
>         Debian GNU/Linux 12 \n \l
>  
> Changes for v4
> https://patchwork.kernel.org/project/linux-pci/cover/20250424010445.2260090-1-hans.zhang@cixtech.com/
> 
>         - Add header file bitfield.h to pcie-cadence.h
>         - Addressed the following review comments
>                 Merged the TI patch as it
>                 Removed initialization of struct variables to '0'
> 
> Changes for v3
> https://patchwork.kernel.org/project/linux-pci/patch/20250411103656.2740517-1-hans.zhang@cixtech.com/
> 
>         - Patch version v3 added to the subject
>         - Use HPA tag for architecture descriptions
>         - Remove bug related changes to be submitted later as a separate
>           patch
>         - Two patches merged from the last series to ensure readability to
>           address the review comments
>         - Fix several description related issues, coding style issues and
>           some misleading comments
>         - Remove cpu_addr_fixup() functions
> ---
> 
> Hans Zhang (6):
>   dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings
>   PCI: Add Cix Technology Vendor and Device ID
>   PCI: sky1: Add PCIe host support for CIX Sky1
>   MAINTAINERS: add entry for CIX Sky1 PCIe driver
>   arm64: dts: cix: Add PCIe Root Complex on sky1
>   arm64: dts: cix: Enable PCIe on the Orion O6 board
> 
> Manikandan K Pillai (9):
>   PCI: cadence: Add module support for platform controller driver
>   PCI: cadence: Split PCIe controller header file
>   PCI: cadence: Add register definitions for High Perf Architecture
>     (HPA)
>   PCI: cadence: Add helper functions for supporting High Perf
>     Architecture (HPA)
>   PCI: cadence: Move PCIe EP common functions to a separate file
>   PCI: cadence: Move PCIe RP common functions to a separate file
>   PCI: cadence: Move PCIe controller common functions as a separate file
>   PCI: cadence: Add support for High Perf Architecture (HPA) controller
>   PCI: cadence: Update PCIe platform to use register offsets passed
> 
>  .../bindings/pci/cix,sky1-pcie-host.yaml      |  83 +++
>  MAINTAINERS                                   |   7 +
>  arch/arm64/boot/dts/cix/sky1-orion-o6.dts     |  20 +
>  arch/arm64/boot/dts/cix/sky1.dtsi             | 126 ++++
>  drivers/pci/controller/cadence/Kconfig        |  21 +-
>  drivers/pci/controller/cadence/Makefile       |  11 +-
>  drivers/pci/controller/cadence/pci-sky1.c     | 232 +++++++
>  .../controller/cadence/pcie-cadence-common.c  | 141 +++++
>  .../cadence/pcie-cadence-ep-common.c          | 251 ++++++++
>  .../cadence/pcie-cadence-ep-common.h          |  36 ++
>  .../controller/cadence/pcie-cadence-ep-hpa.c  | 528 ++++++++++++++++
>  .../pci/controller/cadence/pcie-cadence-ep.c  | 233 +------
>  .../cadence/pcie-cadence-host-common.c        | 179 ++++++
>  .../cadence/pcie-cadence-host-common.h        |  24 +
>  .../cadence/pcie-cadence-host-hpa.c           | 585 ++++++++++++++++++
>  .../controller/cadence/pcie-cadence-host.c    | 156 +----
>  .../cadence/pcie-cadence-hpa-regs.h           | 182 ++++++
>  .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++
>  .../cadence/pcie-cadence-lga-regs.h           | 228 +++++++
>  .../controller/cadence/pcie-cadence-plat.c    |  20 +-
>  drivers/pci/controller/cadence/pcie-cadence.c | 139 +----
>  drivers/pci/controller/cadence/pcie-cadence.h | 412 ++++++------
>  include/linux/pci_ids.h                       |   3 +
>  23 files changed, 3056 insertions(+), 765 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml
>  create mode 100644 drivers/pci/controller/cadence/pci-sky1.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-common.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-common.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-common.h
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-common.h
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c
>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
> 
> 
> base-commit: be48bcf004f9d0c9207ff21d0edb3b42f253829e
> -- 
> 2.49.0
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID
  2025-08-30 13:21   ` Manivannan Sadhasivam
@ 2025-09-01  3:03     ` Hans Zhang
  0 siblings, 0 replies; 39+ messages in thread
From: Hans Zhang @ 2025-09-01  3:03 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 2025/8/30 21:21, Manivannan Sadhasivam wrote:
> [Some people who received this message don't often get email from mani@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL
> 
> On Tue, Aug 19, 2025 at 07:52:35PM GMT, hans.zhang@cixtech.com wrote:
>> From: Hans Zhang <hans.zhang@cixtech.com>
>>
>> Add Cixtech P1 (internal name sky1) as a vendor and device ID for PCI
>> devices. This ID will be used by the CIX Sky1 PCIe host controller driver.
> 
> Nit: Use CIX everywhere.
> 

Dear Mani,

Thank you very much for your reply.

Will change.

Best regards,
Hans

> - Mani
> 
>>
>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>> ---
>>   include/linux/pci_ids.h | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
>> index 92ffc4373f6d..24b04d085920 100644
>> --- a/include/linux/pci_ids.h
>> +++ b/include/linux/pci_ids.h
>> @@ -2631,6 +2631,9 @@
>>
>>   #define PCI_VENDOR_ID_CXL            0x1e98
>>
>> +#define PCI_VENDOR_ID_CIX            0x1f6c
>> +#define PCI_DEVICE_ID_CIX_SKY1               0x0001
>> +
>>   #define PCI_VENDOR_ID_TEHUTI         0x1fc9
>>   #define PCI_DEVICE_ID_TEHUTI_3009    0x3009
>>   #define PCI_DEVICE_ID_TEHUTI_3010    0x3010
>> --
>> 2.49.0
>>
> 
> --
> மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1
  2025-08-30 13:29   ` Manivannan Sadhasivam
@ 2025-09-01  3:04     ` Hans Zhang
  0 siblings, 0 replies; 39+ messages in thread
From: Hans Zhang @ 2025-09-01  3:04 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 2025/8/30 21:29, Manivannan Sadhasivam wrote:
> [Some people who received this message don't often get email from mani@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL
> 
> On Tue, Aug 19, 2025 at 07:52:36PM GMT, hans.zhang@cixtech.com wrote:
>> From: Hans Zhang <hans.zhang@cixtech.com>
>>
>> Add driver for the CIX Sky1 SoC PCIe Gen4 16 GT/s controller based
>> on the Cadence PCIe core.
>>
>> Supports MSI/MSI-x via GICv3, Single Virtual Channel, Single Function.
>>
>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>> ---
>> Changes for v8:
>> - Optimization of CIX SKY1 Root Port driver. (Bjorn and Krzysztof)
>> - Use devm_platform_ioremap_resource_byname.
>> ---
>>   drivers/pci/controller/cadence/Kconfig    |  15 ++
>>   drivers/pci/controller/cadence/Makefile   |   1 +
>>   drivers/pci/controller/cadence/pci-sky1.c | 232 ++++++++++++++++++++++
>>   3 files changed, 248 insertions(+)
>>   create mode 100644 drivers/pci/controller/cadence/pci-sky1.c
>>
>> diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
>> index 117677a23d68..26a248cdc78a 100644
>> --- a/drivers/pci/controller/cadence/Kconfig
>> +++ b/drivers/pci/controller/cadence/Kconfig
>> @@ -42,6 +42,21 @@ config PCIE_CADENCE_PLAT_EP
>>          endpoint mode. This PCIe controller may be embedded into many
>>          different vendors SoCs.
>>
>> +config PCI_SKY1_HOST
>> +     tristate "CIX SKY1 PCIe controller (host mode)"
>> +     depends on OF
>> +     select PCIE_CADENCE_HOST
>> +     select PCI_ECAM
>> +     help
>> +       Say Y here if you want to support the CIX SKY1 PCIe platform
>> +       controller in host mode. CIX SKY1 PCIe controller uses Cadence
>> +       HPA (High Performance Architecture IP [Second generation of
>> +       Cadence PCIe IP])
>> +
>> +       This driver requires Cadence PCIe core infrastructure
>> +       (PCIE_CADENCE_HOST) and hardware platform adaptation layer
>> +       to function.
>> +
>>   config PCI_J721E
>>        tristate
>>        select PCIE_CADENCE_HOST if PCI_J721E_HOST != n
>> diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
>> index de4ddae7aca4..40d7c6e98b4d 100644
>> --- a/drivers/pci/controller/cadence/Makefile
>> +++ b/drivers/pci/controller/cadence/Makefile
>> @@ -8,3 +8,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
>>   obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
>>   obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>>   obj-$(CONFIG_PCI_J721E) += pci-j721e.o
>> +obj-$(CONFIG_PCI_SKY1_HOST) += pci-sky1.o
>> diff --git a/drivers/pci/controller/cadence/pci-sky1.c b/drivers/pci/controller/cadence/pci-sky1.c
>> new file mode 100644
>> index 000000000000..7dd3546275c5
>> --- /dev/null
>> +++ b/drivers/pci/controller/cadence/pci-sky1.c
>> @@ -0,0 +1,232 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * PCIe controller driver for CIX's sky1 SoCs
>> + *
> 
> No copyright for CIX tech?

Dear Mani,

Thank you very much for your reply.

Will add.

> 
>> + * Author: Hans Zhang <hans.zhang@cixtech.com>
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/pci.h>
>> +#include <linux/pci-ecam.h>
>> +#include <linux/pci_ids.h>
>> +
>> +#include "pcie-cadence.h"
>> +#include "pcie-cadence-host-common.h"
>> +
>> +#define STRAP_REG(n)                 ((n) * 0x04)
>> +#define STATUS_REG(n)                        ((n) * 0x04)
>> +#define  LINK_TRAINING_ENABLE                BIT(0)
>> +#define  LINK_COMPLETE                       BIT(0)
> 
> Extra space.

Will change.

> 
>> +
>> +#define SKY1_IP_REG_BANK             0x1000
>> +#define SKY1_IP_CFG_CTRL_REG_BANK    0x4c00
>> +#define SKY1_IP_AXI_MASTER_COMMON    0xf000
>> +#define SKY1_AXI_SLAVE                       0x9000
>> +#define SKY1_AXI_MASTER                      0xb000
>> +#define SKY1_AXI_HLS_REGISTERS               0xc000
>> +#define SKY1_AXI_RAS_REGISTERS               0xe000
>> +#define SKY1_DTI_REGISTERS           0xd000
>> +
>> +#define IP_REG_I_DBG_STS_0           0x420
>> +
>> +struct sky1_pcie {
>> +     struct cdns_pcie *cdns_pcie;
>> +     struct cdns_pcie_rc *cdns_pcie_rc;
>> +
>> +     struct resource *cfg_res;
>> +     struct resource *msg_res;
>> +     struct pci_config_window *cfg;
>> +     void __iomem *strap_base;
>> +     void __iomem *status_base;
>> +     void __iomem *reg_base;
>> +     void __iomem *cfg_base;
>> +     void __iomem *msg_base;
>> +};
>> +
>> +static int sky1_pcie_resource_get(struct platform_device *pdev,
>> +                               struct sky1_pcie *pcie)
>> +{
>> +     struct device *dev = &pdev->dev;
>> +     struct resource *res;
>> +     void __iomem *base;
>> +
>> +     base = devm_platform_ioremap_resource_byname(pdev, "reg");
>> +     if (IS_ERR(base))
>> +             return dev_err_probe(dev, PTR_ERR(base),
>> +                                  "unable to find reg registers\n");
> 
> "unable to find \"reg\" registers". Same for below prints.

Will change.

> 
>> +     pcie->reg_base = base;
>> +
>> +     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
>> +     if (!res)
>> +             return dev_err_probe(dev, ENXIO, "unable to get cfg resource\n");
>> +     pcie->cfg_res = res;
>> +
>> +     base = devm_platform_ioremap_resource_byname(pdev, "rcsu_strap");
>> +     if (IS_ERR(base))
>> +             return dev_err_probe(dev, PTR_ERR(base),
>> +                                  "unable to find rcsu strap registers\n");
>> +     pcie->strap_base = base;
>> +
>> +     base = devm_platform_ioremap_resource_byname(pdev, "rcsu_status");
>> +     if (IS_ERR(base))
>> +             return dev_err_probe(dev, PTR_ERR(base),
>> +                                  "unable to find rcsu status registers\n");
>> +     pcie->status_base = base;
>> +
>> +     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "msg");
>> +     if (!res)
>> +             return dev_err_probe(dev, ENXIO, "unable to get msg resource\n");
>> +     pcie->msg_res = res;
>> +     pcie->msg_base = devm_ioremap_resource(dev, res);
>> +     if (IS_ERR(pcie->msg_base)) {
>> +             return dev_err_probe(dev, PTR_ERR(pcie->msg_base),
>> +                                  "unable to ioremap msg resource\n");
>> +     }
>> +
>> +     return 0;
>> +}
>> +
>> +static int sky1_pcie_start_link(struct cdns_pcie *cdns_pcie)
>> +{
>> +     struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
>> +     u32 val;
>> +
>> +     val = readl(pcie->strap_base + STRAP_REG(1));
>> +     val |= LINK_TRAINING_ENABLE;
>> +     writel(val, pcie->strap_base + STRAP_REG(1));
>> +
>> +     return 0;
>> +}
>> +
>> +static void sky1_pcie_stop_link(struct cdns_pcie *cdns_pcie)
>> +{
>> +     struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
>> +     u32 val;
>> +
>> +     val = readl(pcie->strap_base + STRAP_REG(1));
>> +     val &= ~LINK_TRAINING_ENABLE;
>> +     writel(val, pcie->strap_base + STRAP_REG(1));
>> +}
>> +
>> +static bool sky1_pcie_link_up(struct cdns_pcie *cdns_pcie)
>> +{
>> +     u32 val;
>> +
>> +     val = cdns_pcie_hpa_readl(cdns_pcie, REG_BANK_IP_REG,
>> +                               IP_REG_I_DBG_STS_0);
>> +     return val & LINK_COMPLETE;
>> +}
>> +
>> +static const struct cdns_pcie_ops sky1_pcie_ops = {
>> +     .start_link = sky1_pcie_start_link,
>> +     .stop_link = sky1_pcie_stop_link,
>> +     .link_up = sky1_pcie_link_up,
>> +};
>> +
>> +static int sky1_pcie_probe(struct platform_device *pdev)
>> +{
>> +     struct cdns_plat_pcie_of_data *reg_off;
>> +     struct device *dev = &pdev->dev;
>> +     struct pci_host_bridge *bridge;
>> +     struct cdns_pcie *cdns_pcie;
>> +     struct resource_entry *bus;
>> +     struct cdns_pcie_rc *rc;
>> +     struct sky1_pcie *pcie;
>> +     int ret;
>> +
>> +     pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
>> +     if (!pcie)
>> +             return -ENOMEM;
>> +
>> +     bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
>> +     if (!bridge)
>> +             return -ENOMEM;
>> +
>> +     ret = sky1_pcie_resource_get(pdev, pcie);
>> +     if (ret < 0)
>> +             return -ENXIO;
> 
> return ret;

Will change.

Best regards,
Hans

> 
> - Mani
> 
> --
> மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1
  2025-08-30 13:31   ` Manivannan Sadhasivam
@ 2025-09-01  3:09     ` Hans Zhang
  0 siblings, 0 replies; 39+ messages in thread
From: Hans Zhang @ 2025-09-01  3:09 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 2025/8/30 21:31, Manivannan Sadhasivam wrote:
> [Some people who received this message don't often get email from mani@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL
> 
> On Tue, Aug 19, 2025 at 07:52:38PM GMT, hans.zhang@cixtech.com wrote:
>> From: Hans Zhang <hans.zhang@cixtech.com>
>>
>> Add pcie_x*_rc node to support Sky1 PCIe driver based on the
>> Cadence PCIe core.
>>
>> Supports Gen1/Gen2/Gen3/Gen4, 1/2/4/8 lane, MSI/MSI-x interrupts
>> using the ARM GICv3.
>>
>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>> ---
>> Changes for v8:
>> - The rcsu register is split into two parts: rcsu_strap and rcsu_status.
>> ---
>>   arch/arm64/boot/dts/cix/sky1.dtsi | 126 ++++++++++++++++++++++++++++++
>>   1 file changed, 126 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi
>> index 7dfe7677e649..26c325d8d934 100644
>> --- a/arch/arm64/boot/dts/cix/sky1.dtsi
>> +++ b/arch/arm64/boot/dts/cix/sky1.dtsi
>> @@ -288,6 +288,132 @@ mbox_ap2sfh: mailbox@80a0000 {
>>                        cix,mbox-dir = "tx";
>>                };
>>
>> +             pcie_x8_rc: pcie@a010000 {
>> +                     compatible = "cix,sky1-pcie-host";
>> +                     reg = <0x00 0x0a010000 0x00 0x10000>,
>> +                           <0x00 0x2c000000 0x00 0x4000000>,
>> +                           <0x00 0x0a000300 0x00 0x100>,
>> +                           <0x00 0x0a000400 0x00 0x100>,
>> +                           <0x00 0x60000000 0x00 0x00100000>;
>> +                     reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg";
>> +                     ranges = <0x01000000 0x0 0x60100000 0x0 0x60100000 0x0 0x00100000>,
>> +                              <0x02000000 0x0 0x60200000 0x0 0x60200000 0x0 0x1fe00000>,
>> +                              <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>;
>> +                     #address-cells = <3>;
>> +                     #size-cells = <2>;
>> +                     bus-range = <0xc0 0xff>;
> 
> Isn't each controller in separate domain? Or as per the hw design, all
> controllers are under a single domain sharing the busses?
> 
Dear Mani,

Thank you very much for your reply.

No. The design of each of our controller ECAM is fixed in the hardware 
design. This can be reflected in DTS. The specific attribute is: "cfg".

Best regards,
Hans

> - Mani
> 
> --
> மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board
  2025-08-30 13:33   ` Manivannan Sadhasivam
@ 2025-09-01  3:14     ` Hans Zhang
  2025-09-01  3:17       ` Hans Zhang
  0 siblings, 1 reply; 39+ messages in thread
From: Hans Zhang @ 2025-09-01  3:14 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 2025/8/30 21:33, Manivannan Sadhasivam wrote:
> [Some people who received this message don't often get email from mani@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL
> 
> On Tue, Aug 19, 2025 at 07:52:39PM GMT, hans.zhang@cixtech.com wrote:
>> From: Hans Zhang <hans.zhang@cixtech.com>
>>
>> Add PCIe RC support on Orion O6 board.
>>
> 
> So with this patch (and dependencies), the endpoints are detected and usable?
> Any limitation with not supporting the GPIO and pinctrl should be documented in
> the description.
> 

Dear Mani,

Thank you very much for your reply.

We can rely on the initialization of bios. After the GPIO and pinctrl 
are upstream later, we will add them in.

Just as I described in the change log of the cover letter, we can 
enumerate devices normally and use the network normally.

Just as the first version of this driver also did not have GPIO, 
pinctrl. Moreover, Arnd also suggested that we could separate the upstream.
drivers/pci/controller/dwc/pcie-amd-mdb.c


This is the situation of running the latest linux kernel on our O6 board.
root@cix-localhost:~# uname -a
Linux cix-localhost 6.17.0-rc4-00015-g5aaae89e41ab #203 SMP PREEMPT Mon 
Sep  1 10:54:16 CST 2025 aarch64 GNU/Linux
root@cix-localhost:~# lspci
0000:c0:00.0 PCI bridge: Device 1f6c:0001
0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 
8126 (rev 01)
0001:90:00.0 PCI bridge: Device 1f6c:0001
0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd 
NVMe SSD Controller S4LV008[Pascal]
0002:60:00.0 PCI bridge: Device 1f6c:0001
0002:61:00.0 Network controller: Realtek Semiconductor Co., Ltd. 
RTL8852BE PCIe 802.11ax Wireless Network Controller
0003:00:00.0 PCI bridge: Device 1f6c:0001
0003:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 
8126 (rev 01)
0004:30:00.0 PCI bridge: Device 1f6c:0001
0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 
8126 (rev 01)



Best regards,
Hans


> - Mani
> 
>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>> ---
>> Dear Krzysztof,
>>
>> Due to the fact that the GPIO, PINCTRL and other modules of our platform are
>> not yet ready for upstream. Attributes that PCIe depends on, such as reset-gpios
>> and pinctrl*, have not been added for the time being. It will be added gradually
>> in the future.
>>
>> The following are Arnd's previous comments. We can go to upsteam separately.
>> https://lore.kernel.org/all/422deb4d-db29-48c1-b0c9-7915951df500@app.fastmail.com/
>> ---
>>   arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 20 ++++++++++++++++++++
>>   1 file changed, 20 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
>> index d74964d53c3b..be3ec4f5d11e 100644
>> --- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
>> +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
>> @@ -34,6 +34,26 @@ linux,cma {
>>
>>   };
>>
>> +&pcie_x8_rc {
>> +     status = "okay";
>> +};
>> +
>> +&pcie_x4_rc {
>> +     status = "okay";
>> +};
>> +
>> +&pcie_x2_rc {
>> +     status = "okay";
>> +};
>> +
>> +&pcie_x1_0_rc {
>> +     status = "okay";
>> +};
>> +
>> +&pcie_x1_1_rc {
>> +     status = "okay";
>> +};
>> +
>>   &uart2 {
>>        status = "okay";
>>   };
>> --
>> 2.49.0
>>
> 
> --
> மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board
  2025-09-01  3:14     ` Hans Zhang
@ 2025-09-01  3:17       ` Hans Zhang
  0 siblings, 0 replies; 39+ messages in thread
From: Hans Zhang @ 2025-09-01  3:17 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: bhelgaas, lpieralisi, kw, robh, kwilczynski, krzk+dt, conor+dt,
	mpillai, fugang.duan, guoyin.chen, peter.chen,
	cix-kernel-upstream, linux-pci, devicetree, linux-kernel



On 2025/9/1 11:14, Hans Zhang wrote:
> 
> 
> On 2025/8/30 21:33, Manivannan Sadhasivam wrote:
>> [Some people who received this message don't often get email from 
>> mani@kernel.org. Learn why this is important at 
>> https://aka.ms/LearnAboutSenderIdentification ]
>>
>> EXTERNAL EMAIL
>>
>> On Tue, Aug 19, 2025 at 07:52:39PM GMT, hans.zhang@cixtech.com wrote:
>>> From: Hans Zhang <hans.zhang@cixtech.com>
>>>
>>> Add PCIe RC support on Orion O6 board.
>>>
>>
>> So with this patch (and dependencies), the endpoints are detected and 
>> usable?
>> Any limitation with not supporting the GPIO and pinctrl should be 
>> documented in
>> the description.
>>
> 
> Dear Mani,
> 
> Thank you very much for your reply.
> 
> We can rely on the initialization of bios. After the GPIO and pinctrl 
> are upstream later, we will add them in.
> 
> Just as I described in the change log of the cover letter, we can 
> enumerate devices normally and use the network normally.
> 
> Just as the first version of this driver also did not have GPIO, 
> pinctrl. Moreover, Arnd also suggested that we could separate the upstream.
> drivers/pci/controller/dwc/pcie-amd-mdb.c
> 
> 
> This is the situation of running the latest linux kernel on our O6 board.
> root@cix-localhost:~# uname -a
> Linux cix-localhost 6.17.0-rc4-00015-g5aaae89e41ab #203 SMP PREEMPT Mon 
> Sep  1 10:54:16 CST 2025 aarch64 GNU/Linux
> root@cix-localhost:~# lspci
> 0000:c0:00.0 PCI bridge: Device 1f6c:0001
> 0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 
> 8126 (rev 01)
> 0001:90:00.0 PCI bridge: Device 1f6c:0001
> 0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd 
> NVMe SSD Controller S4LV008[Pascal]
> 0002:60:00.0 PCI bridge: Device 1f6c:0001
> 0002:61:00.0 Network controller: Realtek Semiconductor Co., Ltd. 
> RTL8852BE PCIe 802.11ax Wireless Network Controller
> 0003:00:00.0 PCI bridge: Device 1f6c:0001
> 0003:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 
> 8126 (rev 01)
> 0004:30:00.0 PCI bridge: Device 1f6c:0001
> 0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 
> 8126 (rev 01)
> 
> 

Dear Mani,

In the next version, I will add it in the description.

Best regards,
Hans

> 
> Best regards,
> Hans
> 
> 
>> - Mani
>>
>>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>>> ---
>>> Dear Krzysztof,
>>>
>>> Due to the fact that the GPIO, PINCTRL and other modules of our 
>>> platform are
>>> not yet ready for upstream. Attributes that PCIe depends on, such as 
>>> reset-gpios
>>> and pinctrl*, have not been added for the time being. It will be 
>>> added gradually
>>> in the future.
>>>
>>> The following are Arnd's previous comments. We can go to upsteam 
>>> separately.
>>> https://lore.kernel.org/all/422deb4d-db29-48c1-b0c9-7915951df500@app.fastmail.com/
>>> ---
>>>   arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 20 ++++++++++++++++++++
>>>   1 file changed, 20 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts 
>>> b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
>>> index d74964d53c3b..be3ec4f5d11e 100644
>>> --- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
>>> +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
>>> @@ -34,6 +34,26 @@ linux,cma {
>>>
>>>   };
>>>
>>> +&pcie_x8_rc {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&pcie_x4_rc {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&pcie_x2_rc {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&pcie_x1_0_rc {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&pcie_x1_1_rc {
>>> +     status = "okay";
>>> +};
>>> +
>>>   &uart2 {
>>>        status = "okay";
>>>   };
>>> -- 
>>> 2.49.0
>>>
>>
>> -- 
>> மணிவண்ணன் சதாசிவம்

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

* RE: [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers
  2025-08-30 13:38 ` [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers Manivannan Sadhasivam
@ 2025-09-01  4:28   ` Manikandan Karunakaran Pillai
  0 siblings, 0 replies; 39+ messages in thread
From: Manikandan Karunakaran Pillai @ 2025-09-01  4:28 UTC (permalink / raw)
  To: Manivannan Sadhasivam, hans.zhang@cixtech.com
  Cc: bhelgaas@google.com, lpieralisi@kernel.org, kw@linux.com,
	robh@kernel.org, kwilczynski@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, fugang.duan@cixtech.com,
	guoyin.chen@cixtech.com, peter.chen@cixtech.com,
	cix-kernel-upstream@cixtech.com, linux-pci@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org



>
>On Tue, Aug 19, 2025 at 07:52:24PM GMT, hans.zhang@cixtech.com wrote:
>> From: Hans Zhang <hans.zhang@cixtech.com>
>>
>> ---
>> Dear Maintainers,
>>
>> This series is Cadence's HPA PCIe IP and the Root Port driver of our
>> CIX sky1. Please help review. Thank you very much.
>
>IIUC, sky1 only supports RC mode of the Cadence HPA architecture and not EP.
>But
>you have added the library functions for EP mode also and it is currently
>unused. So you should drop those EP related code from this series and add
>whenever the corresponding platform driver is added. It also makes patch 8
>smaller.
>
>- Mani

Hi Mani,

Will remove the EP related code.

- Manikandan

>
>> ---
>>
>> Enhances the exiting Cadence PCIe controller drivers to support
>> HPA (High Performance Architecture) Cadence PCIe controllers.
>>
>> The patch set enhances the Cadence PCIe driver for HPA support.
>> The header files are separated out for legacy and high performance
>> register maps, register address and bit definitions. The driver
>> read register and write register functions for HPA take the
>> updated offset stored from the platform driver to access the registers.
>> As part of refactoring of the code, few new files are added to the
>> driver by splitting the existing files.
>> This helps SoC vendor who change the address map within PCIe controller
>> in their designs. Setting the menuconfig appropriately will allow
>> selection between RP and/or EP PCIe controller support. The support
>> will include Legacy and HPA for the selected configuration.
>>
>> The TI SoC continues to be supported with the changes incorporated.
>>
>> The changes address the review comments in the previous patches where
>> the need to move away from "ops" pointers used in current implementation
>> and separate out the Legacy and HPA driver implementation was stressed.
>>
>> The scripts/checkpatch.pl has been run on the patches with and without
>> --strict. With the --strict option, 4 checks are generated on 3 patch,
>> which can be ignored. There are no code fixes required for these checks.
>> All other checks generated by ./scripts/checkpatch.pl --strict can be
>> ignored.
>>
>> ---
>> Changes for v8
>>         - Fixed the error issue of DT binding. (Rob and Krzysztof)
>>         - Optimization of CIX SKY1 Root Port driver. (Bjorn and Krzysztof)
>>         - Review comments fixed. (Bjorn and Krzysztof)
>> 	      - All comments related fixes like single line comments, spaces
>>               between HPA or LGA, periods in single line, changes proposed
>>               in the description, etc are fixed. (Bjorn and Krzysztof)
>>         - Patches have been split to separate out code moves from
>>           update and fixes.
>>         - "cdns_...send_irq.." renamed to "cdns_..raise_irq.."
>>
>>         The test log on the Orion O6 board is as follows:
>>         root@cix-localhost:~# lspci
>>         0000:c0:00.0 PCI bridge: Device 1f6c:0001
>>         0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device
>8126 (rev 01)
>>         0001:90:00.0 PCI bridge: Device 1f6c:0001
>>         0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co
>Ltd NVMe SSD Controller PM9A1/PM9A3/980PRO
>>         0002:60:00.0 PCI bridge: Device 1f6c:0001
>>         0002:61:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device
>8126 (rev 01)
>>         0003:00:00.0 PCI bridge: Device 1f6c:0001
>>         0003:01:00.0 Network controller: Realtek Semiconductor Co., Ltd.
>RTL8852BE PCIe 802.11ax Wireless Network Controller
>>         0004:30:00.0 PCI bridge: Device 1f6c:0001
>>         0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.
>RTL8125 2.5GbE Controller (rev 05)
>>         root@cix-localhost:~#
>>         root@cix-localhost:~# uname -a
>>         Linux cix-localhost 6.17.0-rc2-00043-gb2782ead460c #185 SMP PREEMPT
>Tue Aug 19 19:35:34 CST 2025 aarch64 GNU/Linux
>>         root@cix-localhost:~# cat /etc/issue
>>         Debian GNU/Linux 12 \n \l
>>
>> Changes for v7
>> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>pci/cover/20250813042331.1258272-1-
>hans.zhang@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC
>6r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZmCSWnAU$
>>
>>         - Rebase to v6.17-rc1.
>>         - Fixed the error issue of cix,sky1-pcie-host.yaml make dt_binding_check.
>>         - CIX SKY1 Root Port driver compilation error issue: Add header
>>           file, Kconfig select PCI_ECAM.
>>
>> Changes for v6
>> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>pci/cover/20250808072929.4090694-1-
>hans.zhang@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC
>6r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZANqbM0Q$
>>
>>         - The IP level DTS changes for HPA have been removed as the SoC
>>           level DTS is added
>>         - Virtual FPGA platform is also removed as the CiX SoC support is
>>           added
>>         - Fix the issue of dt bindings
>>         - Modify the order of PCIe node attributes in sky1-orion-o6.dts
>>           and delete unnecessary attributes.
>>         - Continue to simplify the RC driver.
>>         - The patch of the Cix Sky1 platform has been accepted and merged into
>the linux master branch.
>>         https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>arm-kernel/cover/20250721144500.302202-1-
>peter.chen@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC6
>r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZlJ6xTRU$
>>
>> Changes for v5
>> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>pci/cover/20250630041601.399921-1-
>hans.zhang@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC
>6r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9Z0zlH-dY$
>>
>>         - Header and code files separated for library functions(common
>>           functions used by both architectures) and Legacy and HPA.
>>         - Few new files added as part of refactoring
>>         - No checks for "is_hpa" as the functions have been separated
>>           out
>>         - Review comments from previous patches have been addressed
>>         - Add region 0 for ECAM and region 1 for message.
>>         - Add CIX sky1 PCIe drivers. Submissions based on the following v9
>patches:
>>         https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>arm-kernel/cover/20250609031627.1605851-1-
>peter.chen@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC6
>r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZKPjlX9o$
>>
>>         Cix Sky1 base dts review link to show its review status:
>>
>https://urldefense.com/v3/__https://lore.kernel.org/all/20250609031627.1605
>851-9-
>peter.chen@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC6
>r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZZsu9lqE$
>>
>>         The test log on the Orion O6 board is as follows:
>>         root@cix-localhost:~# lspci
>>         0000:c0:00.0 PCI bridge: Device 1f6c:0001
>>         0000:c1:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device
>8126 (rev 01)
>>         0001:90:00.0 PCI bridge: Device 1f6c:0001
>>         0001:91:00.0 Non-Volatile memory controller: Samsung Electronics Co
>Ltd NVMe SSD Controller PM9A1/PM9A3/980PRO
>>         0002:60:00.0 PCI bridge: Device 1f6c:0001
>>         0002:61:00.0 Network controller: Realtek Semiconductor Co., Ltd.
>RTL8852BE PCIe 802.11ax Wireless Network Controller
>>         0003:00:00.0 PCI bridge: Device 1f6c:0001
>>         0003:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device
>8126 (rev 01)
>>         0004:30:00.0 PCI bridge: Device 1f6c:0001
>>         0004:31:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device
>8126 (rev 01)
>>         root@cix-localhost:~# uname -a
>>         Linux cix-localhost 6.16.0-rc1-00023-gbaa962a95a28 #138 SMP PREEMPT
>Fri Jun 27 16:43:41 CST 2025 aarch64 GNU/Linux
>>         root@cix-localhost:~# cat /etc/issue
>>         Debian GNU/Linux 12 \n \l
>>
>> Changes for v4
>> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>pci/cover/20250424010445.2260090-1-
>hans.zhang@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC
>6r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZvcO-Ra8$
>>
>>         - Add header file bitfield.h to pcie-cadence.h
>>         - Addressed the following review comments
>>                 Merged the TI patch as it
>>                 Removed initialization of struct variables to '0'
>>
>> Changes for v3
>> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-
>pci/patch/20250411103656.2740517-1-
>hans.zhang@cixtech.com/__;!!EHscmS1ygiU1lA!Gmyi8ReNNRud3t7ZTRxvGPLC
>6r2Oxv0SpzO-OG8wuhb7zNTE-lwLU_xeq-o0tM1C3i9ZZ1pD1qg$
>>
>>         - Patch version v3 added to the subject
>>         - Use HPA tag for architecture descriptions
>>         - Remove bug related changes to be submitted later as a separate
>>           patch
>>         - Two patches merged from the last series to ensure readability to
>>           address the review comments
>>         - Fix several description related issues, coding style issues and
>>           some misleading comments
>>         - Remove cpu_addr_fixup() functions
>> ---
>>
>> Hans Zhang (6):
>>   dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings
>>   PCI: Add Cix Technology Vendor and Device ID
>>   PCI: sky1: Add PCIe host support for CIX Sky1
>>   MAINTAINERS: add entry for CIX Sky1 PCIe driver
>>   arm64: dts: cix: Add PCIe Root Complex on sky1
>>   arm64: dts: cix: Enable PCIe on the Orion O6 board
>>
>> Manikandan K Pillai (9):
>>   PCI: cadence: Add module support for platform controller driver
>>   PCI: cadence: Split PCIe controller header file
>>   PCI: cadence: Add register definitions for High Perf Architecture
>>     (HPA)
>>   PCI: cadence: Add helper functions for supporting High Perf
>>     Architecture (HPA)
>>   PCI: cadence: Move PCIe EP common functions to a separate file
>>   PCI: cadence: Move PCIe RP common functions to a separate file
>>   PCI: cadence: Move PCIe controller common functions as a separate file
>>   PCI: cadence: Add support for High Perf Architecture (HPA) controller
>>   PCI: cadence: Update PCIe platform to use register offsets passed
>>
>>  .../bindings/pci/cix,sky1-pcie-host.yaml      |  83 +++
>>  MAINTAINERS                                   |   7 +
>>  arch/arm64/boot/dts/cix/sky1-orion-o6.dts     |  20 +
>>  arch/arm64/boot/dts/cix/sky1.dtsi             | 126 ++++
>>  drivers/pci/controller/cadence/Kconfig        |  21 +-
>>  drivers/pci/controller/cadence/Makefile       |  11 +-
>>  drivers/pci/controller/cadence/pci-sky1.c     | 232 +++++++
>>  .../controller/cadence/pcie-cadence-common.c  | 141 +++++
>>  .../cadence/pcie-cadence-ep-common.c          | 251 ++++++++
>>  .../cadence/pcie-cadence-ep-common.h          |  36 ++
>>  .../controller/cadence/pcie-cadence-ep-hpa.c  | 528 ++++++++++++++++
>>  .../pci/controller/cadence/pcie-cadence-ep.c  | 233 +------
>>  .../cadence/pcie-cadence-host-common.c        | 179 ++++++
>>  .../cadence/pcie-cadence-host-common.h        |  24 +
>>  .../cadence/pcie-cadence-host-hpa.c           | 585 ++++++++++++++++++
>>  .../controller/cadence/pcie-cadence-host.c    | 156 +----
>>  .../cadence/pcie-cadence-hpa-regs.h           | 182 ++++++
>>  .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++
>>  .../cadence/pcie-cadence-lga-regs.h           | 228 +++++++
>>  .../controller/cadence/pcie-cadence-plat.c    |  20 +-
>>  drivers/pci/controller/cadence/pcie-cadence.c | 139 +----
>>  drivers/pci/controller/cadence/pcie-cadence.h | 412 ++++++------
>>  include/linux/pci_ids.h                       |   3 +
>>  23 files changed, 3056 insertions(+), 765 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/pci/cix,sky1-pcie-
>host.yaml
>>  create mode 100644 drivers/pci/controller/cadence/pci-sky1.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-common.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-
>common.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-
>common.h
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-
>common.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-
>common.h
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa-regs.h
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
>>
>>
>> base-commit: be48bcf004f9d0c9207ff21d0edb3b42f253829e
>> --
>> 2.49.0
>>
>
>--
>மணிவண்ணன் சதாசிவம்

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

* RE: [PATCH v8 06/15] PCI: cadence: Move PCIe RP common functions to a separate file
  2025-08-30 10:36   ` Manivannan Sadhasivam
@ 2025-09-01  4:30     ` Manikandan Karunakaran Pillai
  0 siblings, 0 replies; 39+ messages in thread
From: Manikandan Karunakaran Pillai @ 2025-09-01  4:30 UTC (permalink / raw)
  To: Manivannan Sadhasivam, hans.zhang@cixtech.com
  Cc: bhelgaas@google.com, lpieralisi@kernel.org, kw@linux.com,
	robh@kernel.org, kwilczynski@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, fugang.duan@cixtech.com,
	guoyin.chen@cixtech.com, peter.chen@cixtech.com,
	cix-kernel-upstream@cixtech.com, linux-pci@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org

>> diff --git a/drivers/pci/controller/cadence/Makefile
>b/drivers/pci/controller/cadence/Makefile
>> index 80c1c4be7e80..e45f72388bbb 100644
>> --- a/drivers/pci/controller/cadence/Makefile
>> +++ b/drivers/pci/controller/cadence/Makefile
>> @@ -1,6 +1,6 @@
>>  # SPDX-License-Identifier: GPL-2.0
>>  obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
>> -obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
>> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o
>pcie-cadence-host.o
>>  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-
>cadence-ep.o
>>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>>  obj-$(CONFIG_PCI_J721E) += pci-j721e.o
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>> new file mode 100644
>> index 000000000000..d34f8c7c49f0
>> --- /dev/null
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>> @@ -0,0 +1,179 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Cadence
>> +// Cadence PCIe host controller driver.
>
>This should be changed to 'Cadence PCIe host controller library'. For
>completeness, you should add the 'Author' tag also.
>
>- Mani
>
>--
Hi Mani,
Will change the file comments and Author tag as per your recommendation

-Manikandan

>மணிவண்ணன் சதாசிவம்

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

* RE: [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as a separate file
  2025-08-30 11:21   ` Manivannan Sadhasivam
@ 2025-09-01  4:30     ` Manikandan Karunakaran Pillai
  0 siblings, 0 replies; 39+ messages in thread
From: Manikandan Karunakaran Pillai @ 2025-09-01  4:30 UTC (permalink / raw)
  To: Manivannan Sadhasivam, hans.zhang@cixtech.com
  Cc: bhelgaas@google.com, lpieralisi@kernel.org, kw@linux.com,
	robh@kernel.org, kwilczynski@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, fugang.duan@cixtech.com,
	guoyin.chen@cixtech.com, peter.chen@cixtech.com,
	cix-kernel-upstream@cixtech.com, linux-pci@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org

>functions as a separate file
>
>EXTERNAL MAIL
>
>
>On Tue, Aug 19, 2025 at 07:52:31PM GMT, hans.zhang@cixtech.com wrote:
>> From: Manikandan K Pillai <mpillai@cadence.com>
>>
>> Move the functions for platform common tasks to a separate file. The
>> common library functions and functions specific to platform are
>> now in different files.
>>
>
>Why do we have too many library files? What is the need to split
>pcie-cadence-common.c which itself is a library?
>
Hi Mani,
I plan to drop this patch and that address all your comments.

- Mani

>> Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
>> Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>> ---
>>  drivers/pci/controller/cadence/Makefile       |   2 +-
>>  .../controller/cadence/pcie-cadence-common.c  | 141 ++++++++++++++++++
>>  drivers/pci/controller/cadence/pcie-cadence.c | 129 ----------------
>>  3 files changed, 142 insertions(+), 130 deletions(-)
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-common.c
>>
>> diff --git a/drivers/pci/controller/cadence/Makefile
>b/drivers/pci/controller/cadence/Makefile
>> index e45f72388bbb..b104562fb86a 100644
>> --- a/drivers/pci/controller/cadence/Makefile
>> +++ b/drivers/pci/controller/cadence/Makefile
>> @@ -1,5 +1,5 @@
>>  # SPDX-License-Identifier: GPL-2.0
>> -obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
>> +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
>>  obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-
>cadence-host.o
>>  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-
>cadence-ep.o
>>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-common.c
>b/drivers/pci/controller/cadence/pcie-cadence-common.c
>> new file mode 100644
>> index 000000000000..e14d53d64bf1
>> --- /dev/null
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-common.c
>> @@ -0,0 +1,141 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Cadence
>> +// Cadence PCIe controller driver.
>> +// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
>
>We use below style for multi line comments:
>
>	/*
>	 *
>	 */
>
>So even though this style existed, you should change it in all new files.
>
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/of.h>
>> +
>> +#include "pcie-cadence.h"
>> +
>> +void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
>> +{
>> +	int i = pcie->phy_count;
>> +
>> +	while (i--) {
>> +		phy_power_off(pcie->phy[i]);
>> +		phy_exit(pcie->phy[i]);
>> +	}
>> +}
>> +EXPORT_SYMBOL_GPL(cdns_pcie_disable_phy);
>> +
>> +int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
>> +{
>> +	int ret;
>> +	int i;
>> +
>> +	for (i = 0; i < pcie->phy_count; i++) {
>> +		ret = phy_init(pcie->phy[i]);
>> +		if (ret < 0)
>> +			goto err_phy;
>> +
>> +		ret = phy_power_on(pcie->phy[i]);
>> +		if (ret < 0) {
>> +			phy_exit(pcie->phy[i]);
>> +			goto err_phy;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +
>> +err_phy:
>> +	while (--i >= 0) {
>> +		phy_power_off(pcie->phy[i]);
>> +		phy_exit(pcie->phy[i]);
>> +	}
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(cdns_pcie_enable_phy);
>> +
>> +int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
>> +{
>> +	struct device_node *np = dev->of_node;
>> +	int phy_count;
>> +	struct phy **phy;
>> +	struct device_link **link;
>> +	int i;
>> +	int ret;
>> +	const char *name;
>> +
>> +	phy_count = of_property_count_strings(np, "phy-names");
>> +	if (phy_count < 1) {
>> +		dev_info(dev, "no \"phy-names\" property found; PHY will not
>be initialized\n");
>> +		pcie->phy_count = 0;
>> +		return 0;
>> +	}
>> +
>> +	phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL);
>> +	if (!phy)
>> +		return -ENOMEM;
>> +
>> +	link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL);
>> +	if (!link)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < phy_count; i++) {
>> +		of_property_read_string_index(np, "phy-names", i, &name);
>> +		phy[i] = devm_phy_get(dev, name);
>> +		if (IS_ERR(phy[i])) {
>> +			ret = PTR_ERR(phy[i]);
>> +			goto err_phy;
>> +		}
>> +		link[i] = device_link_add(dev, &phy[i]->dev,
>DL_FLAG_STATELESS);
>> +		if (!link[i]) {
>> +			devm_phy_put(dev, phy[i]);
>> +			ret = -EINVAL;
>> +			goto err_phy;
>> +		}
>> +	}
>> +
>> +	pcie->phy_count = phy_count;
>> +	pcie->phy = phy;
>> +	pcie->link = link;
>> +
>> +	ret =  cdns_pcie_enable_phy(pcie);
>
>Double space after =
>
>- Mani
>
>--
>மணிவண்ணன் சதாசிவம்

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

* RE: [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller
  2025-08-30 13:18   ` Manivannan Sadhasivam
@ 2025-09-01  4:34     ` Manikandan Karunakaran Pillai
  0 siblings, 0 replies; 39+ messages in thread
From: Manikandan Karunakaran Pillai @ 2025-09-01  4:34 UTC (permalink / raw)
  To: Manivannan Sadhasivam, hans.zhang@cixtech.com
  Cc: bhelgaas@google.com, lpieralisi@kernel.org, kw@linux.com,
	robh@kernel.org, kwilczynski@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, fugang.duan@cixtech.com,
	guoyin.chen@cixtech.com, peter.chen@cixtech.com,
	cix-kernel-upstream@cixtech.com, linux-pci@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org



>
>EXTERNAL MAIL
>
>
>On Tue, Aug 19, 2025 at 07:52:32PM GMT, hans.zhang@cixtech.com wrote:
>> From: Manikandan K Pillai <mpillai@cadence.com>
>>
>> Add support for Cadence PCIe RP and EP configuration for High
>> Performance Architecture (HPA) controllers.
>>
>
>Add more info about the controller.

- Sure
- As mentioned in one of the other comments, pcie-cadence-ep-hpa.c  file is dropped as EP related platform is not currently used.
>
>> Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
>> Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
>> Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
>> ---
>>  drivers/pci/controller/cadence/Makefile       |  10 +-
>>  .../controller/cadence/pcie-cadence-ep-hpa.c  | 528 ++++++++++++++++
>>  .../cadence/pcie-cadence-host-hpa.c           | 585 ++++++++++++++++++
>>  .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++
>
>That's a combined 1200+ loc in a single patch, which is very difficult to
>review. You should've split it into atleast two.
>
>>  drivers/pci/controller/cadence/pcie-cadence.c |  11 +
>>  drivers/pci/controller/cadence/pcie-cadence.h |  74 ++-
>>  6 files changed, 1403 insertions(+), 9 deletions(-)
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>>  create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c
>>
>> diff --git a/drivers/pci/controller/cadence/Makefile
>b/drivers/pci/controller/cadence/Makefile
>> index b104562fb86a..de4ddae7aca4 100644
>> --- a/drivers/pci/controller/cadence/Makefile
>> +++ b/drivers/pci/controller/cadence/Makefile
>> @@ -1,6 +1,10 @@
>>  # SPDX-License-Identifier: GPL-2.0
>> -obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
>> -obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o
>pcie-cadence-host.o
>> -obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-
>cadence-ep.o
>> +pcie-cadence-mod-y := pcie-cadence-hpa.o pcie-cadence-common.o pcie-
>cadence.o
>> +pcie-cadence-host-mod-y := pcie-cadence-host-common.o pcie-cadence-
>host.o pcie-cadence-host-hpa.o
>> +pcie-cadence-ep-mod-y := pcie-cadence-ep-common.o pcie-cadence-ep.o
>pcie-cadence-ep-hpa.o
>> +
>> +obj-$(CONFIG_PCIE_CADENCE) = pcie-cadence-mod.o
>> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
>> +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
>>  obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>>  obj-$(CONFIG_PCI_J721E) += pci-j721e.o
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>> new file mode 100644
>> index 000000000000..a5366ecec34f
>> --- /dev/null
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
>> @@ -0,0 +1,528 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Cadence
>> +// Cadence PCIe endpoint controller driver.
>> +// Author: Manikandan K Pillai  <mpillai@cadence.com>
>> +
>> +#include <linux/bitfield.h>
>> +#include <linux/delay.h>
>> +#include <linux/kernel.h>
>> +#include <linux/of.h>
>> +#include <linux/pci-epc.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/sizes.h>
>> +
>> +#include "pcie-cadence.h"
>> +#include "pcie-cadence-ep-common.h"
>> +
>> +static int cdns_pcie_hpa_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
>> +				     phys_addr_t addr, u64 pci_addr, size_t size)
>> +{
>> +	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>> +	struct cdns_pcie *pcie = &ep->pcie;
>> +	u32 r;
>> +
>> +	r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
>> +	if (r >= ep->max_regions - 1) {
>> +		dev_err(&epc->dev, "no free outbound region\n");
>> +		return -EINVAL;
>
>-ENOSPC
>
>> +	}
>> +
>> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
>> +	cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, r, false, addr,
>pci_addr, size);
>> +
>> +	set_bit(r, &ep->ob_region_map);
>> +	ep->ob_addr[r] = addr;
>> +
>> +	return 0;
>> +}
>> +
>> +static void cdns_pcie_hpa_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8
>vfn,
>> +					phys_addr_t addr)
>> +{
>> +	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>> +	struct cdns_pcie *pcie = &ep->pcie;
>> +	u32 r;
>> +
>> +	for (r = 0; r < ep->max_regions - 1; r++)
>> +		if (ep->ob_addr[r] == addr)
>> +			break;
>> +
>> +	if (r == ep->max_regions - 1)
>> +		return;
>> +
>> +	cdns_pcie_hpa_reset_outbound_region(pcie, r);
>> +
>> +	ep->ob_addr[r] = 0;
>> +	clear_bit(r, &ep->ob_region_map);
>> +}
>> +
>> +static void cdns_pcie_hpa_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
>u8 intx,
>> +					 bool assert)
>> +{
>> +	struct cdns_pcie *pcie = &ep->pcie;
>> +	unsigned long flags;
>> +	u32 offset;
>> +	u16 status;
>> +	u8 msg_code;
>> +
>> +	intx &= 3;
>> +
>> +	/* Set the outbound region if needed */
>> +	if (unlikely(ep->irq_pci_addr !=
>CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
>> +		     ep->irq_pci_fn != fn)) {
>> +		/* First region was reserved for IRQ writes */
>> +		cdns_pcie_hpa_set_outbound_region_for_normal_msg(pcie,
>0, fn, 0, ep->irq_phys_addr);
>> +		ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
>> +		ep->irq_pci_fn = fn;
>> +	}
>> +
>> +	if (assert) {
>> +		ep->irq_pending |= BIT(intx);
>> +		msg_code = PCIE_MSG_CODE_ASSERT_INTA + intx;
>> +	} else {
>> +		ep->irq_pending &= ~BIT(intx);
>> +		msg_code = PCIE_MSG_CODE_DEASSERT_INTA + intx;
>> +	}
>> +
>> +	spin_lock_irqsave(&ep->lock, flags);
>> +	status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS);
>> +	if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) {
>> +		status ^= PCI_STATUS_INTERRUPT;
>> +		cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status);
>> +	}
>> +	spin_unlock_irqrestore(&ep->lock, flags);
>> +
>> +	offset = CDNS_PCIE_NORMAL_MSG_ROUTING(PCIE_MSG_TYPE_R_RC)
>|
>> +		 CDNS_PCIE_NORMAL_MSG_CODE(msg_code);
>> +	writel(0, ep->irq_cpu_addr + offset);
>> +}
>> +
>> +static int cdns_pcie_hpa_ep_raise_intx_irq(struct cdns_pcie_ep *ep, u8 fn,
>u8 vfn,
>> +					   u8 intx)
>> +{
>> +	u16 cmd;
>> +
>> +	cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND);
>> +	if (cmd & PCI_COMMAND_INTX_DISABLE)
>> +		return -EINVAL;
>> +
>> +	cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, true);
>> +
>> +	/* The mdelay() value was taken from dra7xx_pcie_raise_intx_irq() */
>> +	mdelay(1);
>
>AFAIK, this 1ms delay is not fixed per the PCIe spec. It depends on how the
>host
>interrupt controller detects the level triggered interrupt. So I don't think
>this 1ms delay will work with all host systems.
>
>> +	cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, false);
>> +	return 0;
>> +}
>> +
>> +static int cdns_pcie_hpa_ep_raise_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
>u8 vfn,
>> +					  u8 interrupt_num)
>> +{
>> +	struct cdns_pcie *pcie = &ep->pcie;
>> +	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
>> +	u16 flags, mme, data, data_mask;
>> +	u8 msi_count;
>> +	u64 pci_addr, pci_addr_mask = 0xff;
>> +
>> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
>> +
>> +	/* Check whether the MSI feature has been enabled by the PCI host */
>> +	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
>> +	if (!(flags & PCI_MSI_FLAGS_ENABLE))
>> +		return -EINVAL;
>
>-EOPNOTSUPP
>
>> +
>> +	/* Get the number of enabled MSIs */
>> +	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
>> +	msi_count = 1 << mme;
>> +	if (!interrupt_num || interrupt_num > msi_count)
>> +		return -EINVAL;
>> +
>> +	/* Compute the data value to be written */
>> +	data_mask = msi_count - 1;
>> +	data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
>> +	data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
>> +
>> +	/* Get the PCI address where to write the data into */
>> +	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap +
>PCI_MSI_ADDRESS_HI);
>> +	pci_addr <<= 32;
>> +	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap +
>PCI_MSI_ADDRESS_LO);
>> +	pci_addr &= GENMASK_ULL(63, 2);
>> +
>> +	/* Set the outbound region if needed */
>> +	if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
>> +		     ep->irq_pci_fn != fn)) {
>> +		/* First region was reserved for IRQ writes */
>> +		cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
>> +						  false,
>> +						  ep->irq_phys_addr,
>> +						  pci_addr & ~pci_addr_mask,
>> +						  pci_addr_mask + 1);
>> +		ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
>> +		ep->irq_pci_fn = fn;
>> +	}
>> +	writel(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
>> +
>> +	return 0;
>> +}
>> +
>> +static int cdns_pcie_hpa_ep_raise_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
>u8 vfn,
>> +					   u16 interrupt_num)
>> +{
>> +	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
>> +	u32 tbl_offset, msg_data, reg;
>> +	struct cdns_pcie *pcie = &ep->pcie;
>> +	struct pci_epf_msix_tbl *msix_tbl;
>> +	struct cdns_pcie_epf *epf;
>> +	u64 pci_addr_mask = 0xff;
>> +	u64 msg_addr;
>> +	u16 flags;
>> +	u8 bir;
>> +
>> +	epf = &ep->epf[fn];
>> +	if (vfn > 0)
>> +		epf = &epf->epf[vfn - 1];
>> +
>> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
>> +
>> +	/* Check whether the MSI-X feature has been enabled by the PCI host
>*/
>> +	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
>> +	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
>> +		return -EINVAL;
>
>-EOPNOTSUPP
>
>> +
>> +	reg = cap + PCI_MSIX_TABLE;
>> +	tbl_offset = cdns_pcie_ep_fn_readl(pcie, fn, reg);
>> +	bir = FIELD_GET(PCI_MSIX_TABLE_BIR, tbl_offset);
>> +	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
>> +
>> +	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
>> +	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
>> +	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
>> +
>> +	/* Set the outbound region if needed */
>> +	if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
>> +	    ep->irq_pci_fn != fn) {
>> +		/* First region was reserved for IRQ writes */
>> +		cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
>> +						  false,
>> +						  ep->irq_phys_addr,
>> +						  msg_addr & ~pci_addr_mask,
>> +						  pci_addr_mask + 1);
>> +		ep->irq_pci_addr = (msg_addr & ~pci_addr_mask);
>> +		ep->irq_pci_fn = fn;
>> +	}
>> +	writel(msg_data, ep->irq_cpu_addr + (msg_addr & pci_addr_mask));
>> +
>> +	return 0;
>> +}
>> +
>> +static int cdns_pcie_hpa_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
>> +				      unsigned int type, u16 interrupt_num)
>> +{
>> +	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>> +	struct cdns_pcie *pcie = &ep->pcie;
>> +	struct device *dev = pcie->dev;
>> +
>> +	switch (type) {
>> +	case PCI_IRQ_INTX:
>> +		if (vfn > 0) {
>> +			dev_err(dev, "Cannot raise INTX interrupts for VF\n");
>> +			return -EINVAL;
>
>-EOPNOTSUPP
>
>> +		}
>> +		return cdns_pcie_hpa_ep_raise_intx_irq(ep, fn, vfn, 0);
>> +
>
>No need of newline
>
>> +	case PCI_IRQ_MSI:
>> +		return cdns_pcie_hpa_ep_raise_msi_irq(ep, fn, vfn,
>interrupt_num);
>> +
>> +	case PCI_IRQ_MSIX:
>> +		return cdns_pcie_hpa_ep_raise_msix_irq(ep, fn, vfn,
>interrupt_num);
>> +
>> +	default:
>> +		break;
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>> +
>
>[...]
>
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>> new file mode 100644
>> index 000000000000..b2e570f2c047
>> --- /dev/null
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>> @@ -0,0 +1,585 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Cadence
>> +// Cadence PCIe host controller driver.
>> +// Author: Manikandan K Pillai <mpillai@cadence.com>
>> +
>> +#include <linux/delay.h>
>> +#include <linux/kernel.h>
>> +#include <linux/list_sort.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_pci.h>
>> +#include <linux/platform_device.h>
>> +
>> +#include "pcie-cadence.h"
>> +#include "pcie-cadence-host-common.h"
>> +
>> +static u8 bar_aperture_mask[] = {
>> +	[RP_BAR0] = 0x1F,
>> +	[RP_BAR1] = 0xF,
>
>Use lowercase for hex.

Sure


>
>> +};
>> +
>
>[...]
>
>> +static void cdns_pcie_hpa_create_region_for_ecam(struct cdns_pcie_rc *rc)
>> +{
>> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
>> +	struct resource *cfg_res = rc->cfg_res;
>> +	struct cdns_pcie *pcie = &rc->pcie;
>> +	u32 value, root_port_req_id_reg, pcie_bus_number_reg;
>> +	u32 ecam_addr_0, region_size_0, request_id_0;
>> +	int busnr = 0, secbus = 0, subbus = 0;
>> +	struct resource_entry *entry;
>> +	resource_size_t size;
>> +	u32 axi_address_low;
>> +	int nbits;
>> +	u64 sz;
>> +
>> +	entry = resource_list_first_type(&bridge->windows,
>IORESOURCE_BUS);
>> +	if (entry) {
>> +		busnr = entry->res->start;
>> +		secbus = (busnr < 0xff) ? (busnr + 1) : 0xff;
>> +		subbus = entry->res->end;
>> +	}
>> +	size = resource_size(cfg_res);
>> +	sz = 1ULL << fls64(size - 1);
>> +	nbits = ilog2(sz);
>> +	if (nbits < 8)
>> +		nbits = 8;
>> +
>> +	root_port_req_id_reg = ((busnr & 0xff) << 8);
>> +	pcie_bus_number_reg = ((subbus & 0xff) << 16) | ((secbus & 0xff) <<
>8) |
>> +			      (busnr & 0xff);
>> +	ecam_addr_0 = cfg_res->start;
>> +	region_size_0 = nbits - 1;
>> +	request_id_0 = ((busnr & 0xff) << 8);
>> +
>> +#define CDNS_PCIE_HPA_TAG_MANAGEMENT (0x0)
>
>Do not use inline definitions. Define them at the start of the file.

Moving all #defines to the header file

>
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_TAG_MANAGEMENT, 0x200000);
>> +
>> +	/* Taking slave err as OKAY */
>> +#define CDNS_PCIE_HPA_SLAVE_RESP (0x100)
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>CDNS_PCIE_HPA_SLAVE_RESP,
>> +			     0x0);
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_SLAVE_RESP + 0x4, 0x0);
>> +
>> +	/* Program the register "i_root_port_req_id_reg" with RP's BDF */
>> +#define I_ROOT_PORT_REQ_ID_REG (0x141c)
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG,
>I_ROOT_PORT_REQ_ID_REG,
>> +			     root_port_req_id_reg);
>> +
>> +	/**
>> +	 * Program the register "i_pcie_bus_numbers" with Primary(RP's bus
>number),
>> +	 * secondary and subordinate bus numbers
>> +	 */
>> +#define I_PCIE_BUS_NUMBERS (CDNS_PCIE_HPA_RP_BASE + 0x18)
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_RP, I_PCIE_BUS_NUMBERS,
>> +			     pcie_bus_number_reg);
>> +
>> +	/* Program the register "lm_hal_sbsa_ctrl[0]" to enable the sbsa */
>> +#define LM_HAL_SBSA_CTRL (0x1170)
>> +	value = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG,
>LM_HAL_SBSA_CTRL);
>> +	value |= BIT(0);
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL,
>value);
>> +
>> +	/* Program region[0] for ECAM */
>> +	axi_address_low = (ecam_addr_0 & 0xfff00000) | region_size_0;
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(0),
>> +			     axi_address_low);
>> +
>> +	/* rc0-high-axi-address */
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(0),
>0x0);
>> +	/* Type-1 CFG */
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_DESC0(0),
>0x05000000);
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0),
>> +			     (request_id_0 << 16));
>> +
>> +	/* All AXI bits pass through PCIe */
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(0),
>0x1b);
>> +	/* PCIe address-high */
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(0),
>0);
>> +	cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
>> +			     CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(0),
>0x06000000);
>> +}
>
>[...]
>
>> +int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc)
>> +{
>> +	struct cdns_pcie *pcie = &rc->pcie;
>> +	struct device *dev = rc->pcie.dev;
>> +	int ret;
>> +
>> +	if (rc->quirk_detect_quiet_flag)
>> +		cdns_pcie_hpa_detect_quiet_min_delay_set(&rc->pcie);
>> +
>> +	cdns_pcie_hpa_host_enable_ptm_response(pcie);
>> +
>> +	ret = cdns_pcie_start_link(pcie);
>> +	if (ret) {
>> +		dev_err(dev, "Failed to start link\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = cdns_pcie_hpa_host_start_link(rc);
>> +	if (ret)
>> +		dev_dbg(dev, "PCIe link never came up\n");
>
>You are not supposed to fail the probe if link doesn't come up.

Removing the return here, to ensure probe continues
>
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_link_setup);
>> +
>
>[...]
>
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>b/drivers/pci/controller/cadence/pcie-cadence.h
>> index 1174cf597bb0..f2eb3f09b21a 100644
>> --- a/drivers/pci/controller/cadence/pcie-cadence.h
>> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
>> @@ -7,6 +7,7 @@
>>  #define _PCIE_CADENCE_H
>>
>>  #include <linux/kernel.h>
>> +#include <linux/module.h>
>>  #include <linux/pci.h>
>>  #include <linux/pci-epf.h>
>>  #include <linux/phy/phy.h>
>> @@ -42,9 +43,9 @@ enum cdns_pcie_reg_bank {
>>  };
>>
>>  struct cdns_pcie_ops {
>> -	int	(*start_link)(struct cdns_pcie *pcie);
>> -	void	(*stop_link)(struct cdns_pcie *pcie);
>> -	bool	(*link_up)(struct cdns_pcie *pcie);
>> +	int     (*start_link)(struct cdns_pcie *pcie);
>> +	void    (*stop_link)(struct cdns_pcie *pcie);
>> +	bool    (*link_up)(struct cdns_pcie *pcie);
>>  	u64     (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
>>  };
>>
>> @@ -76,6 +77,7 @@ struct cdns_plat_pcie_of_data {
>>   * struct cdns_pcie - private data for Cadence PCIe controller drivers
>>   * @reg_base: IO mapped register base
>>   * @mem_res: start/end offsets in the physical system memory to map PCI
>accesses
>> + * @msg_res: Region for send message to map PCI accesses
>>   * @dev: PCIe controller
>>   * @is_rc: tell whether the PCIe controller mode is Root Complex or
>Endpoint.
>>   * @phy_count: number of supported PHY devices
>> @@ -88,6 +90,7 @@ struct cdns_plat_pcie_of_data {
>>  struct cdns_pcie {
>>  	void __iomem		             *reg_base;
>>  	struct resource		             *mem_res;
>> +	struct resource                      *msg_res;
>>  	struct device		             *dev;
>>  	bool			             is_rc;
>>  	int			             phy_count;
>> @@ -110,6 +113,7 @@ struct cdns_pcie {
>>   *                available
>>   * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
>>   * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
>> + * @ecam_support_flag: Whether the ECAM flag is supported
>>   */
>>  struct cdns_pcie_rc {
>>  	struct cdns_pcie	pcie;
>> @@ -120,6 +124,8 @@ struct cdns_pcie_rc {
>>  	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
>>  	unsigned int		quirk_retrain_flag:1;
>>  	unsigned int		quirk_detect_quiet_flag:1;
>> +	unsigned int            ecam_support_flag:1;
>
>ecam_supported
>
>> +	unsigned int		no_inbound_flag:1;
>
>no_inbound_map

Both changes taken care.
>
>- Mani
>
>--
>மணிவண்ணன் சதாசிவம்

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

end of thread, other threads:[~2025-09-01  5:36 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-19 11:52 [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers hans.zhang
2025-08-19 11:52 ` [PATCH v8 01/15] PCI: cadence: Add module support for platform controller driver hans.zhang
2025-08-19 11:52 ` [PATCH v8 02/15] PCI: cadence: Split PCIe controller header file hans.zhang
2025-08-19 11:52 ` [PATCH v8 03/15] PCI: cadence: Add register definitions for High Perf Architecture (HPA) hans.zhang
2025-08-19 17:36   ` ALOK TIWARI
2025-08-20  8:14     ` Manikandan Karunakaran Pillai
2025-08-19 11:52 ` [PATCH v8 04/15] PCI: cadence: Add helper functions for supporting " hans.zhang
2025-08-19 11:52 ` [PATCH v8 05/15] PCI: cadence: Move PCIe EP common functions to a separate file hans.zhang
2025-08-19 17:46   ` ALOK TIWARI
2025-08-19 11:52 ` [PATCH v8 06/15] PCI: cadence: Move PCIe RP " hans.zhang
2025-08-30 10:36   ` Manivannan Sadhasivam
2025-09-01  4:30     ` Manikandan Karunakaran Pillai
2025-08-19 11:52 ` [PATCH v8 07/15] PCI: cadence: Move PCIe controller common functions as " hans.zhang
2025-08-30 11:21   ` Manivannan Sadhasivam
2025-09-01  4:30     ` Manikandan Karunakaran Pillai
2025-08-19 11:52 ` [PATCH v8 08/15] PCI: cadence: Add support for High Perf Architecture (HPA) controller hans.zhang
2025-08-26 12:08   ` kernel test robot
2025-08-30 13:18   ` Manivannan Sadhasivam
2025-09-01  4:34     ` Manikandan Karunakaran Pillai
2025-08-19 11:52 ` [PATCH v8 09/15] PCI: cadence: Update PCIe platform to use register offsets passed hans.zhang
2025-08-19 11:52 ` [PATCH v8 10/15] dt-bindings: PCI: Add CIX Sky1 PCIe Root Complex bindings hans.zhang
2025-08-20  7:23   ` Krzysztof Kozlowski
2025-08-19 11:52 ` [PATCH v8 11/15] PCI: Add Cix Technology Vendor and Device ID hans.zhang
2025-08-30 13:20   ` Manivannan Sadhasivam
2025-08-30 13:21   ` Manivannan Sadhasivam
2025-09-01  3:03     ` Hans Zhang
2025-08-19 11:52 ` [PATCH v8 12/15] PCI: sky1: Add PCIe host support for CIX Sky1 hans.zhang
2025-08-30 13:29   ` Manivannan Sadhasivam
2025-09-01  3:04     ` Hans Zhang
2025-08-19 11:52 ` [PATCH v8 13/15] MAINTAINERS: add entry for CIX Sky1 PCIe driver hans.zhang
2025-08-19 11:52 ` [PATCH v8 14/15] arm64: dts: cix: Add PCIe Root Complex on sky1 hans.zhang
2025-08-30 13:31   ` Manivannan Sadhasivam
2025-09-01  3:09     ` Hans Zhang
2025-08-19 11:52 ` [PATCH v8 15/15] arm64: dts: cix: Enable PCIe on the Orion O6 board hans.zhang
2025-08-30 13:33   ` Manivannan Sadhasivam
2025-09-01  3:14     ` Hans Zhang
2025-09-01  3:17       ` Hans Zhang
2025-08-30 13:38 ` [PATCH v8 00/15] Enhance the PCIe controller driver for next generation controllers Manivannan Sadhasivam
2025-09-01  4:28   ` Manikandan Karunakaran Pillai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).