* [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2 @ 2026-10-23 17:39 ` Anthony Ruhier 0 siblings, 0 replies; 8+ 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 related [flat|nested] 8+ messages in thread
* [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2 @ 2026-10-23 17:39 ` Anthony Ruhier 0 siblings, 0 replies; 8+ messages in thread From: Anthony Ruhier @ 2026-10-23 17:39 UTC (permalink / raw) To: Bjorn Helgaas; +Cc: linux-pci, linux-kernel, Anthony Ruhier 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 related [flat|nested] 8+ messages in thread
* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2 2026-10-23 17:39 ` Anthony Ruhier (?) @ 2026-10-23 17:55 ` sashiko-bot -1 siblings, 0 replies; 8+ messages in thread From: sashiko-bot @ 2026-10-23 17:55 UTC (permalink / raw) To: Anthony Ruhier; +Cc: linux-pci > 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> Sashiko has reviewed this patch and found no issues. -- Sashiko AI review · https://sashiko.dev/#/patchset/20261023-quick-wcn7850-v1-1-9a139b9b2c8e@mailbox.org?part=1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] PCI: Disable LTR on Qualcomm WCN7850 [17cb:1107] to allow ASPM L1.2 2026-10-23 17:39 ` Anthony Ruhier (?) (?) @ 2026-10-23 18:20 ` Bjorn Helgaas 2026-10-23 21:49 ` Anthony Ruhier -1 siblings, 1 reply; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ messages in thread
end of thread, other threads:[~2026-10-26 7:53 UTC | newest] Thread overview: 8+ 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 17:39 ` Anthony Ruhier 2026-10-23 17:55 ` sashiko-bot 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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.