Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH] PCI: cadence: Use cdns_pcie_find_capability() to get PCIe Cap offset in host driver
@ 2026-05-03 16:19 Hans Zhang
  2026-05-03 16:52 ` sashiko-bot
  0 siblings, 1 reply; 11+ messages in thread
From: Hans Zhang @ 2026-05-03 16:19 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kwilczynski, mani
  Cc: robh, linux-pci, linux-kernel, Hans Zhang

The PCI Express capability structure may not always reside at offset 0xC0
in the configuration space of the Cadence PCIe controller. Different SoC
integrations can place the capability at a different offset, making the
hardcoded CDNS_PCIE_RP_CAP_OFFSET unreliable.

Replace the fixed offset with a dynamic lookup using
cdns_pcie_find_capability() in all host-related functions that need
to access the PCIe Capability registers. This ensures correct operation
across various SoC designs.

Signed-off-by: Hans Zhang <18255117159@163.com>
---
When I was dealing with Siddharth Vadapalli's review comments on my patch,
I also discovered that there was hardware coding for the capability. So, 
continued to handle it according to the previous submission.
https://lore.kernel.org/all/20250813144529.303548-1-18255117159@163.com/

This patch is based on the submissions of the following series:
https://patchwork.kernel.org/project/linux-pci/cover/20260501153553.66382-1-18255117159@163.com/
---
 .../cadence/pcie-cadence-host-common.c          | 17 ++++++++---------
 .../pci/controller/cadence/pcie-cadence-host.c  |  5 +++--
 .../controller/cadence/pcie-cadence-lga-regs.h  |  1 -
 3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
index d4ae762f423f..b217e3717851 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
@@ -27,14 +27,14 @@ 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;
+	u8 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP);
 
 	/* 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);
+		lnk_stat = cdns_pcie_rp_readw(pcie, cap + PCI_EXP_LNKSTA);
 		if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
 			break;
 		usleep_range(0, 1000);
@@ -77,27 +77,26 @@ 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;
 	u16 lnk_stat, lnk_ctl;
 	int ret = 0;
+	u8 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP);
 
 	/*
 	 * 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 +
+	lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + cap +
 					     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);
+	lnk_stat = cdns_pcie_rp_readw(pcie, cap + 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 = cdns_pcie_rp_readw(pcie, cap + PCI_EXP_LNKCTL);
 		lnk_ctl |= PCI_EXP_LNKCTL_RL;
-		cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
-				    lnk_ctl);
+		cdns_pcie_rp_writew(pcie, cap + PCI_EXP_LNKCTL, lnk_ctl);
 
 		ret = cdns_pcie_host_training_complete(pcie);
 		if (ret)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 0bc9e6e90e0e..2a3fd41c1cf4 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -115,6 +115,7 @@ static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
 	struct cdns_pcie *pcie = &rc->pcie;
 	u32 value, ctrl;
 	u32 id;
+	u8 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP);
 
 	/*
 	 * Set the root complex BAR configuration register:
@@ -147,12 +148,12 @@ static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
 	cdns_pcie_rp_writeb(pcie, PCI_CLASS_PROG, 0);
 	cdns_pcie_rp_writew(pcie, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
 
-	value = cdns_pcie_rp_readl(pcie, CDNS_PCIE_RP_CAP_OFFSET + PCI_EXP_LNKCAP);
+	value = cdns_pcie_rp_readl(pcie, cap + PCI_EXP_LNKCAP);
 	if (rc->quirk_broken_aspm_l0s)
 		value &= ~PCI_EXP_LNKCAP_ASPM_L0S;
 	if (rc->quirk_broken_aspm_l1)
 		value &= ~PCI_EXP_LNKCAP_ASPM_L1;
-	cdns_pcie_rp_writel(pcie, CDNS_PCIE_RP_CAP_OFFSET + PCI_EXP_LNKCAP, value);
+	cdns_pcie_rp_writel(pcie, cap + PCI_EXP_LNKCAP, value);
 
 	return 0;
 }
diff --git a/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h b/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
index 857b2140c5d2..7b92812ed120 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
+++ b/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
@@ -133,7 +133,6 @@
 
 /* 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
-- 
2.34.1


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

end of thread, other threads:[~2026-05-07 15:32 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-03 16:19 [PATCH] PCI: cadence: Use cdns_pcie_find_capability() to get PCIe Cap offset in host driver Hans Zhang
2026-05-03 16:52 ` sashiko-bot
2026-05-04  8:22   ` Hans Zhang
2026-05-05 21:23     ` Bjorn Helgaas
2026-05-06 16:04       ` Hans Zhang
2026-05-06 17:12         ` Bjorn Helgaas
2026-05-07  3:31           ` Hans Zhang
2026-05-07  3:48             ` Hans Zhang
2026-05-07 12:31               ` Aksh Garg
2026-05-07 15:21                 ` Hans Zhang
2026-05-07 15:32                   ` Bjorn Helgaas

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