GNOME/Wayland environment for CachyOS on a hybrid-graphics laptop with a 4K OLED panel — plus a full hardware investigation log for a machine whose vendor firmware fights back.
If your NVIDIA laptop GPU is stuck around 16 W instead of its rated
35 W, games run at ~17 FPS with heavy input lag, nvidia-smi reports
SW Power Cap throttling, and your kernel log looks like this:
NVRM: GPU0 ... PlatformRequestHandler failed to get target temp from SBIOS
NVRM: GPU0 ... PlatformRequestHandler failed to get platform power mode from SBIOS
[NV_ERR_INVALID_DATA] (0x00000025)
nvidia-powerd: DC power limits table is not supported
nvidia-powerd: Client (presumably SBIOS) has requested to disable Dynamic Boost DC controller
ucsi_acpi USBC000:00: bogus connector number in CCI: 2
…then you have the same problem this repo documents, and there is a working
workaround: debug/gpu/ — start with
OPERATIONS.md for the runbook, or
SOLUTION.md for the mechanism.
Short version: the platform↔GPU power negotiation channel is broken because
the SBIOS returns garbage, so the driver silently caps itself. The fix
injects a runtime SSDT exposing an \NVST method and drives the NVPCF
handshake manually (NVST 3 → wait → NVST 1) under GPU load, re-armed on
every login by a systemd user unit. Affected hardware here is a Xiaomi
Book Pro 16 2022 with an RTX 2050, BIOS XMAAD6B0P1717 (2022-12-13),
but the mechanism should apply to any laptop whose SBIOS breaks NVPCF.
The same broken ACPI also costs this machine its battery charge-limit
interface — see debug/battery/.
- Device: Xiaomi Book Pro 16 2022
- CPU: Intel Core i7-1260P (12th Gen, Alder Lake-P)
- GPU: NVIDIA RTX 2050 Mobile + Intel Iris Xe (hybrid,
nvidia-prime) - Display: 4K OLED
- Storage: Kingston FURY Renegade 2 TB, btrfs + zstd
- Kernel:
linux-cachyos
- DE: GNOME Shell 51 on Wayland
- Shell: Fish 🐟 + Starship
- Terminal: Ghostty
- AUR Helper: Paru
- Power Management: Gamemode + custom GPU clock locking
- VPN: Mullvad (with split tunneling for Steam, Spotify, VS Code and Claude)
fish/— shell config,fnm/pnpmpaths,fastfetchgreeting.ghostty/,fontconfig/— terminal and UI styling.fastfetch/— fetch config and the banner image above.gnome-extensions/— own Shell extensions plus maintained forks of third-party ones, seegnome-extensions/README.md.gdm/— login screen settings (greeter.dconf), applied withsudo gdm/apply.sh; GDM ignores the user's own dconf.scripts/— utility scripts.gamemode-tweaks.shlocks GPU clocks during games; it ischattr +ilocked because sudoers points at it directly.systemd/user/—nvpcf-unlock.service, the boot-time workaround that keeps the GPU from being throttled. Without it the machine loses ~70% of its GPU performance. Also a memory floor for the GNOME session, so the compositor is the last thing to be paged out, andbatlog.timer, a daily battery wear snapshot fordebug/battery/.system/— config that lives in/etc(zswap in place of zram, the session memory floor's system half, systemd-oomd, the open-file limit, the ufw firewall rules, a module blacklist), installed withsudo system/apply.sh, plusenabled-units.txt, the system services to enable.split-tunnel/— launchers that keep selected apps outside the Mullvad tunnel, linked into~/.localbysplit-tunnel/install.sh.git/— global git config and ignore list.backgrounds/— the wallpapergnome-settings.dconfpoints at.nvidia/— driver application profiles for~/.nv/nvidia-application-profiles-rc.d; lifts the CUDA stable-perf limit forgpu-screen-recorder.monitors.xml,user-dirs.dirs,xdg-terminals.list— session bits that are tedious to recreate by hand.gnome-settings.dconf— full dconf dump. This is where the actual GNOME look and behaviour lives; the dotfiles alone won't restore it.pkglist.txt/pkglist-aur.txt— explicitly installed packages (pacman -Qqen/pacman -Qqem).debug/— see below.
Xiaomi shipped broken ACPI tables and never updated the BIOS
(XMAAD6B0P1717, dated 2022-12-13). Several subsystems misbehave as a
result, and each one has its own investigation folder with documentation,
tooling and logs. Start at debug/README.md.
| Branch | Problem | Status |
|---|---|---|
debug/gpu/ |
RTX 2050 throttled to 16 W instead of 35 W | solved via a runtime SSDT workaround |
debug/battery/ |
~43% wear (57% health) after ~2.5 years, no charge limit available | open, logged daily |
debug/nvme/ |
130k power cycles reported at 6k power-on hours | closed — counter is fine |
Each branch keeps its own CSV log and a *check.sh tool. Negative results
and dead ends are kept on purpose — see the conventions in
debug/README.md.
main— the setup running on this machine (GNOME).hyprland— the previous Hyprland setup, with its own history and README.
~/.config is this repo's working tree, so switching branches there replaces
the live config. To read the other branch, use git show hyprland:<path>.
-
Clone into
~/.config: Back up your existing.configfirst.git clone git@github.com:afterallspace/dotfiles.git ~/.config -
Restore packages:
sudo pacman -S --needed - < ~/.config/pkglist.txt paru -S --needed - < ~/.config/pkglist-aur.txt
-
Restore GNOME settings:
dconf load / < ~/.config/gnome-settings.dconf
Then link the Shell extensions and split-tunnel launchers, restore the wallpaper and the NVIDIA driver profiles, build the SVG cursor theme GNOME 51 needs, hide the listed launchers from the app grid, apply the login screen and system settings, enable the system services and reboot:
~/.config/gnome-extensions/install.sh ~/.config/split-tunnel/install.sh install -Dm644 ~/.config/backgrounds/main.webp ~/.local/share/backgrounds/2026-07-19-17-18-09-IMG_20200810_195704.webp install -Dm644 -t ~/.nv/nvidia-application-profiles-rc.d ~/.config/nvidia/* ~/.config/scripts/bibata-scalable.py ~/.config/scripts/hide-apps.sh sudo ~/.config/gdm/apply.sh sudo ~/.config/system/apply.sh sudo systemctl enable $(cat ~/.config/system/enabled-units.txt)
-
Re-arm the GPU workaround — the service alone is not enough, it needs a root helper and a sudoers rule. Full procedure in
debug/gpu/OPERATIONS.md:systemctl --user enable --now nvpcf-unlock.service -
Re-arm the game-mode GPU lock —
gamemode.inirunsscripts/gamemode-tweaks.shthrough sudo, so it needs a sudoers rule, and the script has to stay immutable for that rule to be safe:echo 'afterall ALL=(root) NOPASSWD: /home/afterall/.config/scripts/gamemode-tweaks.sh start, /home/afterall/.config/scripts/gamemode-tweaks.sh stop' | sudo tee /etc/sudoers.d/gamemode-tweaks sudo chmod 440 /etc/sudoers.d/gamemode-tweaks sudo chattr +i ~/.config/scripts/gamemode-tweaks.sh
Every one of these cost hours. Full list in
debug/CLAUDE.md.
modprobe.ddoes not work for modules loaded from initramfs (nvidia,nvme_core) — use the kernel command line viaLINUX_OPTIONSin/etc/sdboot-manage.conf, thensudo sdboot-manage gen.dmesgis restricted (dmesg_restrict=1) — usejournalctl -k.nvidia-smi -plis blocked in the vBIOS.- Recursive
grep -rover/syswill peg every core for a very long time.
