Linux Optimizations for your GPD Win Max

Power management, TDP limitations and more.

Linux Optimizations for your GPD Win Max

Here are several tips, tools and configurations that will help you get the most out of your GPD Win Max running Linux. While this guide uses arch-specific commands like pacman and yay, the actual tools and configurations mentioned should for the most part work regardless which flavor you're running. Please substitute these flavor-specific commands with your own flavor's equivalents where necessary.

Some of these will yield bigger results than others, and some might feel like they don't really have any benefit at all. The goal of these optimizations is to have an as good as possible overall experience, without also requiring a lot of additional tinker time afterwards. Some might enjoy doing that, but I prefer if the Max works well enough so I can enjoy a game here and there.

If you're looking for a guide on how to install Linux on your Max, I have a guide for EndeavourOS as-well as a guide for Manjaro available. You can follow those, then continue onward with this guide here.

Preface

It is not actually my goal to get the absolute most power out of my Max, as that actually limits my personal enjoyment that I could get from the Max. I don't enjoy having the fans at full blast, nor would I really enjoy having just a one-or-thereabouts-hour battery life. So I instead focus on finding the sweet spot, finding a balance between performance, battery life, and temperature.

If your needs vary from this, you can cherry-pick suggestions from this article. Or perhaps use the same tools, but instead configured favoring performance (or battery life) more, for example.

Alright, with that out of the way, let's get to it.


Latest (git) Mesa drivers

You'll probably want to use the more recent mesa drivers to get the most out of your Max and for increased compatibility with games. If you haven't already, install the git Mesa drivers:

❯ yay -S mesa-git lib32-mesa-git

Undervolting & TDP Limits

Starting off with the big one, undervolting can yield a nice performance boost (contradictory as that might initially feel), though does require some thought and consideration. Setting values too aggressively can result in an unstable system, so you'll want to tread carefully here.

If you're familiar with using ThrottleStop under Windows, the concept is similar here, though lacks a GUI. Let's start by installing the following package:

❯ yay -S intel-undervolt

With that out of the way, let's first take a look at the configuration file. Before diving in the deep and making the tool re-apply all these changes you're about to make automatically at reboot, let's first start by trying out what works best for your specific unit. That way if things go wrong and your device crashes, you can actually reboot and not have it immediately jump back into crashing.

Using your favorite text editor, (sudo) open /etc/intel-undervolt.conf. If you scroll down a tiny bit, you'll find the section that covers undervolting. You'll want to pay specific attention to the CPU, GPU and CPU Cache options, and leave the last two alone as they don't work, nor would they really provide any note-worthy benefits if they did.

The number you'll enter here is a relative number, meaning if you write down -50, it means you want to have that specific option run with 50 millivolt (mV) less than its default setting. If you've ever used ThrottleStop before, this is likely identical to how you used it, too.

In a nutshell

If you're new to undervolting, you might want to take an extra moment to read up on how it works. And don't be mistaken; even though we're talking about millivolts here, a difference of just a few tens of millivolts can be the difference between a stable system, and one that crashes constantly.

As how far you're able to push it very much depends on your luck with the "sillicon lottery" (meaning each individual chip will have its own range of stable operating voltages), I highly recommend you start off with low numbers and use -10mV increments.

Each time you apply changes, run some kind of stress test to ensure your Max runs stable still. This could be a synthetic test like Geekbench, or a game that you know pushes your Max hard for example. If the game has a benchmark option, all the better, as it means you can run a consistent test.

Once your Max starts crashing, you know you've gone too far. Jump back down 10mV and re-run the tests. If things are stable, you know you've hit your speciifc hardware's stable limits. Great!

Finding your values

Alright, it's time to give it a try. As I mentioned, start with small numbers and work your way up. Slow and steady wins the race here, and as you're working with three separate values, you'll want to take your time to make sure you understand which value had what (negative) effect.

I recommend you focus on one value at a time. The GPU and CPU values are most interesting in terms of potential performance benefits, with CPU Cache being in third place. While it is possible that you might have to revisit your GPU value once you're tuning in your CPU one, for example, being consistent and focussing on one value at a time will make the whole process a lot simpler, with less guess work involved.

Following the above recommendations, set your first values, and save the configuration file. We should now apply these changes using the following command:

❯ sudo intel-undervolt apply

To try it out we need to start the intel-undervolt service. We don't yet want to enable it fully as we don't want it to apply our changes after every reboot until we're certain everything works consistently, so for now let's just start the service:

❯ sudo systemctl start intel-undervolt

You can use the built-in measure feature to see what the current wattages, voltages and more are. To run this, use the following command:

❯ sudo intel-undervolt measure

This can be pretty handy to see what's going on, and also because you're able to run this command via ssh, so if you have a secondary device, you can monitor everything that's going on even while in a full-screen game for example.

Once you've completed your performance tests and your Max ran stable, you can try bumping it up a bit. You'll want to repeat this process until you've hit your device's sweet spot. This might be a bit tedious, but it'll be worth it in the end.

undervolt 0 'CPU' -70
undervolt 1 'GPU' -100
undervolt 2 'CPU Cache' -70
My Max runs stable with these values, but this fully depends on the unit. Yours might be able to run with higher values, or might require lower ones. Use this as a reference only, it's much better to go through the process and find the values that work best with your Max.

When you've found your values

Once you have found the values you're satisfied with, you can now fully enable the intel-undervolt service so that it can automatically apply these after reboots too:

❯ sudo systemctl enable intel-undervolt

And that's it! You now have undervolted your system. Congratulations!

Let's now take a look at limiting TDP values.

TDP limits:

In the same file you can set TDP limits. It might be handy to write out several options and only un-comment the one you want to use at the moment. Something like this:

# power package 5 5
# power package 10 10
power package 15 15
# power package 20 20
# power package 25 25

When setting the power package values, you're actually setting the short- and long-term values. That's why you see two numbers in my example above. I personally have set both values the same, as you can see in the above example.

This isn't the same as disabling Turboboost. It simply means that in its turboboost stage the CPU is limited to using the same amount of power. If you prefer to get the absolute most out of your Max it might make sense to use different values for these two stages, but as I personally aim to have more consistent performance and battery life, I opted to limit both stages to the same power consumption limits.

Speaking of limiting things, let's take a look at disabling Turboboost next.


Disabling Turboboost

If you want to keep heat and noise to a minimum, it might be interesting to disable Turboboost. Depending on the game this could have a noticeable performance impact, but on the other hand you could end up with (much) more battery life and less heat and noise coming from your Max. In my experience my Max would consistently be about 10 degrees cooler with Turboboost disabled, and the fans could remain at medium speeds instead of frequently jumping to or fully staying at high speeds.

Try it out with your games and see if the trade-offs are worth it.

Trying it out

Running the following command will disable turboboost until your next reboot. It's a great way to give it a try and see what kind of impact disabling it might have on the games you like to play:

❯ echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

Try running several of the games you'd like to play on your Max and see what performance is like. Unless you're trying to push your Max to the, uh, max, and so long as you have reasonable expectations, you might be surprised how many games can still run very well.

Persistent settings

To have your settings be persistent even after reboots, we can make use of TLP, which comes pre-installed with EndeavourOS. Using your favorite text editor and sudo, open /etc/tlp.conf and modify the following options:

# To ensure TLP is fully enabled you can uncomment this line
TLP_ENABLE=1

# This disables Turboboost both on battery power as-well as when plugged in
CPU_BOOST_ON_AC=0
CPU_BOOST_ON_BAT=0

# Set both to 0 to avoid possible hiccups in performance by having your Max always keep all cores/threads available
SCHED_POWERSAVE_ON_AC=0
SCHED_POWERSAVE_ON_BAT=0

Have your changes applied right away by running:

❯ sudo systemctl restart tlp

Anytime you change these settings, be sure to run the above command – or you can reboot your Max for the same effect.

It might be interesting to look through the other available options. Depending on what kind of setup you are going for, there might be some values you can tweak to get a configuration more ideal to your specific needs.


ZEN kernel (or a tkg variant)

The linux-zen kernel is a nice choice as it comes with fsync support, which can provide some additional performance boosts with certain games. It's also a pretty easy choice as it's provided directly in AUR for most Arch-based linux flavors.

If you're a little more adventurous you could consider something like the tkg variants provided by chaotic-aur or frogging family. I am honestly not entirely sure if it's worth the potential hassle and consistency issues that going this route might bring. I had previously been using chaotic-aur's builds but they had some recurring issues with their build servers. Perhaps it is better by the time you read this though, so it could be an interesting choice.

To install the zen kernel, run the following command:

❯ sudo pacman -S linux-zen linux-zen-docs linux-zen-headers

Gamemode

GameMode is a daemon/lib combo for Linux that allows games to request a set of optimisations be temporarily applied to the host OS and/or a game process.
❯ yay -S gamemode lib32-gamemode

After this you'll be able to preface each games' launch command in Steam with gamemoderun to make use of this tool. Unfortunately there doesn't seem to be one way to do it for all games. Fortunately it's only a little bit of effort.


Sensor reading

If you plan on using something like Mangohud or a similar tool to monitor your Max' temperatures, install and configure the following package:

❯ sudo pacman -S lm_sensors
❯ sudo sensors-detect

MangoHud

Speaking of Mangohud, you can install mangohud (or mangohud-git) from AUR using yay, or install the pre-packaged binaries by downloading them from the MangoHud GitHub repository.

From AUR

❯ yay -S mangohud lib32-mangohud

Or for the git version:

❯ yay -S mangohud-git lib32-mangohud-git

Pre-packaged binaries

Download the recent-most version from the MangoHud GitHub repository, then unpack the file and run the included installer:

❯ tar -xvf ~/Downloads/MangoHud*.tar.gz;
❯ cd ~/Downloads/MangoHud && ./mangohud-setup.sh install

Configuring MangoHud

Copy the default configuration file over as a starting point, then edit the file to your liking using your favorite text editor.

❯ mkdir -p ~/.config/MangoHud && cp /usr/share/doc/mangohud/MangoHud.conf.example ~/.config/MangoHud/MangoHud.conf

You can also create game-specific configuration files, as described in MangoHud's readme. Note that displaying GPU information will not work, as this information is apparently not available to MangoHud without root access.

Here's a somewhat abbreviated version of my preferred settings. I've disabled GPU stats as they don't work for integrated graphics anyway, and added three fps limits (off, 60, and 30) that you can cycle through, which might come in handy for certain games.

As of MangoHud version 0.6.2 battery information can now be shown too, which is a really nice addition. I have updated the configuration file below to include this handy new feature.
### MangoHud configuration file
### Uncomment any options you wish to enable. Default options are left uncommented
### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead

################ PERFORMANCE #################

### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless v-synced).
fps_limit=0,60,30

### VSYNC [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
# vsync=

### OpenGL VSYNC [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a fps limiter (fps = display refresh rate / N)
# gl_vsync=

################### VISUAL ###################

### Legacy Layout
# legacy_layout

### Display the current CPU information
cpu_stats
cpu_temp
cpu_power

### Display the current GPU information
vulkan_driver  

### Display FPS and frametime
fps
frametime

### Display loaded MangoHud architecture
arch

### Display the frametime line graph
frame_timing
#histogram

### IO read and write for the app (not system)
# io_read
# io_write
# io_stats

### Display system ram / vram usage
ram

### Display version info of used tools
wine
gamemode
vkbasalt

# Show battery stats
battery

### Disable / hide the hud by deafult
# no_display

################## INTERACTION #################

### Change toggle keybinds for the hud & logging
toggle_hud=Shift_R+F12
toggle_fps_limit=Shift_L+F1
toggle_logging=Shift_L+F2
reload_cfg=Shift_L+F4
#upload_log=Shift_L+F3

Reading CPU power consumption

Due to a vulnerability more recent versions of the Linux kernel disable reading the CPU's power consumption value without root access. If you are looking to display this value in your MangoHud, you'll have to modify the read permission like so:

❯ sudo chmod o+r /sys/class/powercap/intel-rapl\:0/energy_uj

This change is lost after each reboot, but as there's a known vulnerability that's probably for the best.

I have created a simple bash script on my Desktop that I run after a (re)boot whenever I plan on monitoring power consumption. Perhaps you can do something similar, or if you're not worried about the vulnerability you could even make a script that runs automatically at boot.


Closing thoughts

These are but a few suggestions that I hope will help you get the most of your Max. There's probably much more you can do if you're really looking to squeeze the most of your device (in terms of battery life or performance alike), but hopefully these few will help you get started.

I've been really enjoying my Max so far. I am curious about the upcoming refresh, though also a little wary about the possible pricetag that might be attached to it. Regardless of that, I am continuously amazed by how performant the current Max already is. Seeing games like GTA5, Sleeping Dogs, Metal Gear Solid 5 run smoothly at a fixed 30fps, or being able to re-play and possibly finally actually finish Persona 4 Golden is just great fun.

And for those games that simply require a lot more power, being able to use remote play functionality to stream them off of my desktop allows me to still sit comfortably on my couch or in bed for an occasional half an hour or so before sleep for example. I don't play very often, but it's been very nice to have the Max around for when I do.

Before switching from Manjaro to EndeavourOS I had attempted to run Windows 10 on the Max, as I had never really tried that before. I did not like it very much. While in some games you might be able to get 10% more performance, other games you lose performance due to the way Windows just can't seem to ever be fully idle, or at least fully focused on whatever game it is you're trying to run.

What I also immediately missed was the cleanliness that using tools like Proton or separate Wine prefixes through Lutris brings. If you uninstall a game on Windows, you might still have a bunch of left-over stuff. Or perhaps one game or its required software might actually conflict with another game.  Maybe one of those umpteen game launchers/stores will linger on in a half-activated, auto-boot-at-launch state, or something else. Under Linux, you throw away the folder/prefix, and it's gone. No conflicts, no mess. I love that.

I hope you're enjoying your Max, and now that you're possibly running Linux on it, I hope you'll be able to get even more enjoyment out of it.

Happy gaming.


GPD Max

GPD Pocket 2