Subject: Re: [PATCH 2/2] PCI/ASPM: Avoid L0s and L1 on Freescale Root Ports

From: Bjorn Helgaas <[email-masked]>
Date: Fri, 7 Nov 2025 15:55:06 -0600

On Fri, Nov 07, 2025 at 11:39:50AM +0530, Manivannan Sadhasivam wrote:
> On Thu, Nov 06, 2025 at 12:36:39PM -0600, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <[email-masked]>
> > 
> > Christian reported that f3ac2ff14834 ("PCI/ASPM: Enable all ClockPM and
> > ASPM states for devicetree platforms") broke booting on the A-EON X5000.
> > 
> > Fixes: f3ac2ff14834 ("PCI/ASPM: Enable all ClockPM and ASPM states for devicetree platforms")
> > Fixes: df5192d9bb0e ("PCI/ASPM: Enable only L0s and L1 for devicetree platforms"
> > )
> > Reported-by: Christian Zigotzky <[email-masked]>
> > Link: https://lore.kernel.org/r/[email-masked]
> > Signed-off-by: Bjorn Helgaas <[email-masked]>
> > ---
> >  drivers/pci/quirks.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> > index 214ed060ca1b..44e780718953 100644
> > --- a/drivers/pci/quirks.c
> > +++ b/drivers/pci/quirks.c
> > @@ -2525,6 +2525,18 @@ static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
> >   */
> >  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
> >  
> > +/*
> > + * Remove ASPM L0s and L1 support from cached copy of Link Capabilities so
> > + * aspm.c won't try to enable them.
> > + */
> > +static void quirk_disable_aspm_l0s_l1_cap(struct pci_dev *dev)
> > +{
> > +	dev->lnkcap &= ~PCI_EXP_LNKCAP_ASPM_L0S;
> > +	dev->lnkcap &= ~PCI_EXP_LNKCAP_ASPM_L1;
> > +	pci_info(dev, "ASPM: L0s L1 removed from Link Capabilities to work around device defect\n");
> > +}
> > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s_l1_cap);
> 
> From the commit message of the earlier version [1] you shared:
> 
>     Removing advertised features prevents aspm.c from enabling them, even if
>     users try to enable them via sysfs or by building the kernel with
>     CONFIG_PCIEASPM_POWERSAVE or CONFIG_PCIEASPM_POWER_SUPERSAVE.
> 
> Going by this reasoning, shouldn't we be doing this for the other
> quirks (quirk_disable_aspm_l0s_l1/quirk_disable_aspm_l0s) as well?

Yes, probably so.  I was thinking that could be done later to limit
the scope of v6.18 changes, but since we're enabling L0s/L1 when we
didn't before, we should probably update those quirks too.

I was hesitant because quirk_disable_aspm_l0s_l1_cap() isn't quite the
same as quirk_disable_aspm_l0s_l1() because pci_disable_link_state()
turns off states that are currently enabled and also prevents them
from being enabled in the future, but quirk_disable_aspm_l0s_l1_cap()
essentially just clears Link Capability bits.

But if we clear a Link Capability bit for a state that was already
enabled by firmware:

  - If POLICY_DEFAULT or POLICY_PERFORMANCE, I think we'll disable the
    state during enumeration:

      pci_scan_slot
	pcie_aspm_init_link_state
	  pcie_aspm_init_link_state
	    if (POLICY_DEFAULT || POLICY_PERFORMANCE)
	      pcie_config_aspm_path

  - If POLICY_POWERSAVE or POLICY_POWER_SUPERSAVE, I think we'll
    disable it in pci_enable_device():

      pci_enable_device
	do_pci_enable_device
	  pcie_aspm_powersave_config_link
	    if (POLICY_POWERSAVE || POLICY_POWER_SUPERSAVE)
	      pcie_config_aspm_path

If firmware enabled the state, it must at least be safe enough to
boot, and we should eventually disable it regardless of how the kernel
was built.

Bjorn