[PATCH v3 1/2] PCI: cadence: Add flags for disabling ASPM support advertisement

From: Yao Zi

Date: Sun Apr 05 2026 - 11:43:06 EST


Add flags for disabling advertisement of ASPM L0s/L1 states by clearing
corresponding bits in Link Capabilities Register through the local
management bus, allowing ASPM to be disabled on platforms which don't
support it.

Signed-off-by: Yao Zi <me@xxxxxxxx>
Tested-by: Han Gao <gaohan@xxxxxxxxxxx>
---
.../controller/cadence/pcie-cadence-host.c | 7 +++++++
drivers/pci/controller/cadence/pcie-cadence.h | 19 +++++++++++++++++++
2 files changed, 26 insertions(+)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index db3154c1eccb..0bc9e6e90e0e 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -147,6 +147,13 @@ 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);
+ 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);
+
return 0;
}

diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 443033c607d7..32a5666204f5 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -115,6 +115,8 @@ struct cdns_pcie {
* @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
* @ecam_supported: Whether the ECAM is supported
* @no_inbound_map: Whether inbound mapping is supported
+ * @quirk_broken_aspm_l0s: Disable ASPM L0s support as quirk.
+ * @quirk_broken_aspm_l1: Disable ASPM L1 support as quirk.
*/
struct cdns_pcie_rc {
struct cdns_pcie pcie;
@@ -127,6 +129,8 @@ struct cdns_pcie_rc {
unsigned int quirk_detect_quiet_flag:1;
unsigned int ecam_supported:1;
unsigned int no_inbound_map:1;
+ unsigned int quirk_broken_aspm_l0s:1;
+ unsigned int quirk_broken_aspm_l1:1;
};

/**
@@ -344,6 +348,21 @@ 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_rp_writel(struct cdns_pcie *pcie,
+ u32 reg, u32 value)
+{
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
+
+ cdns_pcie_write_sz(addr, 0x4, value);
+}
+
+static inline u32 cdns_pcie_rp_readl(struct cdns_pcie *pcie, u32 reg)
+{
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
+
+ return cdns_pcie_read_sz(addr, 0x4);
+}
+
static inline void cdns_pcie_hpa_rp_writeb(struct cdns_pcie *pcie,
u32 reg, u8 value)
{
--
2.53.0