Update Sep 25 ‘22: Binary build of patched linux-zen kernel is now available! See here for more info.
After previously wiping out Windows 10 on my laptop (an ASUS Flip 13 OLED UX363ea), I felt better. Not because it finally became the Linux master race(tm), but rather that it stopped causing third degree burns every time it booted up.
The battery optimizations I installed for Arch Linux, well, worked.
It did helped reduce power consumption by a few hours.
Hoever, my laptop’s Intel processor was unable to reach the elusive
pc10 C-state with screen turned on. That means the CPU is still consuming electricity even though it would be better off turned off completely.
This, is not ideal.
But why does C-State matter?
C-states help CPU efficiency by progressively turning off more parts of the CPU with deeper C-states. Almost all modern x86 processors support it.
With Intel CPU’s amazing but elusive
the whole CPU is practically turned off.
We would want this if we need to minimize a computer’s power consumption.
You can check C-state residency of your device by utilizing
~$ sudo powertop
Searching for pc10 C-State
I was able to achieve
pc10 state by turning screen completely off,
pc8 could be reached otherwise.
So most likely the system display is blocking pc10 on my system.
Blog post from Intel seems to support my guess. You need to either turn off the screen or have a panel self-refresh(PSR) screen to reach pc10. The problem is, my laptop’s screen does support PSR, and PSR is automatically enabled if possible.
Just in case, I checked its PSR status.
~$ sudo cat /sys/kernel/debug/dri/0/i915_edp_psr_status Sink support: yes [0x01] PSR mode: disabled PSR sink not reliable: no
So it supports PSR, but Linux’s Intel GPU driver disabled it. For seemingly no reason. It even stated that the PSR sink is reliable. (PSR2 is not supported unfortunately)
Fixing panel self-refresh
So my hardware supports it. This is good news,
and we just need to fix the software somehow.
Since this clearly has something to do with
might as well enable
drm logging in the kernel.
drm logging, add
to your kernel’s command-line parameters.
Then, I checked the kernel log:
~$ sudo dmesg | grep PSR [ 1.273207] i915 0000:00:02.0: [drm:intel_psr_init_dpcd [i915]] eDP panel supports PSR version 1 [ 1.471109] i915 0000:00:02.0: [drm:intel_dp_initial_fastset_check [i915]] Forcing full modeset to compute PSR state [ 1.471892] i915 0000:00:02.0: [drm:intel_dp_compute_config [i915]] PSR condition failed: PSR setup time (330 us) too long
This error is caused by this file.
Apparently PSR is disabled due to a failed condition check. However, I know PSR worked on Windows. So, might just as well disable this condition check.
Patching Arch Linux’s kernel
I quickly made
linux 5.19.9. (Only tested on Arch Linux and Fedora)
To build a patched kernel, get
linux-zen’s build files,
~$ asp export linux-zen
, paste the patch file, and replace
PKGBUILD with the file in that gist.
Then, build the kernel:
~$ makepkg -s --skippgpcheck
Installing the kernel with:
~$ sudo pacman -U linux-zen-psrfix-5.19.9.zen1-1-x86_64.pkg.tar.zst linux-zen-psrfix-headers-5.19.9.zen1-1-x86_64.pkg.tar.zst
Enabling the patch
The option to force enable PSR is hidden behind a module parameter.
To enable it, add
~$ echo "options i915 enable_psr=1 psr_ignore_setup_time=1" > /etc/modprobe.d/i915.conf
initramfs, and reboot:
sudo mkinitcpio -P
Did it work?
Using the same command, we can check if the patch worked:
~$ sudo cat /sys/kernel/debug/dri/0/i915_edp_psr_status Sink support: yes [0x01] PSR mode: PSR1 enabled Source PSR ctl: enabled [0x81f00ee9] Source PSR status: SRDENT [0x40010000] Busy frontbuffer bits: 0x00000000
And it worked! Arbitarily removing that condition check enables PSR as expected.
Battery life after patching
powertop reports a battery drain of 2.9 Watt with screens on.
Wow. That’s 20 hours of battery life, a nearly 25% improvement from
its previous best record of 16 hours.
Although panel self-refresh only kicks in when the screem
is displaying static images, this will still help a lot.
But wouldn’t that cause issues? That’s why the condition check was there in the first place, no?
Fortunately for me, there doesn’t seem to be any issues after applying the patch.
The laptop still works, there are no tearing or stability issues.
It could be that my screen reported erraneous latency.
Even better, the CPU is able to reach
pc10 with display on now!
Binary build of patched linux-zen kernel is now available! If your laptop is facing the same problem, feel free to try it out.
Make sure to have another kernel in case this one fails!
The installation files can be downloaded in CI/CD tab.