Re: [PATCH v6 3/3] PCI/ASPM: Mask ASPM states based on Devicetree properties

From: Manivannan Sadhasivam

Date: Thu Jul 30 2026 - 01:06:44 EST


On Mon, Jul 27, 2026 at 07:32:38PM +0530, Krishna Chaitanya Chundru wrote:
> Some platforms require selectively disabling specific ASPM states on a
> given PCIe link to avoid link instability or functional failures caused
> by board-level connectivity constraints such as PCB routing, connectors,
> slots, or external cabling.
>
> Devicetree supports disabling ASPM L0s, L1, and L1 PM Substates via the
> 'aspm-no-l0s', 'aspm-no-l1' [1], and 'aspm-no-l1ss' [2] properties.
> However, the ASPM driver does not currently honor these properties when
> initializing the default link state.
>
> When firmware enables L1 PM Substates before the kernel takes over,
> masking aspm_support alone is insufficient to disable them in hardware.
> pcie_config_aspm_link() guards L1SS configuration behind a check on
> aspm_capable, which is derived from aspm_support. Once aspm_support is
> masked, pcie_config_aspm_l1ss() is never called, leaving
> firmware-enabled L1SS substates active in hardware.
>
> Fix this by introducing pcie_link_has_aspm_override() to check for DT
> override properties on either endpoint of the link. In
> pcie_aspm_override_default_link_state(), use it to:
>
> - Mask aspm_support, aspm_default, and aspm_enabled for any disabled
> state, so software's view of the link stays in sync with what is
> actually programmed in hardware. Leaving aspm_enabled stale would
> make pcie_aspm_enabled() and the aspm sysfs attributes report a
> state as active even after it has been masked, and could cause
> pcie_config_aspm_link()'s "already in requested state" check to
> skip reprogramming hardware to match.
> - Explicitly call pcie_config_aspm_l1ss(link, 0) before masking
> aspm_support when firmware has L1SS active and DT requests disabling
> L1 or L1SS, since pcie_config_aspm_link() will no longer do so once
> aspm_capable is derived from the masked aspm_support.
>
> Move the aspm_default initialization and
> pcie_aspm_override_default_link_state() call in pcie_aspm_cap_init() to
> before the "Restore L0s/L1" block. pcie_aspm_cap_init() disables L1 in
> hardware prior to aspm_l1ss_init() and re-enables it only in the
> restore block. Calling pcie_config_aspm_l1ss() while L1 is already
> disabled satisfies its precondition ("Caller must disable L1 first"),
> whereas the previous placement after the restore violated it.
>
> Since the restore block writes back the parent_lnkctl/child_lnkctl
> snapshot taken from hardware before the DT override ran, mask the L0s
> and L1 enable bits out of that snapshot for any state the override has
> just disabled in aspm_support. Otherwise the restore step would
> unconditionally reprogram the link back to firmware's original L0s/L1
> configuration, defeating the Devicetree override it is meant to
> enforce.
>
> Move pcie_config_aspm_l1ss() earlier in the file so it can be called
> from pcie_aspm_override_default_link_state().
>
> Link [1]: https://github.com/devicetree-org/dt-schema/pull/188
> Link [2]: https://github.com/devicetree-org/dt-schema/pull/190
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@xxxxxxxxxxxxxxxx>

Reviewed-by: Manivannan Sadhasivam <mani@xxxxxxxxxx>

- Mani

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