Re: [PATCH v2 3/3] PCI: cadence: Use dynamic PCIe capability offset in host driver
From: Aksh Garg
Date: Mon May 11 2026 - 00:48:01 EST
Hi Hans,
On 09/05/26 18:37, Hans Zhang wrote:
The Cadence PCIe controller may place the PCI Express Capability
structure at different offsets depending on SoC integration. The
hardcoded CDNS_PCIE_RP_CAP_OFFSET (0xC0) is not universally valid.
Replace all uses of the fixed offset with the dynamically cached
pcie->pcie_cap obtained via cdns_pcie_get_pcie_cap(). This affects:
- Root Port training completion check
- Link retraining
- Root Port initialization (ASPM quirks)
Also remove the now-unused CDNS_PCIE_RP_CAP_OFFSET definition from
pcie-cadence-lga-regs.h.
This change ensures correct operation across different Cadence IP
generations (LGA and HPA) and SoC designs.
Signed-off-by: Hans Zhang <18255117159@xxxxxxx>
---
drivers/pci/controller/cadence/pcie-cadence-ep.c | 5 +++--
drivers/pci/controller/cadence/pcie-cadence-host-common.c | 4 ++--
drivers/pci/controller/cadence/pcie-cadence-host-hpa.c | 2 ++
drivers/pci/controller/cadence/pcie-cadence-host.c | 6 ++++--
drivers/pci/controller/cadence/pcie-cadence-lga-regs.h | 1 -
5 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 38a0157b60dc..eeee954f7dc7 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -571,9 +571,8 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
int max_epfs = sizeof(epc->function_num_map) * 8;
int ret, epf, last_fn;
u32 reg, value;
- u8 cap;
+ u8 cap = pcie->pcie_cap;
Can we eliminate the use of 'cap' variable and use 'pcie->pcie_cap' directly, just like in cdns_pcie_host_init_root_port()?
- cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP);
/*
* BIT(0) is hardwired to 1, hence function 0 is always enabled
* and can't be disabled anyway.
@@ -690,6 +689,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
}
pcie->mem_res = res;
+ cdns_pcie_get_pcie_cap(pcie);
+
ep->max_regions = CDNS_PCIE_MAX_OB;
of_property_read_u32(np, "cdns,max-outbound-regions", &ep->max_regions);
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
index 2b0211870f02..26b248231558 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
@@ -26,7 +26,7 @@ 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;
+ u32 pcie_cap_off = pcie->pcie_cap;> unsigned long end_jiffies;
u16 lnk_stat;
@@ -68,7 +68,7 @@ EXPORT_SYMBOL_GPL(cdns_pcie_host_wait_for_link);
int cdns_pcie_retrain(struct cdns_pcie *pcie,
cdns_pcie_linkup_func pcie_link_up)
{
- u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
+ u32 lnk_cap_sls, pcie_cap_off = pcie->pcie_cap;
u16 lnk_stat, lnk_ctl;
int ret = 0;