diff mbox series

[v14.c,3/4] PCI: ACPI: Use device constraints to opt devices into D3 support

Message ID 20230818194027.27559-4-mario.limonciello@amd.com
State New
Headers show
Series Use LPS0 constraints to opt devices into D3 | expand

Commit Message

Mario Limonciello Aug. 18, 2023, 7:40 p.m. UTC
In Windows, systems that support Modern Standby specify hardware
pre-conditions for the SoC to be able to achieve the lowest power state
by using 'device constraints' in a SOC specific "Power Engine
Plugin" (PEP) [1] [2].

For each device, the constraint is the minimum (shallowest) power
state in which the device can be for the platform to be still able to
achieve significant energy conservation in a system-wide low-power
idle configuration.

Device constraints are specified in the return value for a _DSM of
a PNP0D80 device, and Linux enumerates the constraints during probing.

For PCI bridges (including PCIe ports), the constraints may be
regarded as an additional source of information regarding the power
state to put the device into when it is suspended.  In particular, if
the constraint for a given PCI bridge is D3hot, the platform regards
D3hot as a valid power state for the bridge and it is reasonable to
expect that there won't be any side effects caused by putting the
bridge into that power state.

Accordingly, take the low-power S0 idle (LPS0) constraints into
account when deciding whether or not to allow a given PCI bridge to be
put into D3.

Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/platform-design-for-modern-standby#low-power-core-silicon-cpu-soc-dram [1]
Link: https://uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf [2]
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
v13->v14:
 * Move code as another way to satisfy acpi_pci_bridge_d3() instead
 * Update commit with Rafael's suggestions
v12->v13:
 * Move back to PCI code
 * Trim commit message
v11->v12:
 * Adjust for dropped patch 8/9 from v11.
 * Update comment
v10->v11:
 * Fix kernel kernel build robot errors and various sparse warnings
   related to new handling of pci_power_t.
 * Use the new helpers introduced in previous patches
---
 drivers/pci/pci-acpi.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Rafael J. Wysocki Aug. 21, 2023, 6:38 p.m. UTC | #1
On Fri, Aug 18, 2023 at 9:40 PM Mario Limonciello
<mario.limonciello@amd.com> wrote:
>
> In Windows, systems that support Modern Standby specify hardware
> pre-conditions for the SoC to be able to achieve the lowest power state
> by using 'device constraints' in a SOC specific "Power Engine
> Plugin" (PEP) [1] [2].
>
> For each device, the constraint is the minimum (shallowest) power
> state in which the device can be for the platform to be still able to
> achieve significant energy conservation in a system-wide low-power
> idle configuration.
>
> Device constraints are specified in the return value for a _DSM of
> a PNP0D80 device, and Linux enumerates the constraints during probing.
>
> For PCI bridges (including PCIe ports), the constraints may be
> regarded as an additional source of information regarding the power
> state to put the device into when it is suspended.  In particular, if
> the constraint for a given PCI bridge is D3hot, the platform regards
> D3hot as a valid power state for the bridge and it is reasonable to
> expect that there won't be any side effects caused by putting the
> bridge into that power state.
>
> Accordingly, take the low-power S0 idle (LPS0) constraints into
> account when deciding whether or not to allow a given PCI bridge to be
> put into D3.
>
> Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/platform-design-for-modern-standby#low-power-core-silicon-cpu-soc-dram [1]
> Link: https://uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf [2]
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>

All feedback addressed AFAICS, so

Reviewed-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
> v13->v14:
>  * Move code as another way to satisfy acpi_pci_bridge_d3() instead
>  * Update commit with Rafael's suggestions
> v12->v13:
>  * Move back to PCI code
>  * Trim commit message
> v11->v12:
>  * Adjust for dropped patch 8/9 from v11.
>  * Update comment
> v10->v11:
>  * Fix kernel kernel build robot errors and various sparse warnings
>    related to new handling of pci_power_t.
>  * Use the new helpers introduced in previous patches
> ---
>  drivers/pci/pci-acpi.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index 64e6ada024235..8331aea22d327 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -1022,6 +1022,15 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)
>
>         adev = ACPI_COMPANION(&dev->dev);
>         if (adev) {
> +               int acpi_state;
> +
> +               /* Check if the platform specifies an LPS0 constraint of D3. */
> +               acpi_state = acpi_get_lps0_constraint(adev);
> +               pci_dbg(dev, "LPS0 constraint: %d\n", acpi_state);
> +               if (acpi_state != ACPI_STATE_UNKNOWN &&
> +                   acpi_state >= ACPI_STATE_D3_HOT)
> +                       return true;
> +
>                 /*
>                  * If the bridge has _S0W, whether or not it can go into D3
>                  * depends on what is returned by that object.  In particular,
> --
> 2.34.1
>
diff mbox series

Patch

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 64e6ada024235..8331aea22d327 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1022,6 +1022,15 @@  bool acpi_pci_bridge_d3(struct pci_dev *dev)
 
 	adev = ACPI_COMPANION(&dev->dev);
 	if (adev) {
+		int acpi_state;
+
+		/* Check if the platform specifies an LPS0 constraint of D3. */
+		acpi_state = acpi_get_lps0_constraint(adev);
+		pci_dbg(dev, "LPS0 constraint: %d\n", acpi_state);
+		if (acpi_state != ACPI_STATE_UNKNOWN &&
+		    acpi_state >= ACPI_STATE_D3_HOT)
+			return true;
+
 		/*
 		 * If the bridge has _S0W, whether or not it can go into D3
 		 * depends on what is returned by that object.  In particular,