mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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; 6+ 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] 6+ 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; 6+ 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] 6+ 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
  2026-10-25 21:16     ` Anthony Ruhier
  2026-10-26  7:25     ` Manivannan Sadhasivam
  0 siblings, 2 replies; 6+ 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] 6+ messages in thread

* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2
  2026-10-23 21:49   ` Anthony Ruhier
@ 2026-10-25 21:16     ` Anthony Ruhier
  2026-10-26  7:25     ` Manivannan Sadhasivam
  1 sibling, 0 replies; 6+ messages in thread
From: Anthony Ruhier @ 2026-10-25 21:16 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Bjorn Helgaas, linux-pci, linux-kernel, Baochen Qiang,
	Val Packett, Vasanthakumar Thiagarajan, Jeff Johnson,
	Manivannan Sadhasivam

On Fri, Oct 23, 2026 at 11:49:25PM +0200, Anthony Ruhier wrote:
> 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.

Val Packett suggested that I tried to test that in practice to check if that's
true. So I tested enabling WoL and putting the laptop in suspend, but I
couldn't reproduce what the LLM described. So either it's a hallucination or I
couldn't find the right conditions.

So you can ignore this statement.

Thanks,
--
Anthony Ruhier

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2
  2026-10-23 21:49   ` Anthony Ruhier
  2026-10-25 21:16     ` Anthony Ruhier
@ 2026-10-26  7:25     ` Manivannan Sadhasivam
  2026-10-26  7:53       ` Manivannan Sadhasivam
  1 sibling, 1 reply; 6+ messages in thread
From: Manivannan Sadhasivam @ 2026-10-26  7:25 UTC (permalink / raw)
  To: Anthony Ruhier
  Cc: Bjorn Helgaas, Bjorn Helgaas, linux-pci, linux-kernel,
	Baochen Qiang, Vasanthakumar Thiagarajan, Jeff Johnson

On Fri, Oct 23, 2026 at 11:49:22PM +0200, Anthony Ruhier wrote:
> 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?
> 

This is correct.

> 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.

Max Snoop/No-Snoop latencies are supposed to be set by the host software, not
the Endpoint firmware. The Endpoint firmware only uses these values to send
their Snoop/No-Snoop latencies in the LTR message.

But there are two issues here in Qcom platforms:

1. Neither the BIOS, nor the PCI core/pcie-qcom driver set the Max
Snoop/No-Snoop latencies for the Endpoints/Upstream Ports based on the platform
requirement.

2. The L1_2_Threshold calculated by the PCI core doesn't match the Qcom platforms:

l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;

On the Qcom platforms, T_POWER_ON is 0 by default. I initially misunderstood
that the T_POWER_ON value of '0' was wrong. But after checking more, I
understood that '0' was indeed the correct value, but there is one more
parameter that we are not taking into account, which is TL10_REFCLK_ON time. It
is ~40-80us depending on the platform.

Unfortunately, PCIe base spec didn't define any registers to pass the
TL10_REFCLK_ON time to the OS. I'm planning to introduce a DT property, set
it in Root Port node and take it account in the l1_2_threshold calculation.

Because of the issue (1), the Endpoint firmware reports 0 Snoop/No-Snoop
latencies as the LTR latencies cannot exceed Max Snoop/No-Snoop latencies set
by the host software. This is the behavior across all Endpoints connected to
the Qcom host machines.

So if the LTR requirement bit is set, and the Endpoint sends 0 latencies in LTR
message, then L1.2 is not entered all the time because, LTR > L1_2_Threshold.
The spec mandates that the link should enter L1.2 only if LTR <= L1_2_Threshold.

The reason why L1.2 is entered in Windows with same Endpoint is, Windows sets
L1_2_Threshold to 0. So LTR <= L1_2_Threshold condition gets satisfied.

But this is not the optimal approach. Ideally, the platform latency requirement
should properly be exposed through the Max Snoop/No-Snoop registers and let the
Endpoint specify its own latency requirement through the LTR message. I'm also
working on getting these values so that we can express these through DT. But we
cannot just program the DT read values directly as we need to account for
cumulative latencies along the path to the Root Port as per the PCI Firmware
Spec, v3.3, sec 4.6.6. Once I get the platform latencies, I will work on
programming it in the PCI core.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2
  2026-10-26  7:25     ` Manivannan Sadhasivam
@ 2026-10-26  7:53       ` Manivannan Sadhasivam
  0 siblings, 0 replies; 6+ messages in thread
From: Manivannan Sadhasivam @ 2026-10-26  7:53 UTC (permalink / raw)
  To: Anthony Ruhier
  Cc: Bjorn Helgaas, Bjorn Helgaas, linux-pci, linux-kernel,
	Baochen Qiang, Vasanthakumar Thiagarajan, Jeff Johnson

On Mon, Oct 26, 2026 at 12:55:25PM +0530, Manivannan Sadhasivam wrote:
> On Fri, Oct 23, 2026 at 11:49:22PM +0200, Anthony Ruhier wrote:
> > 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?
> > 
> 
> This is correct.
> 
> > 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.
> 
> Max Snoop/No-Snoop latencies are supposed to be set by the host software, not
> the Endpoint firmware. The Endpoint firmware only uses these values to send
> their Snoop/No-Snoop latencies in the LTR message.
> 
> But there are two issues here in Qcom platforms:
> 
> 1. Neither the BIOS, nor the PCI core/pcie-qcom driver set the Max
> Snoop/No-Snoop latencies for the Endpoints/Upstream Ports based on the platform
> requirement.
> 
> 2. The L1_2_Threshold calculated by the PCI core doesn't match the Qcom platforms:
> 
> l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;
> 
> On the Qcom platforms, T_POWER_ON is 0 by default. I initially misunderstood
> that the T_POWER_ON value of '0' was wrong. But after checking more, I
> understood that '0' was indeed the correct value, but there is one more
> parameter that we are not taking into account, which is TL10_REFCLK_ON time. It
> is ~40-80us depending on the platform.
> 
> Unfortunately, PCIe base spec didn't define any registers to pass the
> TL10_REFCLK_ON time to the OS. I'm planning to introduce a DT property, set
> it in Root Port node and take it account in the l1_2_threshold calculation.
> 
> Because of the issue (1), the Endpoint firmware reports 0 Snoop/No-Snoop
> latencies as the LTR latencies cannot exceed Max Snoop/No-Snoop latencies set
> by the host software. This is the behavior across all Endpoints connected to
> the Qcom host machines.
> 
> So if the LTR requirement bit is set, and the Endpoint sends 0 latencies in LTR
> message, then L1.2 is not entered all the time because, LTR > L1_2_Threshold.
> The spec mandates that the link should enter L1.2 only if LTR <= L1_2_Threshold.

Typo here. I got the condition inverted. Currently, LTR < L1_2_Threshold and
spec mandates LTR >= L1_2_Threshold for entering L1.2.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-10-26  7:53 UTC | newest]

Thread overview: 6+ 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
2026-10-25 21:16     ` Anthony Ruhier
2026-10-26  7:25     ` Manivannan Sadhasivam
2026-10-26  7:53       ` Manivannan Sadhasivam

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®