Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2

From: Bjorn Helgaas

Date: Fri Oct 23 2026 - 14:20:57 EST


[+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@xxxxxxxxxxx>
> ---
> 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@xxxxxxxxxxx>
>