]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: cadence: Add flags for disabling ASPM capability for broken Root Ports
authorYao Zi <me@ziyao.cc>
Sun, 5 Apr 2026 15:41:53 +0000 (15:41 +0000)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 9 Apr 2026 18:28:03 +0000 (13:28 -0500)
Add flags for disabling the ASPM L0s/L1 capability for broken Root Ports
by clearing the corresponding bits in Link Capabilities Register through
the local management bus. This allows ASPM to be disabled on platforms
which don't support it.

Signed-off-by: Yao Zi <me@ziyao.cc>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Han Gao <gaohan@iscas.ac.cn>
Tested-by: Chen Wang <unicorn_wang@outlook.com> # Pioneerbox
Reviewed-by: Chen Wang <unicorn_wang@outlook.com>
Link: https://patch.msgid.link/20260405154154.46829-2-me@ziyao.cc
drivers/pci/controller/cadence/pcie-cadence-host.c
drivers/pci/controller/cadence/pcie-cadence.h

index db3154c1eccbf80d7dada738d547f08c06f61097..0bc9e6e90e0e0075b933cd5fb442bf73a94d48c6 100644 (file)
@@ -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;
 }
 
index 443033c607d75212812711b76316a3172e03673b..efbda0b3ec2cec29e3fa0a747a1e3e0b0e9d5191 100644 (file)
@@ -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)
 {