Fix suspend issues on Dell 7405 2-in-1
Tags: linux, opensource
Published: 2020-10-29 22:29:42

>**UPDATE SEPTEMBER 2021.** _S3 suspension was fixed on kernel 5.14 and this guide works again._

~~>**UPDATE MARCH 2021.** _A patch to enable S0ix state on AMD Renoir hardware has been merged into kernel 5.11, but it does not work at all. In fact, this patch also broke the method to enable the S3 suspension described in this article. To get the latest updates about this issue [follow the discussion on GitLab](https://gitlab.freedesktop.org/drm/amd/-/issues/1230)._~~

If you are a GNU/Linux user and bought this laptop (or any other laptop with Ryzen 4700U) recently , probably you found suspend to RAM does not work at all.

### The root of all evil

Due to the new Windows "modern/connected standby" ([S0ix](https://www.anandtech.com/show/6355/intels-haswell-architecture/3)) the good old sleep to RAM (S3) is disabled in some laptops. We need to patch our DSDT to make S3 available again.

> _AMD support for S0ix will be available soon, making this guide unnecessary (unless you want to save battery or have a decent and reliable sleep mode). Anyways, S0ix is garbage and people that designed it should have a place reserved in hell._

First of all, check S3 state and deep sleep mode are not available:

```
$ sudo dmesg | grep -i acpi | grep supports
[    0.357470] ACPI: (supports S0 S4 S5)
```
```
$ cat /sys/power/mem_sleep
[s2idle]
```


### What's DSDT?

From the [ArchLinux Wiki](https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface):

> _DSDT (Differentiated System Description Table) is a part of the [ACPI](https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface) specification. It supplies information about supported power events in a given system. ACPI tables are provided in firmware from the manufacturer. A common Linux problem is missing ACPI functionality, such as: fans not running, screens not turning off when the lid is closed, etc. This can stem from DSDTs made with Windows specifically in mind, which can be patched after installation. The goal of this article is to analyze and rebuild a faulty DSDT, so that the kernel can override the default one.
  <br> Basically a DSDT table is the code run on ACPI (Power Management) events._



### Step 0: Use a recent Linux Kernel

> _Not directly related to the issue, but it's worth doing._

AMD Ryzen 4000 mobile processors require Linux Kernel v5.8 or above to perform correctly.

At the moment of writing this post, there are a few options to get this kernel: use **openSUSE Tumbleweed**, or installing a _mainline_ kernel on Ubuntu. Also, it's supossed with the release of **Ubuntu 20.04.2** (scheduled for October 2020) the kernel 5.8 will arrive to [the Ubuntu HWE stack](https://wiki.ubuntu.com/Kernel/LTSEnablementStack).

### Step 1: Extract and decompile DSDT

Get `acpidump` and `iasl`, provided by the `acpica` package. Then, dump all your ACPI files into a directory:

```
$ mkdir acpi
$ cd acpi
$ sudo acpidump -b
```

And decompile the DSDT:

```
$ iasl -e *.dat -d dsdt.dat
```

This command produces a source file named `dsdt.dsl`.

### Step 2: Recompile DSDT and examine errors

> IMPORTANT: I updated the BIOS to v1.3.0 (Sep 18, 2020) immediately after purchasing this laptop. Errors and line numbers may vary depending on your BIOS version.

```
iasl -tc dsdt.dsl &> iasl_errors.txt
```

Look for errors in `iasl_errors.txt` with your text editor. For BIOS v1.3.0 you should have just three identical error messages pointing to lines `3965`, `4002` and `4030`.

Open `dsdt.dsl`, look for those lines and replace:

```
Return (Zero)
```

with:

```
Return (ToBuffer(Zero))
```

Then, re-run:

```
iasl -tc dsdt.dsl &> iasl_errors.txt
```

... and make sure there are no more errors on `iasl_errors.txt`.

### Step 3: Enable S3 state

Search for this piece of code in `dsdt.dsl`:

```
    If ((CNSB == Zero))
    {
        If ((DAS3 == One))
        {
            Name (_S3, Package (0x04)  // _S3_: S3 System State
            {
                0x03, 
                0x03, 
                Zero, 
                Zero
            })
        }
    }
```

Then, remove the two if statements and fix the indentation accordingly:

```
Name (_S3, Package (0x04)  // _S3_: S3 System State
{
    0x03, 
    0x03, 
    Zero, 
    Zero
})
```

### Step 4: Bump OEM version

Increase OEM version or otherwise the kernel will not apply the modified ACPI table. In line `21` replace:

```
line 21:    DefinitionBlock ("", "DSD   T", 1, "DELL  ", "WN09    ", 0x00000002)
```

with:

```
line 21:    DefinitionBlock ("", "DSD   T", 1, "DELL  ", "WN09    ", 0x00000003)
```

### Step 5: Compile the final DSDT

```
iasl -ve -tc dsdt.dsl
```

### Step 6: Create a `cpio` file

```
$ mkdir -p kernel/firmware/acpi
$ cp dsdt.aml kernel/firmware/acpi
$ find kernel | cpio -H newc --create > acpi_override
$ sudo cp acpi_override /boot
```

### Step 7: Update GRUB

Edit file `/etc/default/grub` and append `"mem_sleep_default=deep"` to `GRUB_CMDLINE_LINUX_DEFAULT` parameter.

Then, add the line `GRUB_EARLY_INITRD_LINUX_CUSTOM="acpi_override"` below.

Finally, update GRUB with `sudo update-grub` (Debian/Ubuntu) or through _YaST_ > _System_ > _Boot Loader_ in openSUSE (just make a minor change like increasing or decreasing timeout).

### Step 8: Reboot

Reboot and check if S3 and deep sleep are enabled. You should see:

```
$ sudo dmesg | grep -i acpi | grep supports
[    0.502663] ACPI: (supports S0 S3 S4 S5)
```
```
$ cat /sys/power/mem_sleep
s2idle [deep]
```

Finally, try suspending to RAM.

## References

- [Fixing the DSDT of an Asus P8Z68V-Pro]() | Gentoo Forums
- [Best practice to debug Linux* suspend/hibernate issues](https://01.org/blogs/rzhang/2015/best-practice-debug-linux-suspend/hibernate-issues) | 01.org
- [Lenovo IdeaPad 5 14are05 - Suspend issues (S3 sleep fix)](https://wiki.archlinux.org/index.php/Lenovo_IdeaPad_5_14are05#Suspend_issues_(S3_sleep_fix)) | ArchWiki
- [Lenovo ThinkPad X1 Yoga (Gen 3) - Enabling S3 (before BIOS version 1.33)](https://wiki.archlinux.org/index.php/Lenovo_ThinkPad_X1_Yoga_(Gen_3)#Manual_method) | ArchWiki
- [AMD Ryzen 7 4700U suspend/hibernate not working on any kernel
](https://www.reddit.com/r/linuxhardware/comments/j517jj/amd_ryzen_7_4700u_suspendhibernate_not_working_on/) | Reddit
- [Ideapad 14ARE05 S3 sleep fix
](https://www.reddit.com/r/linuxhardware/comments/i28nm5/ideapad_14are05_s3_sleep_fix/) | Reddit