#acpi

mauve75@diaspora-fr.org

Putting an AMD Ryzen based HP x360 Envy (13-ar0xxx) into legacy S3 suspend mode

#Linux #Manjaro #AMD #Ryzen #x360 #13ar0xxx #s2idle #s0ix #s3 #deepsleep #acpi
WARNING : This tutorial is specific to that exact computer model, but the general idea may help debug other systems.
So, to whom may find that tutorial useful …
Context :
I have a 2020 HP X360 Envy 13-ar0xxx (Ryzen 7 3700U based, nothing fancy but nice hardware) ; bios version F.25 dated 04/2022
The darn thing has never been able to sleep under Linux because HP screwed buyers by only allowing the s2idle method to put the computer into sleep mode, and that method is broken on AMD Ryzen based platforms. Work is being done to support s2idle in kernel, but at a glacially slow pace.
HP refuses to acknowledge the problem (unlike Dell or Lenovo) and locked the AMI Bios option to switch between S2idle and the more common S3 (deep sleep) method. Thankfully, hibernation has always worked and the SSD is fast enough it’s not too painful. But. But it’s MY computer and I’m not going to be told what I can, can’t or should do.

After months of trying every “legal” way to make it happen without success, I finally (thanks to a bout of COVID) took some days to stick my greasy fingers into the root cause of the problem : ACPI tables.

 First you need to install the acpi-tools. With Manjaro, use snap :

https://snapcraft.io/install/acpi-tools/manjaro

- create a work directory and place yourself inside that directory

- run : 
acpi-tools.acpidump -o tables 
to create a file with the currently running tables then
acpi-tools.acpixtract -a tables 
to extract the individual tables (we need both FACP and DSDT tables)

- FACP :
acpi-tools.iasl -d facp.dat to disassemble the FACP table
edit facp.dsl
increase the “Oem Revision” field at the top by 1
set the “Hardware Reduced (V5)” field to 0
acpi-tools.iasl -sa facp.dsl to assemble your modified table

- DSDT :
acpi-tools.iasl -e ssdt*.dat -d dsdt.dat
(if you don’t xref ssdt tables, you won’t be able to recompile dsdt)
edit dsdt.dsl
add 1 to the last parameter of the DefinitionBlock() line - that’s the OEM version number
search for XS3 ; replace with _S3 (one occurence)
acpi-tools.iasl -sa dsdt.dsl to assemble your modified table

- Make the following folder structure: payload/kernel/firmware/acpi/
In the acpi/ folder add your compiled facp.aml and dsdt.aml
In the payload/ folder, run:
find kernel | cpio -H newc --create > overrideacpi.img

- Move the resulting overrideacpi.img to your /boot folder
Edit /etc/default/grub
Add mem_sleep_default=deep as the last parameter of the line GRUB_CMDLINE_DEFAULT
(like so : ) GRUB_CMDLINE_DEFAULT="... mem_sleep_default=deep"
Create a new line just below like so :
GRUB_EARLY_INITRD_LINUX_CUSTOM="overrideacpi.img"
Save /etc/default/grub
Update grub as usual : sudo update-grub

- Finally reboot. Check in dmesg your modified ACPI tables are indeed loaded, and do a :
cat /sys/power/mem_sleep, it should now return :
s2idle [deep]

Try putting the computer to sleep and enjoy the sound of silence… and be amazed when it wakes up at the slightest touch of the space bar !

last words : I haven’t tested all the the scenarios where this could go wrong (plugging or unplugging AC power while the computer is suspended, for instance), but it seems to do the job so far. In S3 suspend mode, the computer draws less than 1% of the battery per hour.

This solution was heavily inspired by the work of Jordan Maris : https://gitlab.freedesktop.org/drm/amd/-/issues/1230#note_580057