Skip to content

Add MSI Titan GT77HX driver wiring and Cooler Boost after 30s sustained 85C - #12003

Open
andyholst wants to merge 1 commit into
omacom:quattrofrom
andyholst:feat/msi-titan-cooler-boost
Open

andyholst wants to merge 1 commit into
omacom:quattrofrom
andyholst:feat/msi-titan-cooler-boost

Conversation

@andyholst

@andyholst andyholst commented Sep 15, 2026 •

Copy link
Copy Markdown

Summary

Single commit 1d4815f3, rebased on upstream quattro. Closes #11583.

On MSI Titan GT77HX 13VI (and other MSI laptop families), Omarchy now:

  1. Installs and configures required hardware drivers
  2. Enables Cooler Boost only after CPU/GPU stay at or above 85C for more than 30 seconds, via a systemd watcher

Silent/auto EC fan curves never flip the Cooler Boost flag at any temperature. CoolerControl cannot PWM these fans (RPM-only), so the watcher flips the flag itself. Verified live on a GT77HX 13VI: the EC cooler_boost flag flips off -> on after 30s of sustained >=85C, and all four EC fans ramp to ~4,900 RPM.

Hardware

Component Detail
Model MSI Titan GT77HX 13VI
CPU Intel i9-13980HX (24C/32T)
GPU NVIDIA RTX 4090 Laptop (AD103M) — hybrid Optimus
Ethernet Killer E3000 (RTL8125B, 2.5GbE)
WiFi Intel Wi-Fi 6E (CNVi, not replaceable)
EC MSI EC via msi-ec-dkms-git
Boot Limine (UKI), not GRUB

What's Added

Detection Scripts (bin/)

  • omarchy-hw-msi — reads DMI IDs from $OMARCHY_DMI_ID_PATH (test stub) or /sys/class/dmi/id. Matches vendor "Micro-Star International Co., Ltd." + 14 laptop family names (Titan, Stealth, Raider, Vector, Crosshair, Summit, Creator, Modern, Katana, Cyborg, Pulse, Bravo, Alpha, Prestige). Exits 0 on MSI laptop, 1 otherwise. Exits 1 on desktop boards (MEG, MAG, MPG families without laptop markers).
  • omarchy-hw-msi-titan — hidden, narrow check for "Titan GT77HX" specifically. Gates the cooler boost watcher.

Install Script (install/hardware/msi.sh)

Runs from install/hardware/all.sh when omarchy-hw-msi returns 0.

  1. RTL8125B Ethernet — scans PCI devices via sysfs (OMARCHY_PCI_DEVICES_PATH) for vendor 0x10ec / device 0x8125 (avoids lspci which wakes suspended GPUs on hybrid laptops — see PR Avoid lspci in favor of sysfs #11259). Installs r8125-dkms and blacklists r8169 only when r8125 is actually loaded.
  2. msi-ec-dkms-git — enables EC sysfs (/sys/devices/platform/msi-ec) for Cooler Boost, fan curves, battery thresholds.
  3. CoolerControl — replaces thermald for fan management.
  4. Battery thresholds — start 60%, end 80% via msi-ec sysfs.
  5. nvidia-settings — NVIDIA DPMS config.

Cooler Boost Watcher (bin/omarchy-msi-cooler-boost-watch)

  • Daemon that polls msi-ec CPU/GPU temperature every 5s
  • ON only after CPU or GPU has been at or above 85C for more than 30 seconds — a short spike does not trigger it, and the sustain counter resets on any dip below 85C
  • OFF when both are at or below 70C
  • Hysteresis between the two thresholds prevents rapid toggling
  • CLI supports --once (single check), --decide <state> <cpu> <gpu> (unit-testable decision function)
  • Exits cleanly on non-Titan hardware

Systemd Unit (default/systemd/system/omarchy-msi-cooler-boost-watch.service)

  • Starts after multi-user.target
  • ConditionPathExists=/sys/devices/platform/msi-ec/cooler_boost — only on systems with msi-ec loaded
  • Env: MSI_COOLER_BOOST_ON_AT=85, MSI_COOLER_BOOST_OFF_AT=70, MSI_COOLER_BOOST_SUSTAIN=30, MSI_COOLER_BOOST_INTERVAL=5
  • Auto-restarts on failure

Tests (test/shell.d/)

  • hw-msi-test.sh (181 lines) — DMI detection across the 14 families, edge cases (family-only/name-only), office desktops rejected, install-script assertions, systemd unit thresholds
  • msi-cooler-boost-test.sh (167 lines) — decision logic (84C stays off, 85C turns on, 70C turns off, hysteresis, garbage temps), sustained-trigger behavior (6 polls at 86C do not enable; the 7th does; exactly 85C counts; the counter resets on a dip), non-Titan hardware exits without touching the EC, unit thresholds

What's NOT in This PR

  • RGB support — The Titan GT77HX uses a Cherry MX mechanical keyboard that msi-perkeyrgb does NOT support. The tool exits 0 but produces no lighting. RGB was explicitly removed from scope (see issue comments). If re-added, it must clearly state which models it works on (e.g., GE63/GE73 with 1038:1122).
  • MSI desktop boards — omarchy-hw-msi explicitly excludes MEG/MAG/MPG boards that lack laptop family markers in product_family/product_name.
  • Other MSI laptop families — Cooler Boost watcher is Titan GT77HX-only. Other MSI families (Stealth, Raider, etc.) get driver packaging only.

Testing

bash test/shell.d/msi-cooler-boost-test.sh   # 27 assertions — all pass
bash test/shell.d/hw-msi-test.sh             # 45 assertions — all pass

Verified on real GT77HX 13VI hardware (2026-09-16), 32-thread sustained load:

Event Time Detail
First >=85C t+13s CPU 85C+ under load
Cooler Boost ON t+44s 31s of sustained >=85C (7 consecutive 5s polls); journal: cooler_boost off -> on (cpu=91C gpu=51C)
Fan response — all four EC fans ~2,100 -> ~4,900 RPM (hwmon msi_wmi_platform)
Cooler Boost OFF t+74s first poll at/under 70C during cooldown; journal: cooler_boost on -> off (cpu=63C)

Service active + enabled; omarchy-hw-msi and omarchy-hw-msi-titan both exit 0 on this hardware; r8125 loaded with r8169 blacklisted; coolercontrold running with thermald disabled.

Detection for other MSI families (Stealth, Raider, etc.) and non-MSI rejection is covered by the stubbed DMI tests only — no other hardware was available to verify physically.

Related

@andyholst
andyholst force-pushed the feat/msi-titan-cooler-boost branch from 91a317a to 4e0ae8b Compare September 15, 2026 19:36
@andyholst andyholst changed the title Enable MSI Titan Cooler Boost at 85C Add MSI Titan GT77HX driver wiring and Cooler Boost at 85C Sep 15, 2026
@andyholst
andyholst force-pushed the feat/msi-titan-cooler-boost branch 3 times, most recently from 6113e63 to 0ac3e68 Compare September 16, 2026 00:06
…mp trigger

Wire MSI laptop drivers (Killer E3000/RTL8125B, msi-ec, CoolerControl,
nvidia-settings) into the hardware install path behind omarchy-hw-msi
detection, and add a Titan GT77HX watcher that enables the EC Cooler Boost
flag only after CPU/GPU stay at or above 85C for more than 30 seconds,
turning it off again at 70C. Matches omacom#11583: Extreme 100% at 85C and
Silent staying low until 70C.
@andyholst
andyholst force-pushed the feat/msi-titan-cooler-boost branch from 0ac3e68 to 1d4815f Compare September 16, 2026 00:52
@andyholst andyholst changed the title Add MSI Titan GT77HX driver wiring and Cooler Boost at 85C Add MSI Titan GT77HX driver wiring and Cooler Boost after 30s sustained 85C Sep 16, 2026
@omarchybot omarchybot added the enhancement New feature or request label Sep 27, 2026
@llstrk

llstrk commented Sep 27, 2026

Copy link
Copy Markdown

Automated AI review

Community review: Independent automated community review, unaffiliated with the Omarchy team, intended to help prepare PRs for their review.

Verified: the Cooler Boost watcher's decision logic matches the description, and both new tests pass at head (45 and 27 checks). The install path does not deliver the feature through Omarchy's own install flow, though. The RTL8125 scan never matches. Three of the packages cannot be installed by omarchy-pkg-add. thermald ends up enabled after the same all.sh run. The findings below are in order of impact.

RTL8125 scan in msi.sh never matches

install/hardware/msi.sh:14-15 reads the PCI IDs with $(< "$device/vendor" 2>/dev/null). Bash only treats $(< file) as a file read when the substitution has a single < redirection (can_optimize_cat_file in bash's builtins/evalstring.c). With the extra 2>/dev/null, it becomes an empty command and expands to nothing.

Sandboxed run with bash 5.3, using a fixture file containing 0x10ec and a fixture 10ec:8125 device:

$(< f)                         -> 0x10ec
$(< f 2>/dev/null)             -> (empty)
msi.sh loop, lines 11-20 as-is -> rtl8125b_found=false
same loop, 2>/dev/null removed -> rtl8125b_found=true

Impact: r8125-dkms is never installed and r8169 is never blacklisted on any machine. Even with the scan fixed, the blacklist is gated on lsmod | grep -q r8125. A freshly built DKMS module is not loaded during installation, so the blacklist branch is skipped there too.

Suggested change: drop the two 2>/dev/null (sysfs PCI devices always have vendor and device), or follow bin/omarchy-hw-nvidia (shopt -s nullglob and a plain $(< …)). A test that points OMARCHY_PCI_DEVICES_PATH at a fixture, as test/shell.d/hw-nvidia-test.sh does, would catch this. The same pattern appears in bin/omarchy-hw-laptop:13 (existing code, outside this PR). Its chassis-type fallback never matches either, though its lid-switch check still works.

The MSI packages cannot be installed, so the watcher is inert on a fresh install

  • bin/omarchy-pkg-add only runs pacman -S. r8125-dkms, msi-ec-dkms-git and coolercontrol are AUR-only. None of them is in Arch's official repositories or omacom/omarchy-pkgs.
  • None of the four new packages, including nvidia-settings, is listed in install/omarchy-other.packages. The ISO builder uses that list to stage packages for offline installs.
  • The ISO runs the hardware phase against that offline repository. A stubbed simulation of that flow (Titan DMI, nothing preinstalled) gave:
error: target not found: msi-ec-dkms-git  -> WARNING: Failed to install msi-ec-dkms-git
error: target not found: coolercontrol    -> WARNING: Failed to install coolercontrol
Unit file coolercontrold.service does not exist -> WARNING: Failed to enable coolercontrold
error: target not found: nvidia-settings  -> WARNING: Failed to install nvidia-settings
enabled at the end: omarchy-msi-cooler-boost-watch.service, thermald.service

The simulation modelled the offline repository as the package names in the two lists. r8125-dkms is missing from the output only because the scan never matches.

With network access, the three AUR packages still fail. /sys/devices/platform/msi-ec/cooler_boost comes only from the out-of-tree msi-ec driver. According to the Linux 7.2 source, the in-kernel msi-ec (built as a module in linux-omarchy) only adds battery thresholds. It has no cooler_boost attribute and no GT77HX firmware entry.

Impact: on a fresh install, the watcher unit is enabled but its ConditionPathExists never passes, unless the out-of-tree driver is installed some other way. Until then, Cooler Boost is not managed. The live verification in the PR body cannot have come from these install steps: omarchy-pkg-add cannot fetch AUR packages, and the r8125 branch never runs.

Suggested change: get msi-ec-dkms-git (and any other package still needed) into omarchy-pkgs first, then list it in install/omarchy-other.packages. The open PR #13181 routes its MSI DKMS driver through omarchy-pkgs first (omarchy-pkgs#623).

thermald ends up enabled after the same all.sh run

all.sh:3   msi.sh             -> systemctl disable --now thermald   (no-op on a fresh install)
all.sh:17  intel/thermald.sh  -> Intel model >= 42 and a battery (i9-13980HX qualifies)
                              -> omarchy-pkg-add thermald
                              -> systemctl enable thermald.service
end state: thermald enabled

A stubbed run confirmed this end state both on a fresh install and on a rerun where thermald was already enabled.

Impact: the PR's "coolercontrold running with thermald disabled" result is not what all.sh produces. Separately, disabling thermald on every Intel MSI laptop reverses the policy in intel/thermald.sh, so maintainers need to decide on it. The msi.sh comment says coolercontrold "talks to the EC directly and knows the MSI fan table". That contradicts the PR's own statement that CoolerControl cannot PWM these fans.

Suggested change: if thermald should stay off on these machines, make intel/thermald.sh skip them rather than undoing it later. Otherwise, drop the thermald and CoolerControl steps and keep the watcher.

Battery thresholds end at 70/80, not 60/80

msi-ec stores one charge limit. Writing charge_control_start_threshold sets the end to value + 10, and reading it returns end − 10 (msi-ec.c, charge_control_start_threshold_store/_show; the in-kernel driver uses the same single register). The step writes start 60 and then end 80. It runs only while the battery is Discharging and only targets BAT1, although msi-ec attaches the attributes to whichever battery exists.

Impact: when the step runs, the thresholds end at start 70 / end 80. During a normal install on AC power it is skipped, and machines whose battery is not BAT1 are skipped too.

Suggested change: write only the end threshold (80), note the fixed 10% gap, and find the battery the same way omarchy-battery-present does. Not verified on hardware.

No migration for existing installs

msi.sh runs only through omarchy-apply-hardware, which runs during ISO setup or when invoked manually. omarchy update does not call it, and the PR adds no migration.

Impact: existing GT77HX owners get the new commands but no enabled watcher.

Suggested change: add a migration that sources msi.sh, as recent hardware additions do (migrations/1787666837.sh, migrations/1788862626.sh).

Watcher: manual Cooler Boost is switched off, and unreadable sensors read as 0C

Sandboxed --once runs against a fixture EC tree:

  • With cooler_boost=on and both sensors at or below 70C, the next poll writes off. The watcher cannot tell its own "on" from someone else's.
  • A missing or unreadable temperature file is read as 0. With the CPU sensor file missing and the GPU at 60C, boost went on -> off (cpu=0C gpu=60C). The failure was simulated with a missing file and with a directory in its place, not with a real EC I/O error.

Impact: a Cooler Boost switched on by the user or another tool is turned off within one interval. A read failure on the hot sensor, while the other reads 70C or below, switches boost off and restarts the 30 s window.

Suggested change: keep the current state when a sensor cannot be read. Only switch off a boost that the watcher itself switched on, for example by recording that in a state file and reconciling it on start, since /run does not survive a reboot.

omarchy-hw-msi accepts some desktops and misses common laptop lines

Checked against real MSI DMI strings from public linuxhw dumps:

DMI product (family) Device Result
Creator Z590 P100X (Desktop) desktop accepted
Modern ADL-P AM242 (AIO) all-in-one accepted
GF63 8RC, Thin GF63 12HW, Sword 15 A11UD (GF) laptop rejected
MEG Z490 Trident X, MAG Z590 Codex X5 (Desktop) desktop rejected (correct)

msi-ec also supports GF75 Thin, GP/GL Leopard and Sword firmwares, which the family list misses. On real MSI laptops, product_family is a series name (GT for the Titan GT77HX, or GF, GS, GE, Modern, Prestige), not the full model line used in the test fixtures.

Impact: some MSI desktops and all-in-ones get the laptop driver setup, and common laptop lines (GF, Thin, Sword, Leopard) get none of it.

Suggested change: match the MSI vendor plus the existing omarchy-hw-laptop check instead of a family list. omarchy-hw-msi-titan matches the real Titan GT77HX 13VH string correctly.

Optional test improvement: diagnostic mutants run against the new tests show which changes still pass. Removing the watcher's Titan gate passes both tests. So does ignoring GPU temperature in the polling path, removing the thermald disable or the watcher enable from msi.sh, or pointing the unit's ExecStart at a missing path. The install assertions grep msi.sh text rather than running it, which is also how the RTL8125 scan got through. docs/testing.md describes the expected approach: stub sudo and the helpers on PATH, run the real script, and assert on the call log and the files it writes.

Smaller notes:

  • install/ leaf scripts are sourced by run_logged and intentionally have no shebang (agents/skills/install-scripts.md). msi.sh is also the only install/hardware leaf that sets set -euo pipefail. With pipefail, lsmod | grep -q … can report failure when lsmod gets SIGPIPE. This was shown with a stub lsmod; how often the real one hits it was not tested. [[ -d /sys/module/r8125 ]] avoids the pipe.
  • /etc/X11/xorg.conf.d/10-nvidia-dpms.conf contains no DPMS option, despite its name. Omarchy runs Hyprland, and SDDM runs on Wayland, so the file only affects an Xorg server, which stock Omarchy does not start.

Verified:

  • Watcher logic. At the default 5 s interval, boost stays off for six polls at or above 85C and turns on at the 7th. Exactly 85C counts, and a dip below 85C resets the counter. At or below 70C it turns off, and 71 to 84C holds the current state. GPU-only heat also turns boost on. A failed EC write is reported and --once exits 1, while the daemon keeps polling.
  • msi-ec interface. The sysfs files the watcher uses match the out-of-tree msi-ec driver: cooler_boost on/off, and integer cpu/ and gpu/realtime_temperature. The GT77HX firmwares 17Q2IMS1.107/.10D are in its supported table.
  • Unit file. After=multi-user.target together with WantedBy=multi-user.target does not create an ordering cycle. ExecStart and the $OMARCHY_PATH/default/... source path match how the Omarchy packages install files.
  • Repository checks. The new commands pass bin-style-test.sh, the test/cli metadata lint and privileged-heredoc-test.sh.

Review information

Test scope: reviewed at head 1d4815f. None of the changes on current quattro affect these findings (the package and hardware-match helpers only gained -- separators). Source review of the changed files, the hardware install flow, the msi-ec driver (out-of-tree and in-kernel Linux 7.2), AUR and Arch package metadata, the omarchy-pkgs and omarchy-iso build inputs, and public MSI DMI dumps. The PR tests, related repository tests, the watcher and a stubbed run of msi.sh followed by intel/thermald.sh were executed in a sandbox with fixture DMI, PCI and EC trees and stubbed sudo, pacman, systemctl and lsmod. No MSI hardware was available, so real EC behavior, boot-time unit start and the real lsmod SIGPIPE rate are untested.

AI process: Opus 5.5 Medium coordination and synthesis, Opus 5.5 Xhigh technical review and final fact check, GPT 6 Sol Xhigh search for related issues, Opus 5.5 Medium editorial check.

Opt out: To stop receiving these reviews, reply to this comment saying so.

@jandrusk

Copy link
Copy Markdown

Thanks for the detailed write-up. On top of the install-path points in the Sep 27 review, two policy points for whoever decides scope:

  • install/hardware/msi.sh sets charge thresholds of 60/80% on every MSI laptop omarchy-hw-msi matches (14 families), and only when the machine happens to be discharging during install. That's a user-visible battery policy change that depends on install-time state. I'd scope it to the Titan (like the watcher), make it opt-in, or leave it out.
  • Same for disabling thermald on all MSI families. The watcher is gated on GT77HX, but this part isn't.

Could you narrow the install script to the hardware you verified on, or say why the wider match is safe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MSI Titan GT77HX: driver packaging and Cooler Boost at 85C

4 participants