* [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2
@ 2026-10-23 17:39 Anthony Ruhier via B4 Relay
2026-10-23 18:20 ` Bjorn Helgaas
0 siblings, 1 reply; 3+ messages in thread
From: Anthony Ruhier via B4 Relay @ 2026-10-23 17:39 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, linux-kernel, Anthony Ruhier
From: Anthony Ruhier <aruhier@mailbox.org>
The WCN7850 Wifi/BT card, found in several Snapdragon X laptops, never
enters ASPM L1.2 when LTR is enabled. Its firmware reads the
LTR_L1.2_THRESHOLD set at enumeration and reports an LTR value just
below it, so the L1.2 entry condition is never met and the link stays in
L1.1.
Windows does not set LTR Mechanism Enable for this device (verified by
dumping the ACPI tables), and the link idles in L1.2 normally.
Replicate the same behavior: clear PCI_EXP_DEVCTL2_LTR_EN for WCN7850 at
enumeration and again on resume, as the LTR state is restored there.
On a Lenovo Yoga Slim 7x (X1E80100) this allows the link to reach L1.2
and reduces idle power by about 70 mW.
Signed-off-by: Anthony Ruhier <aruhier@mailbox.org>
---
drivers/pci/quirks.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 1aa87a3ef9ed..374c505981a0 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3795,6 +3795,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x1103, quirk_no_bus_reset); /* WCN
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x1107, quirk_no_bus_reset); /* WCN7850 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x0308, quirk_no_bus_reset); /* SDX62/SDX65 */
+/*
+ * The WCN7850 firmware reports an LTR just below the LTR_L1.2_THRESHOLD it
+ * sees at boot, preventing it to ever enter L1.2.
+ * With LTR disabled the link idles in L1.2, similar to what Windows does.
+ */
+static void quirk_wcn7850_disable_ltr(struct pci_dev *pdev)
+{
+ pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_LTR_EN);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QCOM, 0x1107, quirk_wcn7850_disable_ltr);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_QCOM, 0x1107,
+ quirk_wcn7850_disable_ltr);
+
/*
* Root port on some Cavium CN8xxx chips do not successfully complete a bus
* reset when used with certain child devices. After the reset, config
---
base-commit: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
change-id: 20261023-quick-wcn7850-a792968cc25f
Best regards,
--
Anthony Ruhier <aruhier@mailbox.org>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2
2026-10-23 17:39 [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2 Anthony Ruhier via B4 Relay
@ 2026-10-23 18:20 ` Bjorn Helgaas
2026-10-23 21:49 ` Anthony Ruhier
0 siblings, 1 reply; 3+ messages in thread
From: Bjorn Helgaas @ 2026-10-23 18:20 UTC (permalink / raw)
To: Anthony Ruhier
Cc: Bjorn Helgaas, linux-pci, linux-kernel, Baochen Qiang,
Vasanthakumar Thiagarajan, Jeff Johnson, Manivannan Sadhasivam
[+cc Qualcomm folks]
On Fri, Oct 23, 2026 at 07:39:35PM +0200, Anthony Ruhier wrote:
> The WCN7850 Wifi/BT card, found in several Snapdragon X laptops, never
> enters ASPM L1.2 when LTR is enabled. Its firmware reads the
> LTR_L1.2_THRESHOLD set at enumeration and reports an LTR value just
> below it, so the L1.2 entry condition is never met and the link stays in
> L1.1.
Here are the ASPM L1.2 entry conditions in PCIe r7.0, sec 5.5.1:
The following rules define how the L1.1 and L1.2 substates are entered:
- Both the Upstream and Downstream Ports must monitor the logical
state of the CLKREQ# signal.
...
- When in ASPM L1.0 and the ASPM L1.2 Enable bit is Set, the L1.2
substate must be entered when CLKREQ# is deasserted and all of
the following conditions are true:
- The reported snooped LTR value last sent or received by this
Port is greater than or equal to the value set by the
LTR_L1.2_THRESHOLD Value and Scale fields, or there is no
snoop service latency requirement.
- The reported non-snooped LTR last sent or received by this
Port value is greater than or equal to the value set by the
LTR_L1.2_THRESHOLD Value and Scale fields, or there is no
non-snoop service latency requirement.
By "firmware reports LTR value", do you mean that the WCN7850 sends an
LTR Message with snooped/non-snooped values just below
LTR_L1.2_THRESHOLD?
And since the reported LTR values are never greater than or equal to
LTR_L1.2_THRESHOLD, the link never enters L1.2?
If so that sounds like a clue that the firmware went to some lengths
to prevent L1.2 from being used, which is "interesting."
> Windows does not set LTR Mechanism Enable for this device (verified by
> dumping the ACPI tables), and the link idles in L1.2 normally.
I don't know that ASL not enabling LTR is definitive (lspci would be
more direct). But it sounds like you've verified that the link is
actually in L1.2 when idle.
> Replicate the same behavior: clear PCI_EXP_DEVCTL2_LTR_EN for WCN7850 at
> enumeration and again on resume, as the LTR state is restored there.
>
> On a Lenovo Yoga Slim 7x (X1E80100) this allows the link to reach L1.2
> and reduces idle power by about 70 mW.
>
> Signed-off-by: Anthony Ruhier <aruhier@mailbox.org>
> ---
> drivers/pci/quirks.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 1aa87a3ef9ed..374c505981a0 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3795,6 +3795,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x1103, quirk_no_bus_reset); /* WCN
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x1107, quirk_no_bus_reset); /* WCN7850 */
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x0308, quirk_no_bus_reset); /* SDX62/SDX65 */
>
> +/*
> + * The WCN7850 firmware reports an LTR just below the LTR_L1.2_THRESHOLD it
> + * sees at boot, preventing it to ever enter L1.2.
> + * With LTR disabled the link idles in L1.2, similar to what Windows does.
> + */
> +static void quirk_wcn7850_disable_ltr(struct pci_dev *pdev)
> +{
> + pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL2,
> + PCI_EXP_DEVCTL2_LTR_EN);
I don't think we can guarantee that the PCI core ASPM support will
leave LTR disabled. I don't see anything there that looks like "leave
PCI_EXP_DEVCTL2_LTR_EN unchanged."
> +}
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QCOM, 0x1107, quirk_wcn7850_disable_ltr);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_QCOM, 0x1107,
> + quirk_wcn7850_disable_ltr);
> +
> /*
> * Root port on some Cavium CN8xxx chips do not successfully complete a bus
> * reset when used with certain child devices. After the reset, config
>
> ---
> base-commit: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
> change-id: 20261023-quick-wcn7850-a792968cc25f
>
> Best regards,
> --
> Anthony Ruhier <aruhier@mailbox.org>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2
2026-10-23 18:20 ` Bjorn Helgaas
@ 2026-10-23 21:49 ` Anthony Ruhier
0 siblings, 0 replies; 3+ messages in thread
From: Anthony Ruhier @ 2026-10-23 21:49 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, linux-pci, linux-kernel, Baochen Qiang,
Vasanthakumar Thiagarajan, Jeff Johnson, Manivannan Sadhasivam
On Fri, Oct 23, 2026 at 01:20:04PM -0500, Bjorn Helgaas wrote:
> By "firmware reports LTR value", do you mean that the WCN7850 sends an
> LTR Message with snooped/non-snooped values just below
> LTR_L1.2_THRESHOLD?
>
> And since the reported LTR values are never greater than or equal to
> LTR_L1.2_THRESHOLD, the link never enters L1.2?
Not exactly. The firmware doesn't report a max snoop/no snoop that I could see
in lspci (it's set at 0ns), but if I set one with setpci, the card still
doesn't reach L1.2.
However, if I lower after boot the t-power-on-us of the pcie port by 10µs, the
card goes to L1.2.
I suspect that the firmware dynamically sets an internal threshold from the
reported LTR_L1.2_THRESHOLD because lowering the t-power-on-us in the
devicetree by 10µs doesn't mitigate the problem. Doing this seems to shift the
internal threshold to 10µs lower, because lowering the t-power-on-us by anoter
10µs is still needed.
> If so that sounds like a clue that the firmware went to some lengths
> to prevent L1.2 from being used, which is "interesting."
By disassembling the firmware with an LLM, I discovered that when wake-on-lan
is active, it stops this behavior so that the card can go to L1.2. But I
couldn't find anything else of why it would do this.
So I don't know why the firmware tries to prevent L1.2 when LTR is set,
considering that Windows runs the card fine with L1.2, and this is a Windows on
ARM laptop. I haven't seen any degradation of performance or packet loss in
Linux with L1.2 enabled.
> I don't think we can guarantee that the PCI core ASPM support will
> leave LTR disabled. I don't see anything there that looks like "leave
> PCI_EXP_DEVCTL2_LTR_EN unchanged."
I don't understand this, can you clarify what you mean and what you would like
me to change?
Thanks,
--
Anthony Ruhier
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-23 21:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-23 17:39 [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2 Anthony Ruhier via B4 Relay
2026-10-23 18:20 ` Bjorn Helgaas
2026-10-23 21:49 ` Anthony Ruhier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®