mirror of https://github.com/torvalds/linux.git
pci-v6.18-fixes-5
-----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEEgMe7l+5h9hnxdsnuWYigwDrT+vwFAmkXokcUHGJoZWxnYWFz QGdvb2dsZS5jb20ACgkQWYigwDrT+vyejw/8CN4kM8PROTw3p6QBJQF6am5uPCA4 nQans+groD/XJXJd7T4aqwuvLXvIrrEd3K+PegBLiGgk3Wgw9fq5pEWDafUH8IAv LG5g462aHyrHPMV8XI6lIrDLD7PCltmpoIu22Xkri4l4gkca7Ros/4Q5gU+AgtCz LtsO9UmcK0PaR95NCdYFf2VZ1PsdZu/ezTb90S1xT5gty9uwpxCmHje5gg07MXXO 12i/SNczU9gFYo8P6XMeD7q0Ixwt7JLC+xa1iBlBEODvcPkyf8Al2dIkxWlnrwGn kxi4K/PKM4f7ZhtyTHh/G8EiFYh/QwbHGvnCBj5XQAKOLWkjZCn8l5MxqGAKKvnz Dem3/MFwJQ79+y/vrseg5beBiLPahd5fsAITOFIxmQZsEjvL+B8fhU52QBkLVFUw iJg7PJXHJ9Jy/NRGT/rinu9mi2K+z1baZHZm11QK5khTTbYAs+qsvwWck9Jcr004 OEsQGngomUv09WjHv0/26dJzVI5wpnn+C+DFAximlIMZnTaQguN/WNplYYyXBRzB T09qK1ZzpJM6QEU5i2ZForGpFtKSbGHwJrC6DYjLiVV3P4EzpHWSmTy2dqM7GUNa Wrvaxy3j/MT2kudfyIs10Qwu1EJ+rHYb/QfS3pqlggSDic9WFg9P4uUlFR1YUKPb h+Peip6NV/tQNHI= =2eqF -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7a0892d283
|
|
@ -958,6 +958,7 @@ void pci_save_aspm_l1ss_state(struct pci_dev *dev);
|
||||||
void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
|
void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
|
||||||
|
|
||||||
#ifdef CONFIG_PCIEASPM
|
#ifdef CONFIG_PCIEASPM
|
||||||
|
void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap);
|
||||||
void pcie_aspm_init_link_state(struct pci_dev *pdev);
|
void pcie_aspm_init_link_state(struct pci_dev *pdev);
|
||||||
void pcie_aspm_exit_link_state(struct pci_dev *pdev);
|
void pcie_aspm_exit_link_state(struct pci_dev *pdev);
|
||||||
void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked);
|
void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked);
|
||||||
|
|
@ -965,6 +966,7 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
|
||||||
void pci_configure_ltr(struct pci_dev *pdev);
|
void pci_configure_ltr(struct pci_dev *pdev);
|
||||||
void pci_bridge_reconfigure_ltr(struct pci_dev *pdev);
|
void pci_bridge_reconfigure_ltr(struct pci_dev *pdev);
|
||||||
#else
|
#else
|
||||||
|
static inline void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap) { }
|
||||||
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
|
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
|
||||||
static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
|
static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
|
||||||
static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked) { }
|
static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked) { }
|
||||||
|
|
|
||||||
|
|
@ -814,7 +814,6 @@ static void pcie_aspm_override_default_link_state(struct pcie_link_state *link)
|
||||||
static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
|
static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
|
||||||
{
|
{
|
||||||
struct pci_dev *child = link->downstream, *parent = link->pdev;
|
struct pci_dev *child = link->downstream, *parent = link->pdev;
|
||||||
u32 parent_lnkcap, child_lnkcap;
|
|
||||||
u16 parent_lnkctl, child_lnkctl;
|
u16 parent_lnkctl, child_lnkctl;
|
||||||
struct pci_bus *linkbus = parent->subordinate;
|
struct pci_bus *linkbus = parent->subordinate;
|
||||||
|
|
||||||
|
|
@ -829,9 +828,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
|
||||||
* If ASPM not supported, don't mess with the clocks and link,
|
* If ASPM not supported, don't mess with the clocks and link,
|
||||||
* bail out now.
|
* bail out now.
|
||||||
*/
|
*/
|
||||||
pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
|
if (!(parent->aspm_l0s_support && child->aspm_l0s_support) &&
|
||||||
pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
|
!(parent->aspm_l1_support && child->aspm_l1_support))
|
||||||
if (!(parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPMS))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Configure common clock before checking latencies */
|
/* Configure common clock before checking latencies */
|
||||||
|
|
@ -843,8 +841,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
|
||||||
* read-only Link Capabilities may change depending on common clock
|
* read-only Link Capabilities may change depending on common clock
|
||||||
* configuration (PCIe r5.0, sec 7.5.3.6).
|
* configuration (PCIe r5.0, sec 7.5.3.6).
|
||||||
*/
|
*/
|
||||||
pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
|
|
||||||
pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
|
|
||||||
pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
|
pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
|
||||||
pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
|
pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
|
||||||
|
|
||||||
|
|
@ -864,7 +860,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
|
||||||
* given link unless components on both sides of the link each
|
* given link unless components on both sides of the link each
|
||||||
* support L0s.
|
* support L0s.
|
||||||
*/
|
*/
|
||||||
if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
|
if (parent->aspm_l0s_support && child->aspm_l0s_support)
|
||||||
link->aspm_support |= PCIE_LINK_STATE_L0S;
|
link->aspm_support |= PCIE_LINK_STATE_L0S;
|
||||||
|
|
||||||
if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
|
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)
|
||||||
link->aspm_enabled |= PCIE_LINK_STATE_L0S_DW;
|
link->aspm_enabled |= PCIE_LINK_STATE_L0S_DW;
|
||||||
|
|
||||||
/* Setup L1 state */
|
/* Setup L1 state */
|
||||||
if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
|
if (parent->aspm_l1_support && child->aspm_l1_support)
|
||||||
link->aspm_support |= PCIE_LINK_STATE_L1;
|
link->aspm_support |= PCIE_LINK_STATE_L1;
|
||||||
|
|
||||||
if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
|
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)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_enable_link_state_locked);
|
EXPORT_SYMBOL(pci_enable_link_state_locked);
|
||||||
|
|
||||||
|
void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap)
|
||||||
|
{
|
||||||
|
if (lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
|
||||||
|
pdev->aspm_l0s_support = 0;
|
||||||
|
if (lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
|
||||||
|
pdev->aspm_l1_support = 0;
|
||||||
|
|
||||||
|
pci_info(pdev, "ASPM: Link Capabilities%s%s treated as unsupported to avoid device defect\n",
|
||||||
|
lnkcap & PCI_EXP_LNKCAP_ASPM_L0S ? " L0s" : "",
|
||||||
|
lnkcap & PCI_EXP_LNKCAP_ASPM_L1 ? " L1" : "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int pcie_aspm_set_policy(const char *val,
|
static int pcie_aspm_set_policy(const char *val,
|
||||||
const struct kernel_param *kp)
|
const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1656,6 +1656,13 @@ void set_pcie_port_type(struct pci_dev *pdev)
|
||||||
if (reg32 & PCI_EXP_LNKCAP_DLLLARC)
|
if (reg32 & PCI_EXP_LNKCAP_DLLLARC)
|
||||||
pdev->link_active_reporting = 1;
|
pdev->link_active_reporting = 1;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCIEASPM
|
||||||
|
if (reg32 & PCI_EXP_LNKCAP_ASPM_L0S)
|
||||||
|
pdev->aspm_l0s_support = 1;
|
||||||
|
if (reg32 & PCI_EXP_LNKCAP_ASPM_L1)
|
||||||
|
pdev->aspm_l1_support = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
parent = pci_upstream_bridge(pdev);
|
parent = pci_upstream_bridge(pdev);
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -2494,28 +2494,27 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
|
||||||
*/
|
*/
|
||||||
static void quirk_disable_aspm_l0s(struct pci_dev *dev)
|
static void quirk_disable_aspm_l0s(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
pci_info(dev, "Disabling L0s\n");
|
pcie_aspm_remove_cap(dev, PCI_EXP_LNKCAP_ASPM_L0S);
|
||||||
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
|
|
||||||
}
|
}
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
|
||||||
|
|
||||||
static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
|
static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
pci_info(dev, "Disabling ASPM L0s/L1\n");
|
pcie_aspm_remove_cap(dev,
|
||||||
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
|
PCI_EXP_LNKCAP_ASPM_L0S | PCI_EXP_LNKCAP_ASPM_L1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2523,7 +2522,10 @@ static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
|
||||||
* upstream PCIe root port when ASPM is enabled. At least L0s mode is affected;
|
* upstream PCIe root port when ASPM is enabled. At least L0s mode is affected;
|
||||||
* disable both L0s and L1 for now to be safe.
|
* disable both L0s and L1 for now to be safe.
|
||||||
*/
|
*/
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
|
||||||
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s_l1);
|
||||||
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PASEMI, 0xa002, quirk_disable_aspm_l0s_l1);
|
||||||
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain
|
* Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain
|
||||||
|
|
|
||||||
|
|
@ -412,6 +412,8 @@ struct pci_dev {
|
||||||
u16 l1ss; /* L1SS Capability pointer */
|
u16 l1ss; /* L1SS Capability pointer */
|
||||||
#ifdef CONFIG_PCIEASPM
|
#ifdef CONFIG_PCIEASPM
|
||||||
struct pcie_link_state *link_state; /* ASPM link state */
|
struct pcie_link_state *link_state; /* ASPM link state */
|
||||||
|
unsigned int aspm_l0s_support:1; /* ASPM L0s support */
|
||||||
|
unsigned int aspm_l1_support:1; /* ASPM L1 support */
|
||||||
unsigned int ltr_path:1; /* Latency Tolerance Reporting
|
unsigned int ltr_path:1; /* Latency Tolerance Reporting
|
||||||
supported from root to here */
|
supported from root to here */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue