diff options
| -rw-r--r-- | drivers/pci/controller/cadence/pcie-cadence-host.c | 7 | ||||
| -rw-r--r-- | drivers/pci/controller/cadence/pcie-cadence.h | 19 |
2 files changed, 26 insertions, 0 deletions
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..efbda0b3ec2c 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) { |
