diff mbox series

Enhance PCIe cadence controller driver for supporting HPA architecture

Message ID CH2PPF4D26F8E1CB68755477DCA7AA9C6EBA2EE2@CH2PPF4D26F8E1C.namprd07.prod.outlook.com (mailing list archive)
State Changes Requested
Headers show
Series Enhance PCIe cadence controller driver for supporting HPA architecture | expand

Commit Message

Manikandan Karunakaran Pillai Jan. 29, 2025, 7:24 a.m. UTC
This patch enhances the Cadence PCIe controller driver to support HPA
architecture. The Kconfig is added for PCIE_CADENCE_HPA config, which
needs to be selected when HPA compatible PCIe controller is supported.
The support for Legacy PCIe controller does not change.

Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Signed-off-by: yuanzhao <yuanzhao@cadence.com>
---
 drivers/pci/controller/cadence/Kconfig        |   8 +
 .../pci/controller/cadence/pcie-cadence-ep.c  |  12 +-
 .../controller/cadence/pcie-cadence-host.c    |  44 ++-
 .../pci/controller/cadence/pcie-cadence-hpa.h | 260 ++++++++++++++++++
 .../controller/cadence/pcie-cadence-legacy.h  | 243 ++++++++++++++++
 drivers/pci/controller/cadence/pcie-cadence.c |  42 ++-
 drivers/pci/controller/cadence/pcie-cadence.h | 230 +---------------
 7 files changed, 598 insertions(+), 241 deletions(-)
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.h
 create mode 100644 drivers/pci/controller/cadence/pcie-cadence-legacy.h

Comments

Bjorn Helgaas Jan. 29, 2025, 3:26 p.m. UTC | #1
Take a look at the additions of previous drivers and follow the style.
For example:

  2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver")
  0e898eb8df4e ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
  da36024a4e83 ("PCI: visconti: Add Toshiba Visconti PCIe host controller driver")
  f3e25911a430 ("PCI: j721e: Add TI J721E PCIe driver")

After skimming the patch, it looks like this doesn't actually add a
new driver, but adds support to an existing driver for some kind of
different surrounding platform architecture.

On Wed, Jan 29, 2025 at 07:24:04AM +0000, Manikandan Karunakaran Pillai wrote:
> This patch enhances the Cadence PCIe controller driver to support HPA
> architecture. The Kconfig is added for PCIE_CADENCE_HPA config, which
> needs to be selected when HPA compatible PCIe controller is supported.
> The support for Legacy PCIe controller does not change.

Use imperative mood ("Enhance" instead of "This patch enhances ...").

Expand "HPA".

>  drivers/pci/controller/cadence/Kconfig        |   8 +
>  .../pci/controller/cadence/pcie-cadence-ep.c  |  12 +-
>  .../controller/cadence/pcie-cadence-host.c    |  44 ++-
>  .../pci/controller/cadence/pcie-cadence-hpa.h | 260 ++++++++++++++++++
>  .../controller/cadence/pcie-cadence-legacy.h  | 243 ++++++++++++++++
>  drivers/pci/controller/cadence/pcie-cadence.c |  42 ++-
>  drivers/pci/controller/cadence/pcie-cadence.h | 230 +---------------

This looks like it should be 5+ separate patches to make this
reviewable.  Each patch should do only *one* thing.  Obviously
everything must build and work correctly after each patch is added.

> +++ b/drivers/pci/controller/cadence/Kconfig
> @@ -6,6 +6,14 @@ menu "Cadence-based PCIe controllers"
>  config PCIE_CADENCE
>  	bool
>  
> +config PCIE_CADENCE_HPA
> +	bool "PCIE controller HPA architecture"

s/PCIE/PCIe/ to match other entries.

Change the menu item to match surrounding entries (include vendor,
host/endpoint, etc).

But I don't think this is a *new* driver; it looks like it might be
optional functionality for the PCIE_CADENCE_PLAT and/or PCI_J721E
drivers?  Maybe it needs to depend on PCIE_CADENCE?

> +	help
> +	  Say Y here if you want to support Cadence PCIe Platform controller
> +	  on HPA architecture
> +	  The option should be deselected if the Cadence PCIe controller
> +	  is of legacy architecture

"HPA" must be expanded here too.

Omit the "deselect part".  A user has no way to identify what "legacy
architecture" means here.

> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> @@ -121,7 +121,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
>  	else
>  		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
> +#ifdef CONFIG_PCIE_CADENCE_HPA

Nope.  I don't want #ifdefs like this littered through the cadence
generic code.  The driver should be able to support both HPA and
non-HPA in the same kernel image.  You should be able to decide at
run-time, not at build-time.

> +	b = (bar < BAR_3) ? bar : bar - BAR_3;
> +#else
>  	b = (bar < BAR_4) ? bar : bar - BAR_4;
> +#endif

> +++ b/drivers/pci/controller/cadence/pcie-cadence-hpa.h
> @@ -0,0 +1,260 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe Gen5(HPA) controller driver defines

Space before "(".  Expand HPA.

> + * This file contains the updates/changes for PCIE Gen5 Controller

s/PCIE/PCIe/ everywhere in commit logs and comments.

> +#define CDNS_PCIE_IP_REG_BANK           (0x01000000)
> +#define CDNS_PCIE_IP_CFG_CTRL_REG_BANK  (0x01003C00)
> +#define CDNS_PCIE_IP_AXI_MASTER_COMMON  (0x02020000)

No parens needed for bare numbers.

> +/* Vendor ID Register */
> +#define CDNS_PCIE_LM_ID		        (CDNS_PCIE_IP_REG_BANK + 0x1420)
> +#define  CDNS_PCIE_LM_ID_VENDOR_MASK    GENMASK(15, 0)
> +#define  CDNS_PCIE_LM_ID_VENDOR_SHIFT   0

Omit _SHIFT definitions and use GENMASK()/FIELD_PREP()/FIELD_GET()
instead.

But it looks like this is mainly a move from one file to another.  A
move like that should be strictly a move and shouldn't change the
content at the same time.

The move should be in its own patch that does nothing other than the
move, so you can ignore some of these comments for now.

> +#define CDNS_PCIE_LM_EP_FUNC_CFG	(CDNS_PCIE_IP_REG_BANK + 0x02c0)

Pick either upper-case or lower-case for hex numbers and stick to it.

> +#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_ENABLE BIT(0)
> +#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_IO BIT(1)
> +#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_MEM (0)
> +#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_32BITS (0)
> +#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_PREFETCH_MEM_DISABLE (0)

These are unused.  Don't add #defines that are not used.

When you do add them, indent the BIT() parts to they line up.

> +++ b/drivers/pci/controller/cadence/pcie-cadence.c
> ...
>  	/*
>  	 * Whatever Bit [23] is set or not inside DESC0 register of the outbound
>  	 * PCIe descriptor, the PCI function number must be set into
>  	 * Bits [26:24] of DESC0 anyway.
> +	 * for HPA, Bit [26] is set or not inside CTRL0 register of the outbound
> +	 * PCI descriptor, the PCI function num must be set into Bits [31:24]
> +	 * of DESC1 anyway.

Start sentences with a capital letter.

Add blank lines between paragraphs.

> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -10,213 +10,11 @@
>  #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

This looks like a move of a lot of things out of pcie-cadence.h to
somewhere else.  A move like this should be its own patch with its own
commit log.

It looks suspect because this is a generic header used by several
drivers.

Bjorn
Manikandan Karunakaran Pillai Jan. 31, 2025, 11:59 a.m. UTC | #2
>[PATCH] Enhance PCIe cadence controller driver for supporting
>HPA architecture
>
>EXTERNAL MAIL
>
>
>Take a look at the additions of previous drivers and follow the style.
>For example:
>
>  2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller
>driver")
>  0e898eb8df4e ("PCI: rockchip-dwc: Add Rockchip RK356X host controller
>driver")
>  da36024a4e83 ("PCI: visconti: Add Toshiba Visconti PCIe host controller
>driver")
>  f3e25911a430 ("PCI: j721e: Add TI J721E PCIe driver")
>
>After skimming the patch, it looks like this doesn't actually add a new driver,
>but adds support to an existing driver for some kind of different surrounding
>platform architecture.
>

The patch adds support for Cadence second generation PCIe controllers, referred 
as High performance Architecture(HPA).

>On Wed, Jan 29, 2025 at 07:24:04AM +0000, Manikandan Karunakaran Pillai
>wrote:
>> This patch enhances the Cadence PCIe controller driver to support HPA
>> architecture. The Kconfig is added for PCIE_CADENCE_HPA config, which
>> needs to be selected when HPA compatible PCIe controller is supported.
>> The support for Legacy PCIe controller does not change.
>
>Use imperative mood ("Enhance" instead of "This patch enhances ...").
>
>Expand "HPA".
>
>>  drivers/pci/controller/cadence/Kconfig        |   8 +
>>  .../pci/controller/cadence/pcie-cadence-ep.c  |  12 +-
>>  .../controller/cadence/pcie-cadence-host.c    |  44 ++-
>>  .../pci/controller/cadence/pcie-cadence-hpa.h | 260
>> ++++++++++++++++++  .../controller/cadence/pcie-cadence-legacy.h  |
>> 243 ++++++++++++++++  drivers/pci/controller/cadence/pcie-cadence.c |
>> 42 ++-  drivers/pci/controller/cadence/pcie-cadence.h | 230
>> +---------------
>
>This looks like it should be 5+ separate patches to make this reviewable.  Each
>patch should do only *one* thing.  Obviously everything must build and work
>correctly after each patch is added.
Will break into smaller patches and send them
>
>> +++ b/drivers/pci/controller/cadence/Kconfig
>> @@ -6,6 +6,14 @@ menu "Cadence-based PCIe controllers"
>>  config PCIE_CADENCE
>>  	bool
>>
>> +config PCIE_CADENCE_HPA
>> +	bool "PCIE controller HPA architecture"
>
>s/PCIE/PCIe/ to match other entries.
>
>Change the menu item to match surrounding entries (include vendor,
>host/endpoint, etc).
>
>But I don't think this is a *new* driver; it looks like it might be optional
>functionality for the PCIE_CADENCE_PLAT and/or PCI_J721E drivers?  Maybe it
>needs to depend on PCIE_CADENCE?
>
>> +	help
>> +	  Say Y here if you want to support Cadence PCIe Platform controller
>> +	  on HPA architecture
>> +	  The option should be deselected if the Cadence PCIe controller
>> +	  is of legacy architecture
>
>"HPA" must be expanded here too.
>
>Omit the "deselect part".  A user has no way to identify what "legacy
>architecture" means here.
>
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
>> @@ -121,7 +121,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc,
>u8 fn, u8 vfn,
>>  		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
>>  	else
>>  		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
>> +#ifdef CONFIG_PCIE_CADENCE_HPA
>
>Nope.  I don't want #ifdefs like this littered through the cadence generic code.
>The driver should be able to support both HPA and non-HPA in the same
>kernel image.  You should be able to decide at run-time, not at build-time.

Cadence PCIe controller does not have a version register that could be used to check the architecture, however 
one of the PCIe config space registers provides different reset values for the different architectures. This register will
be used to support the HPA and non-HPA in the same kernel image.

>
>> +	b = (bar < BAR_3) ? bar : bar - BAR_3; #else
>>  	b = (bar < BAR_4) ? bar : bar - BAR_4;
>> +#endif
>
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-hpa.h
>> @@ -0,0 +1,260 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */ // Copyright (c) 2017 Cadence
>> +// Cadence PCIe Gen5(HPA) controller driver defines
>
>Space before "(".  Expand HPA.
>
>> + * This file contains the updates/changes for PCIE Gen5 Controller
>
>s/PCIE/PCIe/ everywhere in commit logs and comments.
>
>> +#define CDNS_PCIE_IP_REG_BANK           (0x01000000)
>> +#define CDNS_PCIE_IP_CFG_CTRL_REG_BANK  (0x01003C00) #define
>> +CDNS_PCIE_IP_AXI_MASTER_COMMON  (0x02020000)
>
>No parens needed for bare numbers.
>
>> +/* Vendor ID Register */
>> +#define CDNS_PCIE_LM_ID		        (CDNS_PCIE_IP_REG_BANK +
>0x1420)
>> +#define  CDNS_PCIE_LM_ID_VENDOR_MASK    GENMASK(15, 0)
>> +#define  CDNS_PCIE_LM_ID_VENDOR_SHIFT   0
>
>Omit _SHIFT definitions and use GENMASK()/FIELD_PREP()/FIELD_GET()
>instead.
>
>But it looks like this is mainly a move from one file to another.  A move like that
>should be strictly a move and shouldn't change the content at the same time.
>
>The move should be in its own patch that does nothing other than the move,
>so you can ignore some of these comments for now.
>
>> +#define CDNS_PCIE_LM_EP_FUNC_CFG	(CDNS_PCIE_IP_REG_BANK +
>0x02c0)
>
>Pick either upper-case or lower-case for hex numbers and stick to it.
>
>> +#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_ENABLE BIT(0) #define
>> +CDNS_PCIE_LM_RC_BAR_CFG_BAR0_IO BIT(1) #define
>> +CDNS_PCIE_LM_RC_BAR_CFG_BAR0_MEM (0) #define
>> +CDNS_PCIE_LM_RC_BAR_CFG_BAR0_32BITS (0) #define
>> +CDNS_PCIE_LM_RC_BAR_CFG_BAR0_PREFETCH_MEM_DISABLE (0)
>
>These are unused.  Don't add #defines that are not used.
>
>When you do add them, indent the BIT() parts to they line up.
>
>> +++ b/drivers/pci/controller/cadence/pcie-cadence.c
>> ...
>>  	/*
>>  	 * Whatever Bit [23] is set or not inside DESC0 register of the outbound
>>  	 * PCIe descriptor, the PCI function number must be set into
>>  	 * Bits [26:24] of DESC0 anyway.
>> +	 * for HPA, Bit [26] is set or not inside CTRL0 register of the outbound
>> +	 * PCI descriptor, the PCI function num must be set into Bits [31:24]
>> +	 * of DESC1 anyway.
>
>Start sentences with a capital letter.
>
>Add blank lines between paragraphs.
>
>> --- a/drivers/pci/controller/cadence/pcie-cadence.h
>> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
>> @@ -10,213 +10,11 @@
>>  #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
>
>This looks like a move of a lot of things out of pcie-cadence.h to somewhere
>else.  A move like this should be its own patch with its own commit log.
>
>It looks suspect because this is a generic header used by several drivers.
>
>Bjorn
diff mbox series

Patch

diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
index 8a0044bb3989..d7501ce7b39e 100644
--- a/drivers/pci/controller/cadence/Kconfig
+++ b/drivers/pci/controller/cadence/Kconfig
@@ -6,6 +6,14 @@  menu "Cadence-based PCIe controllers"
 config PCIE_CADENCE
 	bool
 
+config PCIE_CADENCE_HPA
+	bool "PCIE controller HPA architecture"
+	help
+	  Say Y here if you want to support Cadence PCIe Platform controller
+	  on HPA architecture
+	  The option should be deselected if the Cadence PCIe controller
+	  is of legacy architecture
+
 config PCIE_CADENCE_HOST
 	bool
 	depends on OF
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index e0cc4560dfde..caf8040b12e9 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -121,7 +121,11 @@  static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
 	else
 		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	b = (bar < BAR_3) ? bar : bar - BAR_3;
+#else
 	b = (bar < BAR_4) ? bar : bar - BAR_4;
+#endif
 
 	if (vfn == 0 || vfn == 1) {
 		cfg = cdns_pcie_readl(pcie, reg);
@@ -158,7 +162,11 @@  static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
 	else
 		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	b = (bar < BAR_3) ? bar : bar - BAR_3;
+#else
 	b = (bar < BAR_4) ? bar : bar - BAR_4;
+#endif
 
 	if (vfn == 0 || vfn == 1) {
 		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
@@ -569,7 +577,6 @@  static int cdns_pcie_ep_start(struct pci_epc *epc)
 	 * BIT(0) is hardwired to 1, hence function 0 is always enabled
 	 * and can't be disabled anyway.
 	 */
-	cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, epc->function_num_map);
 
 	/*
 	 * Next function field in ARI_CAP_AND_CTR register for last function
@@ -682,9 +689,6 @@  int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	if (!ep->ob_addr)
 		return -ENOMEM;
 
-	/* Disable all but function 0 (anyway BIT(0) is hardwired to 1). */
-	cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, BIT(0));
-
 	epc = devm_pci_epc_create(dev, &cdns_pcie_epc_ops);
 	if (IS_ERR(epc)) {
 		dev_err(dev, "failed to create epc device\n");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 8af95e9da7ce..be279c5baa5d 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -14,6 +14,18 @@ 
 
 #define LINK_RETRAIN_TIMEOUT HZ
 
+#ifdef CONFIG_PCIE_CADENCE_HPA
+static u64 bar_max_size[] = {
+	[RP_BAR0] = SZ_2G,
+	[RP_BAR1] = SZ_2G,
+	[RP_NO_BAR] = _BITULL(63),
+};
+
+static u8 bar_aperture_mask[] = {
+	[RP_BAR0] = 0xF,
+	[RP_BAR1] = 0xF,
+};
+#else
 static u64 bar_max_size[] = {
 	[RP_BAR0] = _ULL(128 * SZ_2G),
 	[RP_BAR1] = SZ_2G,
@@ -24,6 +36,7 @@  static u8 bar_aperture_mask[] = {
 	[RP_BAR0] = 0x1F,
 	[RP_BAR1] = 0xF,
 };
+#endif
 
 void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 			       int where)
@@ -32,7 +45,7 @@  void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 	struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
 	struct cdns_pcie *pcie = &rc->pcie;
 	unsigned int busn = bus->number;
-	u32 addr0, desc0;
+	u32 addr0, desc0, desc1, ctrl0;
 
 	if (pci_is_root_bus(bus)) {
 		/*
@@ -46,20 +59,30 @@  void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 		return pcie->reg_base + (where & 0xfff);
 	}
 	/* Check that the link is up */
-	if (!(cdns_pcie_readl(pcie, CDNS_PCIE_LM_BASE) & 0x1))
+	if (!(cdns_pcie_readl(pcie, (CDNS_PCIE_AT_LINKDOWN)) & 0x1))
 		return NULL;
 	/* Clear AXI link-down status */
-	cdns_pcie_writel(pcie, CDNS_PCIE_AT_LINKDOWN, 0x0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_LINKDOWN,
+			 cdns_pcie_readl(pcie, CDNS_PCIE_AT_LINKDOWN) & 0xe);
 
 	/* Update Output registers for AXI region 0. */
 	addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
 		CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) |
 		CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(busn);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(0), addr0);
-
+	desc1 = 0;
+	ctrl0 = 0;
 	/* Configuration Type 0 or Type 1 access. */
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	desc1 = cdns_pcie_readl(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0));
+	desc1 &= ~CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN_MASK;
+	desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN(0);
+	ctrl0 = CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_BUS |
+		CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN;
+#else
 	desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
 		CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+#endif
 	/*
 	 * The bus number was already set once for all in desc1 by
 	 * cdns_pcie_host_init_address_translation().
@@ -69,7 +92,10 @@  void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 	else
 		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1;
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(0), desc0);
-
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CTRL0(0), ctrl0);
+#endif
 	return rc->cfg_base + (where & 0xfff);
 }
 
@@ -239,11 +265,19 @@  static int cdns_pcie_host_bar_ib_config(struct cdns_pcie_rc *rc,
 		return 0;
 
 	value = cdns_pcie_readl(pcie, CDNS_PCIE_LM_RC_BAR_CFG);
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	value &= ~(LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar) |
+		   LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) |
+		   LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar) |
+		   LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) |
+		   LM_RC_BAR_CFG_APERTURE(bar, bar_aperture_mask[bar] + 7));
+#else
 	value &= ~(LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar) |
 		   LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) |
 		   LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar) |
 		   LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) |
 		   LM_RC_BAR_CFG_APERTURE(bar, bar_aperture_mask[bar] + 2));
+#endif
 	if (size + cpu_addr >= SZ_4G) {
 		if (!(flags & IORESOURCE_PREFETCH))
 			value |= LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar);
diff --git a/drivers/pci/controller/cadence/pcie-cadence-hpa.h b/drivers/pci/controller/cadence/pcie-cadence-hpa.h
new file mode 100644
index 000000000000..ee0bd76d84a0
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-hpa.h
@@ -0,0 +1,260 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2017 Cadence
+// Cadence PCIe Gen5(HPA) controller driver defines
+// Author: Manikandan K Pillai <mpillai@cadence.com>
+
+#ifndef _PCIE_CADENCE_HPA_H
+#define _PCIE_CADENCE_HPA_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-epf.h>
+#include <linux/phy/phy.h>
+
+/*
+ * This file contains the updates/changes for PCIE Gen5 Controller
+ */
+/* 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 are renamed here and
+ * are in tune with PCIe Gen5 changes in controller
+ */
+#define CDNS_PCIE_IP_REG_BANK           (0x01000000)
+#define CDNS_PCIE_IP_CFG_CTRL_REG_BANK  (0x01003C00)
+#define CDNS_PCIE_IP_AXI_MASTER_COMMON  (0x02020000)
+
+/* Vendor ID Register */
+#define CDNS_PCIE_LM_ID		        (CDNS_PCIE_IP_REG_BANK + 0x1420)
+#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)
+
+/* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_3) ? CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(pfn) \
+	(CDNS_PCIE_IP_CFG_CTRL_REG_BANK + (0x4000 * (pfn)))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(pfn) \
+	(CDNS_PCIE_IP_CFG_CTRL_REG_BANK + (0x4000 * (pfn)) + 0x04)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_3) ? CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(vfn) \
+	(CDNS_PCIE_IP_CFG_CTRL_REG_BANK + (0x4000 * (vfn)) + 0x08)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(vfn) \
+	(CDNS_PCIE_IP_CFG_CTRL_REG_BANK + (0x4000 * (vfn)) + 0x0C)
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(f) \
+	(GENMASK(9, 4) << ((f) * 10))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+	(((a) << (4 + ((b) * 10))) & (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b)))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(f) \
+	(GENMASK(3, 0) << ((f) * 10))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+	(((c) << ((b) * 10)) & (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)))
+
+/* Endpoint Function Configuration Register */
+#define CDNS_PCIE_LM_EP_FUNC_CFG	(CDNS_PCIE_IP_REG_BANK + 0x02c0)
+
+/* Root Complex BAR Configuration Register */
+#define CDNS_PCIE_LM_RC_BAR_CFG	(CDNS_PCIE_IP_CFG_CTRL_REG_BANK + 0x14)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK	GENMASK(9, 4)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
+	(((a) << 4) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK		GENMASK(3, 0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \
+	(((c) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK	GENMASK(19, 14)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
+	(((a) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK		GENMASK(13, 10)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \
+	(((c) << 10) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK)
+
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_ENABLE BIT(0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_IO BIT(1)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_MEM (0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_32BITS (0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_PREFETCH_MEM_DISABLE (0)
+
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_ENABLE BIT(10)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_DISABLE (0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_IO BIT(11)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_MEM (0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_32BITS (0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_PREFETCH_MEM_ENABLE BIT(13)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_PREFETCH_MEM_DISABLE (0)
+
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE	BIT(20)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS    0
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS    BIT(21)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE      BIT(22)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS      0
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS      BIT(23)
+
+/* 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		0x3
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS		0x1
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS	0x9
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS		0x5
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS	0xD
+
+#define LM_RC_BAR_CFG_CTRL_DISABLED(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED << ((bar) * 10))
+#define LM_RC_BAR_CFG_CTRL_IO_32BITS(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS << ((bar) * 10))
+#define LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS << ((bar) * 10))
+#define LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar)	\
+	(CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS << ((bar) * 10))
+#define LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar)		\
+		(CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS << ((bar) * 10))
+#define LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar)	\
+	(CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS << ((bar) * 10))
+#define LM_RC_BAR_CFG_APERTURE(bar, aperture)		\
+					(((aperture) - 7) << ((bar) * 10))
+
+#define  CDNS_PCIE_LM_RC_CFG_BAR_APERTURE_MASK(b) \
+	 (GENMASK(9, 4) << ((b) * 10))
+
+/* PTM Control Register */
+#define CDNS_PCIE_LM_PTM_CTRL	(CDNS_PCIE_IP_REG_BANK + 0x0520)
+#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	0x0
+#define CDNS_PCIE_RP_CAP_OFFSET 0xc0
+
+/*
+ * Address Translation Registers
+ */
+#define CDNS_PCIE_AXI_SLAVE	0x03000000
+#define CDNS_PCIE_AXI_MASTER    0x03002000
+
+/* Region r Outbound AXI to PCIe Address Translation Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
+	(CDNS_PCIE_AXI_SLAVE + 0x1010 + ((r) & 0x1f) * 0x0080)
+#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(23, 16)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+	(((devfn) << 16) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK	GENMASK(31, 24)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+	(((bus) << 24) & 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_AXI_SLAVE + 0x1014 + ((r) & 0x1f) * 0x0080)
+
+/* Region r Outbound PCIe Descriptor Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_DESC0(r) \
+	(CDNS_PCIE_AXI_SLAVE + 0x1008 + ((r) & 0x1f) * 0x0080)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK		GENMASK(28, 24)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM	\
+	((0x0 << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO	\
+	((0x2 << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0  \
+	((0x4 << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1  \
+	((0x5 << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG  \
+	((0x10 << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK)
+
+/* Region r Outbound PCIe Descriptor Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_DESC1(r)	\
+	(CDNS_PCIE_AXI_SLAVE + 0x100c + ((r) & 0x1f) * 0x0080)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK	GENMASK(31, 24)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \
+	(((bus) << 24) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN_MASK    GENMASK(23, 16)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN(devfn) \
+	(((devfn) << 16) & CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN_MASK)
+
+#define CDNS_PCIE_AT_OB_REGION_CTRL0(r)	\
+	(CDNS_PCIE_AXI_SLAVE + 0x1018 + ((r) & 0x1f) * 0x0080)
+#define  CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_BUS BIT(26)
+#define  CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN BIT(25)
+
+/* Region r AXI Region Base Address Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
+	(CDNS_PCIE_AXI_SLAVE + 0x1000 + ((r) & 0x1f) * 0x0080)
+#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_AXI_SLAVE + 0x1004 + ((r) & 0x1f) * 0x0080)
+
+/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \
+	(CDNS_PCIE_AXI_MASTER + ((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_AXI_MASTER + 0x04 + ((bar) * 0x0008))
+
+/* AXI link down register */
+#define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AXI_SLAVE + 0x04)
+
+/* Physical Layer Configuration Register 0
+ * This register contains the parameters required for functional setup
+ * of Physical Layer.
+ */
+#define  CDNS_PCIE_PHY_LAYER_CFG0   (CDNS_PCIE_IP_REG_BANK + 0x0400)
+#define  CDNS_PCIE_LTSSM_CONTROL_CAP CDNS_PCIE_PHY_LAYER_CFG0
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK  GENMASK(26, 24)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 24
+#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        15
+
+/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+	(CDNS_PCIE_IP_AXI_MASTER_COMMON + ((fn) * 0x0040) + ((bar) * 0x0008))
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+	(CDNS_PCIE_IP_AXI_MASTER_COMMON + 0x4 + ((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_HPA_H */
diff --git a/drivers/pci/controller/cadence/pcie-cadence-legacy.h b/drivers/pci/controller/cadence/pcie-cadence-legacy.h
new file mode 100644
index 000000000000..1053cae9fd72
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-cadence-legacy.h
@@ -0,0 +1,243 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2017 Cadence
+// Cadence PCIe Gen4 controller driver defines
+// Author: Manikandan K Pillai <mpillai@cadence.com>
+
+#ifndef _PCIE_CADENCE_LEGACY_H
+#define _PCIE_CADENCE_LEGACY_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-epf.h>
+#include <linux/phy/phy.h>
+
+/*
+ * This file contains the changes for PCIE Gen4 Controller
+ */
+
+/* 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(fn0) \
+	(CDNS_PCIE_LM_BASE + 0x0240 + (fn0) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn1) \
+	(CDNS_PCIE_LM_BASE + 0x0244 + (fn1) * 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(fn0) \
+	(CDNS_PCIE_LM_BASE + 0x0280 + (fn0) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn1) \
+	(CDNS_PCIE_LM_BASE + 0x0284 + (fn1) * 0x0008)
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(ba) \
+	(GENMASK(4, 0) << ((ba) * 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(bc) \
+	(GENMASK(7, 5) << ((bc) * 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_LEGACY_H */
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index 204e045aed8c..edd7e5332e8e 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -34,7 +34,7 @@  void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 	 */
 	u64 sz = 1ULL << fls64(size - 1);
 	int nbits = ilog2(sz);
-	u32 addr0, addr1, desc0, desc1;
+	u32 addr0, addr1, desc0, desc1, ctrl0;
 
 	if (nbits < 8)
 		nbits = 8;
@@ -53,37 +53,51 @@  void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 	else
 		desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM;
 	desc1 = 0;
-
+	ctrl0 = 0;
 	/*
 	 * Whatever Bit [23] is set or not inside DESC0 register of the outbound
 	 * PCIe descriptor, the PCI function number must be set into
 	 * Bits [26:24] of DESC0 anyway.
+	 * for HPA, Bit [26] is set or not inside CTRL0 register of the outbound
+	 * PCI descriptor, the PCI function num 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 [23] is mandatory when in Root Complex mode:
-	 * then the driver must provide the bus, resp. device, number in
+	 * Besides, setting Bit [23]([26]- HPA) is mandatory when in Root Complex
+	 * mode then the driver must provide the bus, resp. device, number in
 	 * Bits [7:0] of DESC1, resp. Bits[31:27] 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 [23] of DESC0, hence
 	 * the PCIe controller will use the captured values for the bus and
-	 * device numbers.
+	 * device numbers. For Gen 5, instead clear Bit [26] of CTRL0.
 	 */
 	if (pcie->is_rc) {
+#ifdef CONFIG_PCIE_CADENCE_HPA
+		desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr) |
+			CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN(0);
+		ctrl0 = CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_BUS |
+			CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN;
+#else
 		/* The device and function numbers are always 0. */
 		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
 			 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
 		desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr);
+#endif
 	} else {
 		/*
 		 * Use captured values for bus and device numbers but still
 		 * need to set the function number.
 		 */
+#ifdef CONFIG_PCIE_CADENCE_HPA
+		desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN(fn);
+#else
 		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
+#endif
 	}
 
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), desc0);
@@ -105,12 +119,23 @@  void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
 						  u8 busnr, u8 fn,
 						  u32 r, u64 cpu_addr)
 {
-	u32 addr0, addr1, desc0, desc1;
+	u32 addr0, addr1, desc0, desc1, ctrl0;
 
 	desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG;
 	desc1 = 0;
+	ctrl0 = 0;
 
 	/* See cdns_pcie_set_outbound_region() comments above. */
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	if (pcie->is_rc) {
+		desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr) |
+			CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN(0);
+		ctrl0 = CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_BUS |
+			CDNS_PCIE_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN;
+	} else {
+		desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_DEVFN(fn);
+	}
+#else
 	if (pcie->is_rc) {
 		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
 			 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
@@ -118,7 +143,7 @@  void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
 	} else {
 		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
 	}
-
+#endif
 	/* Set the CPU address */
 	if (pcie->ops->cpu_addr_fixup)
 		cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
@@ -133,6 +158,9 @@  void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
+#ifdef CONFIG_PCIE_CADENCE_HPA
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CTRL0(r), ctrl0);
+#endif
 }
 
 void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index f5eeff834ec1..47de8e9e9abb 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -10,213 +10,11 @@ 
 #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)
+#ifdef CONFIG_PCIE_CADENCE_HPA
+#include "pcie-cadence-hpa.h"
+#else
+#include "pcie-cadence-legacy.h"
+#endif
 
 enum cdns_pcie_rp_bar {
 	RP_BAR_UNDEFINED = -1,
@@ -225,29 +23,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_NO_DATA			BIT(16)
-
 struct cdns_pcie;
 
 enum cdns_pcie_msg_code {