Skip to content

Commit 7a0892d

Browse files
committed
Merge tag 'pci-v6.18-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci fixes from Bjorn Helgaas: - Cache the ASPM L0s/L1 Supported bits early so quirks can override them if necessary (Bjorn Helgaas) - Add quirks for PA Semi and Freescale Root Ports and a HiSilicon Wi-Fi device that are reported to have broken L0s and L1 (Shawn Lin, Bjorn Helgaas) * tag 'pci-v6.18-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: PCI/ASPM: Avoid L0s and L1 on Hi1105 [19e5:1105] Wi-Fi PCI/ASPM: Avoid L0s and L1 on PA Semi [1959:a002] Root Ports PCI/ASPM: Avoid L0s and L1 on Freescale [1957:0451] Root Ports PCI/ASPM: Convert quirks to override advertised link states PCI/ASPM: Add pcie_aspm_remove_cap() to override advertised link states PCI/ASPM: Cache L0s/L1 Supported so advertised link states can be overridden
2 parents cbba5d1 + 921b3f5 commit 7a0892d

File tree

5 files changed

+50
-28
lines changed

5 files changed

+50
-28
lines changed

drivers/pci/pci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,13 +958,15 @@ void pci_save_aspm_l1ss_state(struct pci_dev *dev);
958958
void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
959959

960960
#ifdef CONFIG_PCIEASPM
961+
void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap);
961962
void pcie_aspm_init_link_state(struct pci_dev *pdev);
962963
void pcie_aspm_exit_link_state(struct pci_dev *pdev);
963964
void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked);
964965
void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
965966
void pci_configure_ltr(struct pci_dev *pdev);
966967
void pci_bridge_reconfigure_ltr(struct pci_dev *pdev);
967968
#else
969+
static inline void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap) { }
968970
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
969971
static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
970972
static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked) { }

drivers/pci/pcie/aspm.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,6 @@ static void pcie_aspm_override_default_link_state(struct pcie_link_state *link)
814814
static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
815815
{
816816
struct pci_dev *child = link->downstream, *parent = link->pdev;
817-
u32 parent_lnkcap, child_lnkcap;
818817
u16 parent_lnkctl, child_lnkctl;
819818
struct pci_bus *linkbus = parent->subordinate;
820819

@@ -829,9 +828,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
829828
* If ASPM not supported, don't mess with the clocks and link,
830829
* bail out now.
831830
*/
832-
pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
833-
pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
834-
if (!(parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPMS))
831+
if (!(parent->aspm_l0s_support && child->aspm_l0s_support) &&
832+
!(parent->aspm_l1_support && child->aspm_l1_support))
835833
return;
836834

837835
/* Configure common clock before checking latencies */
@@ -843,8 +841,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
843841
* read-only Link Capabilities may change depending on common clock
844842
* configuration (PCIe r5.0, sec 7.5.3.6).
845843
*/
846-
pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
847-
pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
848844
pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
849845
pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
850846

@@ -864,7 +860,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
864860
* given link unless components on both sides of the link each
865861
* support L0s.
866862
*/
867-
if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
863+
if (parent->aspm_l0s_support && child->aspm_l0s_support)
868864
link->aspm_support |= PCIE_LINK_STATE_L0S;
869865

870866
if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
@@ -873,7 +869,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
873869
link->aspm_enabled |= PCIE_LINK_STATE_L0S_DW;
874870

875871
/* Setup L1 state */
876-
if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
872+
if (parent->aspm_l1_support && child->aspm_l1_support)
877873
link->aspm_support |= PCIE_LINK_STATE_L1;
878874

879875
if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
@@ -1530,6 +1526,19 @@ int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
15301526
}
15311527
EXPORT_SYMBOL(pci_enable_link_state_locked);
15321528

1529+
void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap)
1530+
{
1531+
if (lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
1532+
pdev->aspm_l0s_support = 0;
1533+
if (lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
1534+
pdev->aspm_l1_support = 0;
1535+
1536+
pci_info(pdev, "ASPM: Link Capabilities%s%s treated as unsupported to avoid device defect\n",
1537+
lnkcap & PCI_EXP_LNKCAP_ASPM_L0S ? " L0s" : "",
1538+
lnkcap & PCI_EXP_LNKCAP_ASPM_L1 ? " L1" : "");
1539+
1540+
}
1541+
15331542
static int pcie_aspm_set_policy(const char *val,
15341543
const struct kernel_param *kp)
15351544
{

drivers/pci/probe.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,13 @@ void set_pcie_port_type(struct pci_dev *pdev)
16561656
if (reg32 & PCI_EXP_LNKCAP_DLLLARC)
16571657
pdev->link_active_reporting = 1;
16581658

1659+
#ifdef CONFIG_PCIEASPM
1660+
if (reg32 & PCI_EXP_LNKCAP_ASPM_L0S)
1661+
pdev->aspm_l0s_support = 1;
1662+
if (reg32 & PCI_EXP_LNKCAP_ASPM_L1)
1663+
pdev->aspm_l1_support = 1;
1664+
#endif
1665+
16591666
parent = pci_upstream_bridge(pdev);
16601667
if (!parent)
16611668
return;

drivers/pci/quirks.c

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,36 +2494,38 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
24942494
*/
24952495
static void quirk_disable_aspm_l0s(struct pci_dev *dev)
24962496
{
2497-
pci_info(dev, "Disabling L0s\n");
2498-
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
2499-
}
2500-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
2501-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s);
2502-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s);
2503-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s);
2504-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s);
2505-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s);
2506-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s);
2507-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s);
2508-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s);
2509-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s);
2510-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s);
2511-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
2512-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
2513-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
2497+
pcie_aspm_remove_cap(dev, PCI_EXP_LNKCAP_ASPM_L0S);
2498+
}
2499+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
2500+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s);
2501+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s);
2502+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s);
2503+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s);
2504+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s);
2505+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s);
2506+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s);
2507+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s);
2508+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s);
2509+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s);
2510+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
2511+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
2512+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
25142513

25152514
static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
25162515
{
2517-
pci_info(dev, "Disabling ASPM L0s/L1\n");
2518-
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
2516+
pcie_aspm_remove_cap(dev,
2517+
PCI_EXP_LNKCAP_ASPM_L0S | PCI_EXP_LNKCAP_ASPM_L1);
25192518
}
25202519

25212520
/*
25222521
* ASM1083/1085 PCIe-PCI bridge devices cause AER timeout errors on the
25232522
* upstream PCIe root port when ASPM is enabled. At least L0s mode is affected;
25242523
* disable both L0s and L1 for now to be safe.
25252524
*/
2526-
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
2525+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
2526+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s_l1);
2527+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PASEMI, 0xa002, quirk_disable_aspm_l0s_l1);
2528+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1);
25272529

25282530
/*
25292531
* Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain

include/linux/pci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,8 @@ struct pci_dev {
412412
u16 l1ss; /* L1SS Capability pointer */
413413
#ifdef CONFIG_PCIEASPM
414414
struct pcie_link_state *link_state; /* ASPM link state */
415+
unsigned int aspm_l0s_support:1; /* ASPM L0s support */
416+
unsigned int aspm_l1_support:1; /* ASPM L1 support */
415417
unsigned int ltr_path:1; /* Latency Tolerance Reporting
416418
supported from root to here */
417419
#endif

0 commit comments

Comments
 (0)