Page MenuHomeFreeBSD

acpi_spmc: Add SPMC (system power management controller) driver
Needs ReviewPublic

Authored by obiwac_gmail.com on Thu, Jan 9, 12:15 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Jan 30, 4:14 AM
Unknown Object (File)
Thu, Jan 30, 4:11 AM
Unknown Object (File)
Thu, Jan 30, 4:06 AM
Unknown Object (File)
Wed, Jan 29, 8:39 PM
Unknown Object (File)
Wed, Jan 29, 12:21 PM
Unknown Object (File)
Wed, Jan 22, 2:05 PM
Unknown Object (File)
Wed, Jan 22, 2:03 PM
Unknown Object (File)
Mon, Jan 13, 6:31 PM

Details

Reviewers
jkim
jhb
imp
Summary

Add SPMC (system power management controller) driver as acpi_spmc. This is the device which provides the LPI device D-state constraints and allows for OSPM to send S0ix/modern standby entry/exit notifications. This supports the original Intel DSM (https://uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf, untested), the AMD DSM (tested), and the Microsoft DSM (partially tested, getting constraints seems to only work for the AMD DSM on my machine).

For entry/exit, all the notifications supported by the platform are called. I'm not sure of which ones are necessary and on which systems exactly, but my system needs at least one of the AMD or Microsoft regular entry notifications and the Microsoft modern standby one. I don't think it's necessarily an issue to do this, and Linux adopts the same strategy.

Before entry, acpi_spmc_check_constraints is called to notify of any violated power constraints. This uses acpi_pwr_get_state added in D48386 to get current device D-states.

This is a prerequisite to s2idle on AMD, as the EC (which we can't mask out the GPE's of because it notifies us of important wake events, such as the lid opening or the power button being pressed) is very noisy until the entry notifications are called: https://patchwork.kernel.org/project/linux-pm/patch/2279758.LZ0rCGQtcH@aspire.rjw.lan/ It still is very noisy (albeit less so) but hopefully that's something a driver for the AMD PMC will solve.

This is sort of a parallel to @bwidawsk 's D17676 revision, which went with device_post_suspend/resume device methods to call SPMC's entry/exit functions. Since we'll probably also need an AMD-specific PMC that runs after device_post_suspend in the near future, I decided against doing it this way and instead simply added acpi_spmc_enter/exit function pointers on the ACPI softc which acpi_spmc sets in probe to be called in a future patch before idling in acpi_EnterSleepState.

Another solution (what I believe Linux does after a cursory check) is to make acpi_spmc responsible for calling the entry/exit functions for any other PMC's there may be. My concern for doing this is if a system has an AMD PMC but no SPMC, if such a system exists.

Sponsored by: The FreeBSD Foundation

Test Plan

I have tested this on the Framework 13 AMD Ryzen 7040 series. I am able to get device constraints correctly and enter/exit from modern standby when idling the CPU and the device constraints are respected. Other devices (especially Intel-based) will need testing.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 62097
Build 58981: arc lint + arc unit

Event Timeline

obiwac_gmail.com created this revision.

On my laptop with Intel i7-1355U CPU I see this while device attached:

Jan 29 15:19:07 thinkpad kernel: acpi_spmc0: <Low Power S0 Idle (DSM sets 0x3)> on acpi0
Jan 29 15:19:07 thinkpad kernel: ACPI Error: Incorrect return type from \_SB_.PEPD._DSM - received [Buffer], requested [Package] (20241212/nsxfeval-274)
Jan 29 15:19:07 thinkpad kernel: acpi_spmc0: failed to call DSM 1 (acpi_spmc_get_constraints)

On my laptop with Intel i7-1355U CPU I see this while device attached:

Jan 29 15:19:07 thinkpad kernel: acpi_spmc0: <Low Power S0 Idle (DSM sets 0x3)> on acpi0
Jan 29 15:19:07 thinkpad kernel: ACPI Error: Incorrect return type from \_SB_.PEPD._DSM - received [Buffer], requested [Package] (20241212/nsxfeval-274)
Jan 29 15:19:07 thinkpad kernel: acpi_spmc0: failed to call DSM 1 (acpi_spmc_get_constraints)

Thanks for testing this out! Indeed, I believe this is due to me using the Microsoft UUID instead of the Intel one for getting device constraints on Intel. I will let you know when I fix this.

  • Use Intel GET_DEVICE_CONSTRAINTS DSM by default (Microsoft doesn't have this)
  • Comment for entry/exit notification functions

@shuriku_shurik.kiev.ua Intel (might) work now. I have not validated the acpi_spmc_get_constraints_spec function at all however, as I don't have an Intel laptop. So there are likely to be other problems :)

Print out message when all device power constraints are respected

@shuriku_shurik.kiev.ua Intel (might) work now. I have not validated the acpi_spmc_get_constraints_spec function at all however, as I don't have an Intel laptop. So there are likely to be other problems :)

There are another errors now:

Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: <Low Power S0 Idle (DSM sets 0x3)> on acpi0
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.EMMC
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.PSDC
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.SAT0.VOL0
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.GLAN
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.VMD0
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.RP25
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.RP26
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.RP27
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.RP28
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.PUF0
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.PUF1
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC00.TXDC
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC01.TRP0
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC01.TRP1
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC01.TRP2
Jan 30 06:19:20 thinkpad kernel: acpi_spmc0: failed to get handle for \_SB.PC01.TRP3

I found some time and tried it on Intel Core 8th gen laptop.

acpi_spmc0: <Low Power S0 Idle (DSM sets 0x1)> on acpi0
acpi_spmc0: failed to get handle for \134_SB.PCI0.PSDC

Thanks for trying this out @jkim & @shuriku_shurik.kiev.ua :)

Could you send me your ASL dumps by email (obiwac@freebsd.org):

acpidump -dt