feat: Power-off fix for the Steam Machine; the kernel pin is optional

Kernels >= 7.2 keep the firmware's S4/S5 wake bit on GPIO pin 18, so the
Steam Machine starts again right after powering off. Steam Machine
support now builds a DKMS module (patches/steamify-fremont-poweroff.c)
that clears it before power-off, for every kernel. The kernel pin is no
longer ticked by default. Module sources and patches move to patches/,
embedded by the single-file build.
This commit is contained in:
theupriser committed 2026-09-27 12:13:23 +02:00
1 parent b2c4a0a00a
commit 443dbcdfb8
17 files changed
+297 -41

No files matched your search

+17
View File
@@ -31,6 +31,23 @@ version="v$(grep -oP '^VERSION=\K.*' "$entry"), $(git describe --always --dirty
sed -e '1{/^#!/d}' -e '/^# Sourced by steamify.sh/d' "lib/$lib.sh"
echo
done
# patches/ embedded: replaces lib/common.sh's patch_file, which reads
# them from the checkout.
echo "# ----- patches/ -----"
echo "patch_file() {"
echo ' case "$1" in'
for f in patches/*; do
[[ "$f" == patches/README.md ]] && continue
grep -q '^STEAMIFY_PATCH_EOF$' "$f" && { echo "bundle: $f contains the heredoc delimiter" >&2; exit 1; }
echo " $(basename "$f")) cat << 'STEAMIFY_PATCH_EOF'"
cat "$f"
echo "STEAMIFY_PATCH_EOF"
echo " ;;"
done
echo ' *) return 1 ;;'
echo ' esac'
echo "}"
echo
echo "# ----- steamify.sh -----"
echo "main() {"
# Everything after the source loop is the entry point's body.
+2 -2
View File
@@ -6,7 +6,7 @@
# curl -fsSL https://github.com/theupriser/steamify-cachyos/releases/latest/download/steamify.sh | bash
# curl -fsSL https://github.com/theupriser/steamify-cachyos/releases/download/latest/steamify.sh | bash
# Each release also has the app (v2): steamify-app.tar.gz (ui/, steamify.sh,
# lib/, the icon) and its launcher, run with:
# lib/, patches/, the icon) and its launcher, run with:
# curl -fsSL https://github.com/theupriser/steamify-cachyos/releases/latest/download/steamify-app.sh | bash
# A push to feat/v2-ui (the app, not released yet) updates the pre-release
# v2-ui-preview instead, whose launcher gets that build:
@@ -36,7 +36,7 @@ jobs:
.github/tools/bundle.sh dist/steamify.sh
# The app: sources, not the single-file build (its backend mode runs
# steamify.sh from its own folder).
tar -czf dist/steamify-app.tar.gz steamify.sh lib ui assets/steam-gaming-settings.svg LICENSE.md
tar -czf dist/steamify-app.tar.gz steamify.sh lib patches ui assets/steam-gaming-settings.svg LICENSE.md
cp ui/steamify-app.sh dist/steamify-app.sh
- name: Check
+14
View File
@@ -15,6 +15,10 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
- `steamify.sh` - the only entry point. Pre-flight checks,
sources `lib/*.sh`, runs the menu and applies the plan. No component
logic here.
- `patches/` - kernel module sources and patches the scripts build or
apply, never inline in the shell code. Read them with `patch_file
<name>` (`lib/common.sh`, from the checkout); the bundle embeds every file
in `patches/` and overrides `patch_file`. Add new ones to its README.
- `lib/*.sh` - one file per responsibility, each defining functions only
(no top-level side effects besides constants). See the table in
`TECHNICAL.md`.
@@ -204,6 +208,16 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
kernel only pairs that with a named lookup ("Port C") when the CEC driver
registered first, which never happens since amdgpu loads from the
initramfs. Without it `/dev/cec0` exists but stays at `f.f.f.f`.
- Power-off fix (`lib/fremont-poweroff.sh`, part of `machine`): kernels
>= 7.2 keep the firmware's S4/S5 wake bit on GPIO pin 18, so the Steam
Machine boots again right after powering off (Valve's kernel clears it at
probe, not for upstream). The DKMS module `steamify-fremont-poweroff`
(`patches/steamify-fremont-poweroff.c`) clears it in a power-off-prepare
handler, for every kernel. It made the kernel pin optional (`kpin` is in
`NO_PRESELECT`, no longer ticked with `machine`). `machine_repair` ticks
`machine` for setups without it. CachyOS's `linux-cachyos` is clang-built,
`-bore` GCC-built: let DKMS pick the compiler, never pass `LLVM=1`. Test
shutdown on the real machine for every new major kernel.
- `Relogin=true` means a gamescope that fails to start is relaunched in a
tight loop; keep that in mind when changing session handling.
+17
View File
@@ -5,6 +5,23 @@ All notable changes, per version and per commit. Versions follow
`steamify.sh`. Versions before 0.7.0 were numbered afterwards,
one per merged pull request.
## 2.2.0 - 2026-09-27
- **feat: Power-off fix for the Steam Machine; the kernel pin is optional**
- With kernels 7.2 and newer the Steam Machine started again right after
shutting down: Linux 7.2 keeps the wake bit the firmware sets on GPIO
pin 18, which Valve's own kernel clears in a patch that won't reach
CachyOS. Steam Machine support now builds a small module with DKMS for
every kernel that clears it right before power-off. Tested with
CachyOS 7.2.8: stays off, and without the module it rebooted.
- The kernel pin is no longer ticked with Steam Machine support or on a
first run; it stays available (HDMI refresh boost needs it). An
existing pin is kept. Steam Machine support from before 2.2.0 is
ticked in the menu to add the fix.
- Module sources and patches live in `patches/` instead of inside the
shell code; the single-file build embeds them. The Steam Machine CEC
driver change is now `patches/cros-ec-cec-single-port.patch`.
## 2.1.0 - 2026-09-26
- **feat(ui): Manage button for HDMI refresh boost**
+7 -5
View File
@@ -43,11 +43,13 @@ What Steamify can do on a Valve Steam Machine:
TV's remote, and the TV turns on and off with the Steam Machine
([details](TECHNICAL.md#hdmi-cec)).
- **Steam Machine support** - the front **LED bar** works, Steam's
**hardware settings** (fan, performance) work, and the power
button puts it to sleep like a console.
- **Pin the kernel to 7.1.6-1** - on by default: with newer CachyOS kernels
the Steam Machine reboots instead of shutting down. Untick it once CachyOS
fixes that. The kernel comes from its own
**hardware settings** (fan, performance) work, the power button puts it
to sleep like a console, and **shutting down really turns it off**, also
with the newest CachyOS kernel
([details](TECHNICAL.md#power-off-fix-steam-machine)).
- **Pin the kernel to 7.1.6-1** - optional, off by default: stays on an
older kernel (HDMI refresh boost needs it). It used to be needed for
shutting down; the power-off fix above covers that now. The kernel comes from its own
[release](https://github.com/theupriser/steamify-cachyos/releases/tag/kernel-7.1.6-1),
checked against CachyOS's signature
([details](TECHNICAL.md#kernel-pin-steam-machine)).
+32 -5
View File
@@ -208,11 +208,36 @@ upset CEC for the TV's other devices
Turning it off removes the packages again (`linuxconsole` only if the
wizard installed it).
## Power-off fix (Steam Machine)
With kernels 7.2 and newer a Steam Machine starts again right after
powering off. Linux 7.2 stopped clearing the S4/S5 wake bits at probe
(`pinctrl-amd: Don't clear S4 wake bits at probe`), and the firmware leaves
that bit set on GPIO pin 18 (`_SB.PCI0.GPP6`). Valve's own kernel
(`linux-neptune-72`) clears it at probe on Fremont, in a patch marked not
for upstream ("until the firmware is fixed"), so CachyOS and mainline won't
get it.
Steam Machine support builds a small module with DKMS for every installed
kernel, `steamify-fremont-poweroff` (source in
[`patches/steamify-fremont-poweroff.c`](patches/steamify-fremont-poweroff.c)).
It only loads on Fremont (DMI board name) and touches one register: right
before power-off (a `SYS_OFF_MODE_POWER_OFF_PREPARE` handler, after the
drivers have shut down) it clears that pin's S4/S5 wake bit. On a kernel
that already clears it, it does nothing. It logs the pin's state at load:
`dmesg | grep 'GPIO 18'`; `/sys/kernel/debug/gpio` shows the S4/S5 column.
Tested on a Steam Machine with `linux-cachyos-bore` 7.2.8: it stayed off
three times in a row, and rebooted right away with the module unloaded.
Steam Machine support set up before 2.2.0 has no power-off fix; the menu
ticks it, so a normal run adds it.
## Kernel pin (Steam Machine)
With CachyOS kernels newer than 7.1.6 a Steam Machine reboots instead of
shutting down. The **Pin the kernel** sub-option (ticked along with Steam
Machine support) installs `linux-cachyos` and `linux-cachyos-headers`
With CachyOS kernels newer than 7.1.6 a Steam Machine rebooted instead of
shutting down; the power-off fix above handles that now, so the pin is
optional. The **Pin the kernel** sub-option (off by default; HDMI refresh
boost needs it) installs `linux-cachyos` and `linux-cachyos-headers`
7.1.6-1 and adds them to `IgnorePkg` in `/etc/pacman.conf`, so updates skip
them. DKMS builds the LED driver for it; restart to boot it.
@@ -356,8 +381,10 @@ immediately, which can turn into a loop - see
| `lib/bios.sh` | Update BIOS (Steam Machine, opt-in): current/newest version, double confirmation, fwupd |
| `lib/cec.sh` | HDMI-CEC: Valve's `cecd` and friends from its `holo` repository |
| `lib/steam-machine.sh` | Steam Machine support: LED driver, LED access, steamos-manager; kernel pin |
| `lib/hdmi-refresh.sh` | HDMI refresh boost (Steam Machine, pinned kernel): EDID over DDC, calculated steps, live test, `drm.edid_firmware` |
| `.github/tools/bundle.sh` | Builds the single-file version (`dist/steamify.sh`) |
| `lib/fremont-poweroff.sh` | Steam Machine support: the power-off fix (DKMS module from `patches/`) |
| `lib/hdmi-refresh.sh` | HDMI refresh boost (Steam Machine, pinned kernel): EDID over DDC, calculated steps, live test, per-display EDID hotplug script |
| `patches/` | Module sources and patches the scripts build or apply (`patch_file`); see its README |
| `.github/tools/bundle.sh` | Builds the single-file version (`dist/steamify.sh`), with `patches/` embedded |
| `.github/workflows/bundle.yml` | Builds and checks it on every push; publishes it on `main` |
The single-file version is generated: on every push to `main`, GitHub
+4 -9
View File
@@ -60,8 +60,8 @@ cec_reload_driver() {
cec_driver_enable() {
detect_valve_fremont || return 0
local tmp k
if ! pacman -Q dkms >/dev/null 2>&1; then
sudo pacman -S --needed --noconfirm dkms || { err "Installing dkms failed."; return 1; }
if ! pacman -Q dkms patch >/dev/null 2>&1; then
sudo pacman -S --needed --noconfirm dkms patch || { err "Installing dkms failed."; return 1; }
fi
install_kernel_headers || return 1
tmp="$(mktemp -d)"
@@ -72,13 +72,8 @@ cec_driver_enable() {
err "Downloading Valve's CEC driver failed (or its checksum didn't match)."
return 1
fi
# amdgpu registers its HDMI notifier without a port name, which only
# matches the driver's named lookup ("Port C") if the driver loaded
# first; amdgpu loads from the initramfs, so it never does. With a
# single CEC port, look it up by device alone.
sed -i 's/cec_notifier_cec_adap_register(hdmi_dev, conns\[port_num\],/cec_notifier_cec_adap_register(hdmi_dev, conns[1] ? conns[port_num] : NULL,/' \
"$tmp/cros-ec-cec.c"
grep -q 'conns\[1\] ? conns\[port_num\] : NULL' "$tmp/cros-ec-cec.c" ||
# So it finds amdgpu's HDMI port (see the patch for why).
patch_file cros-ec-cec-single-port.patch | patch -s -d "$tmp" -p1 ||
{ rm -rf "$tmp"; err "Patching Valve's CEC driver failed."; return 1; }
echo 'obj-m += cros-ec-cec.o' >"$tmp/Makefile"
printf '%s\n' "# Written by Steamify: Valve's cros_ec_cec, which knows the Steam Machine." \
+3
View File
@@ -6,6 +6,9 @@ c_reset="\033[0m"; c_bold="\033[1m"; c_green="\033[32m"; c_yellow="\033[33m"; c_
info() { echo -e "${c_cyan}[INFO]${c_reset} $*"; }
ok() { echo -e "${c_green}[OK]${c_reset} $*"; }
# patch_file <name>: a file from patches/ (module sources, patches). The
# single-file build replaces this with one that has them embedded.
patch_file() { cat "$SCRIPT_DIR/patches/$1"; }
warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; }
err() { echo -e "${c_red}[ERROR] $*${c_reset}" >&2; }
ask_yn() {
+57
View File
@@ -0,0 +1,57 @@
#!/bin/bash
# Part of "Steam Machine support": the Steam Machine powers off instead of
# booting up again, on every kernel. Since Linux 7.2 ("pinctrl-amd: Don't
# clear S4 wake bits at probe") the S4/S5 wake bit the firmware leaves set
# on GPIO pin 18 stays set, and the machine starts again right after
# powering off (the reason for the kernel pin). Valve's kernel clears it at
# probe on Fremont, in a patch not meant for upstream, so CachyOS won't get
# it. A small module (patches/steamify-fremont-poweroff.c) clears it right
# before power-off; DKMS builds it for every kernel. On kernels that clear it themselves it does nothing.
# Sourced by steamify.sh; not meant to be run on its own.
POWEROFF_DKMS_NAME=steamify-fremont-poweroff
POWEROFF_DKMS_VER=1
POWEROFF_DKMS_SRC="/usr/src/$POWEROFF_DKMS_NAME-$POWEROFF_DKMS_VER"
POWEROFF_MODULES_LOAD=/etc/modules-load.d/steamify-fremont-poweroff.conf
poweroff_fix_installed() { [[ -f "$POWEROFF_DKMS_SRC/dkms.conf" && -f "$POWEROFF_MODULES_LOAD" ]]; }
poweroff_fix_enable() {
detect_valve_fremont || return 0
local tmp k
if ! pacman -Q dkms >/dev/null 2>&1; then
sudo pacman -S --needed --noconfirm dkms || { err "Installing dkms failed."; return 1; }
fi
install_kernel_headers || return 1
tmp="$(mktemp -d)"
patch_file "$POWEROFF_DKMS_NAME.c" > "$tmp/$POWEROFF_DKMS_NAME.c"
echo "obj-m += $POWEROFF_DKMS_NAME.o" >"$tmp/Makefile"
printf '%s\n' "# Written by Steamify: the Steam Machine powers off instead of booting up again." \
"PACKAGE_NAME=\"$POWEROFF_DKMS_NAME\"" "PACKAGE_VERSION=\"$POWEROFF_DKMS_VER\"" \
"BUILT_MODULE_NAME[0]=\"$POWEROFF_DKMS_NAME\"" 'DEST_MODULE_LOCATION[0]="/updates/dkms"' \
'AUTOINSTALL="yes"' >"$tmp/dkms.conf"
sudo dkms remove "$POWEROFF_DKMS_NAME/$POWEROFF_DKMS_VER" --all >/dev/null 2>&1
sudo rm -rf "$POWEROFF_DKMS_SRC"
sudo install -d "$POWEROFF_DKMS_SRC" &&
sudo install -m644 "$tmp"/{"$POWEROFF_DKMS_NAME.c",Makefile,dkms.conf} "$POWEROFF_DKMS_SRC/"
rm -rf "$tmp"
sudo dkms add "$POWEROFF_DKMS_NAME/$POWEROFF_DKMS_VER" >/dev/null ||
{ err "Adding the power-off fix to DKMS failed."; return 1; }
for k in /usr/lib/modules/*/build; do
k="$(basename "$(dirname "$k")")"
info "Building the power-off fix for $k..."
sudo dkms install "$POWEROFF_DKMS_NAME/$POWEROFF_DKMS_VER" -k "$k" >/dev/null ||
warn "Building the power-off fix for $k failed; with that kernel it may start again after shutting down."
done
echo "$POWEROFF_DKMS_NAME" | sudo tee "$POWEROFF_MODULES_LOAD" >/dev/null
sudo modprobe "$POWEROFF_DKMS_NAME" 2>/dev/null
return 0
}
poweroff_fix_disable() {
sudo rm -f "$POWEROFF_MODULES_LOAD"
sudo modprobe -r "$POWEROFF_DKMS_NAME" 2>/dev/null
[[ -d "$POWEROFF_DKMS_SRC" ]] || return 0
sudo dkms remove "$POWEROFF_DKMS_NAME/$POWEROFF_DKMS_VER" --all >/dev/null 2>&1
sudo rm -rf "$POWEROFF_DKMS_SRC"
}
+6 -4
View File
@@ -16,7 +16,7 @@ declare -A PARENT=([boot]=gaming [kpin]=machine [hdmi]=machine [bios]=machine)
# upset other devices on the TV, even on SteamOS), except on a Steam Machine,
# which has CEC like on SteamOS. HDMI refresh boost needs someone at the
# screen to confirm each step.
NO_PRESELECT=(boot cec hdmi)
NO_PRESELECT=(boot cec kpin hdmi)
declare -A LABEL=(
[gaming]="SteamOS conversion: boot into gaming mode, Steam on the desktop"
@@ -27,7 +27,7 @@ declare -A LABEL=(
[launcher]="Steamify shortcut: the app on the desktop, Steamify Terminal in the launcher"
[cec]="HDMI-CEC: use Steam with the TV remote, TV on/off with the PC (experimental)"
[machine]="Steam Machine support: LED bar driver, hardware settings in Steam"
[kpin]="Pin the kernel to $PINNED_KERNEL_VER (fixes rebooting after shutdown)"
[kpin]="Pin the kernel to $PINNED_KERNEL_VER (optional, stays on an older kernel)"
[hdmi]="HDMI refresh boost: highest refresh your HDMI display runs"
[bios]="Update BIOS"
)
@@ -72,6 +72,8 @@ detect_components() {
done
# HDMI-CEC set up by an older version: tick it, so a normal run fixes it.
component_available cec && cec_repair && WANTED[cec]=1
# Steam Machine support from before 2.2.0 lacks the power-off fix.
component_available machine && machine_repair && WANTED[machine]=1
# The terminal-only Steamify shortcut from before 2.0.1: tick it, so a
# normal run replaces it with the app.
launcher_repair && WANTED[launcher]=1
@@ -96,8 +98,8 @@ toggle_component() {
if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[single]=0; WANTED[boot]=0; fi
# Where to boot to is part of the conversion, too.
if [[ "$c" == boot && "${WANTED[boot]}" == 1 ]]; then WANTED[gaming]=1; fi
# The kernel pin is opt-out: ticked along with Steam Machine support.
if [[ "$c" == machine ]]; then WANTED[kpin]=${WANTED[machine]}; fi
# The kernel pin is opt-in (the power-off fix made it optional).
if [[ "$c" == machine && "${WANTED[machine]}" == 0 ]]; then WANTED[kpin]=0; fi
if [[ "$c" == kpin && "${WANTED[kpin]}" == 1 ]]; then WANTED[machine]=1; fi
# HDMI refresh boost and the BIOS update sit under Steam Machine support;
# the boost also needs the pinned kernel (newer kernels don't need it).
+19 -8
View File
@@ -1,6 +1,7 @@
#!/bin/bash
# "Steam Machine support" menu item, only on Valve Fremont hardware: the
# front LED bar driver, LED access for Steam, and steamos-manager.
# front LED bar driver, LED access for Steam, steamos-manager, and the
# power-off fix (lib/fremont-poweroff.sh).
# Sourced by steamify.sh; not meant to be run on its own.
detect_valve_fremont() {
@@ -14,8 +15,8 @@ detect_valve_fremont() {
[[ "$vendor" == "OEM" && "$product" == "F7F" ]]
}
# Kernel pinned on a Steam Machine: with newer linux-cachyos releases it
# reboots instead of shutting down. The packages are kept in
# Kernel pinned on a Steam Machine (optional): newer linux-cachyos releases
# rebooted it instead of shutting down, which the power-off fix now handles. The packages are kept in
# PINNED_KERNEL_DIR, so re-applying (or reinstalling after an update slipped
# through) needs no download.
PINNED_KERNEL_VER="7.1.6-1"
@@ -334,13 +335,13 @@ reload_powerdevil() {
kernel_overview() {
# Per installed kernel: headers (needed to build DKMS modules), the
# in-kernel Steam controller driver, and, on a Steam Machine, whether the
# LED driver is built for it. Printed in the menu so it's easy to verify
# LED driver and the power-off fix are built for it. Printed in the menu so it's easy to verify
# a kernel update or a newly added kernel got everything.
local mark="${c_green}yes${c_reset}" miss="${c_red}no ${c_reset}" leds=false
detect_valve_fremont && command -v dkms >/dev/null 2>&1 && leds=true
local kdir k pkg headers hid led running line
local kdir k pkg headers hid led off running line
local legend="> = running; controller = Steam controller driver"
[[ "$leds" == true ]] && legend+=", LEDs = LED bar driver built"
[[ "$leds" == true ]] && legend+=", LEDs = LED bar driver built, power-off = power-off fix built"
echo -e " ${c_bold}Kernels${c_reset} ($legend)"
for kdir in /usr/lib/modules/*/; do
k="$(basename "$kdir")"
@@ -352,7 +353,8 @@ kernel_overview() {
line="$(printf '%-23s %-18s headers %b controller %b' "$k" "$pkg" "$headers" "$hid")"
if [[ "$leds" == true ]]; then
led="$miss"; dkms status -k "$k" leds-valve-dkms 2>/dev/null | grep -q installed && led="$mark"
line+="$(printf ' LEDs %b' "$led")"
off="$miss"; dkms status -k "$k" "$POWEROFF_DKMS_NAME" 2>/dev/null | grep -q installed && off="$mark"
line+="$(printf ' LEDs %b power-off %b' "$led" "$off")"
fi
echo -e " ${running}${line}"
done
@@ -369,7 +371,13 @@ kernel_overview() {
machine_available() { detect_valve_fremont; }
machine_status() {
pacman -Qi leds-valve-dkms-git >/dev/null 2>&1 && pacman -Qi steamos-manager >/dev/null 2>&1
pacman -Qi leds-valve-dkms-git >/dev/null 2>&1 && pacman -Qi steamos-manager >/dev/null 2>&1 &&
poweroff_fix_installed
}
# Set up before 2.2.0: no power-off fix yet; the menu ticks it to add it.
machine_repair() {
pacman -Qi leds-valve-dkms-git >/dev/null 2>&1 && pacman -Qi steamos-manager >/dev/null 2>&1 &&
! poweroff_fix_installed
}
machine_enable() {
@@ -381,6 +389,8 @@ machine_enable() {
ensure_aur_helper || { warn "Couldn't set up an AUR helper automatically. Install yay or paru, then run the wizard again."; return 1; }
install_valve_led_driver || { warn "LED driver setup ran into a problem - see errors above."; return 1; }
install_headers_boot_check
info "Installing the power-off fix (the machine stays off after shutting down)..."
poweroff_fix_enable || { err "Installing the power-off fix failed."; return 1; }
# The LED files are root-only. Steam runs as the user; let it write them
# in case it drives the bar directly (Valve's own privileged-write helper
@@ -424,6 +434,7 @@ machine_disable() {
sudo udevadm control --reload
sudo modprobe -r leds-valve 2>/dev/null
sudo pacman -Rns --noconfirm leds-valve-dkms-git 2>/dev/null
poweroff_fix_disable
krevert machine
reload_powerdevil
sudo systemctl disable ensure-kernel-headers.service 2>/dev/null
+10
View File
@@ -0,0 +1,10 @@
# Patches and extra sources
Files Steamify builds or applies, kept out of the shell code so they can be
read and reviewed on their own. `lib/*.sh` reads them with `patch_file
<name>`; the single-file build (`.github/tools/bundle.sh`) embeds them.
| File | Used by | What |
|---|---|---|
| `steamify-fremont-poweroff.c` | `lib/fremont-poweroff.sh` (Steam Machine support) | Kernel module (DKMS): clears GPIO 18's S4/S5 wake bit before power-off, so the Steam Machine stays off on kernels 7.2 and newer |
| `cros-ec-cec-single-port.patch` | `lib/cec.sh` (HDMI-CEC) | Makes Valve's Steam Machine CEC driver find amdgpu's HDMI port |
+21
View File
@@ -0,0 +1,21 @@
Steam Machine CEC: find amdgpu's HDMI port with a single CEC port.
amdgpu registers its HDMI notifier without a port name, which only matches
the driver's named lookup ("Port C") if the CEC driver loaded first; amdgpu
loads from the initramfs, so it never does and /dev/cec0 stays at f.f.f.f.
With a single CEC port, look the notifier up by device alone.
Applies to Valve's drivers/media/cec/platform/cros-ec/cros-ec-cec.c
(evlaV/linux-integration 10c8c880, see CEC_DRIVER_URL in lib/cec.sh).
--- a/cros-ec-cec.c
+++ b/cros-ec-cec.c
@@ -485,7 +485,7 @@
goto out_probe_adapter;
}
- port->notify = cec_notifier_cec_adap_register(hdmi_dev, conns[port_num],
+ port->notify = cec_notifier_cec_adap_register(hdmi_dev, conns[1] ? conns[port_num] : NULL,
port->adap);
if (!port->notify) {
ret = -ENOMEM;
+80
View File
@@ -0,0 +1,80 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Steam Machine (Fremont): power off instead of booting up again.
*
* Since Linux 7.2 ("pinctrl-amd: Don't clear S4 wake bits at probe") the
* S4/S5 wake bit the firmware leaves set on GPIO pin 18 (_SB.PCI0.GPP6)
* stays set, and the machine starts again right after powering off.
* Valve's kernel clears that bit at probe on Fremont (not for upstream);
* this does the same right before power-off, for kernels without it.
*/
#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/dmi.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#define FREMONT_GPP6_PIN 18
#define WAKE_CNTRL_OFF_S4 15
static void __iomem *pin_reg;
static struct sys_off_handler *handler;
static int fremont_poweroff_prepare(struct sys_off_data *data)
{
u32 v = readl(pin_reg);
if (v & BIT(WAKE_CNTRL_OFF_S4))
writel(v & ~BIT(WAKE_CNTRL_OFF_S4), pin_reg);
return NOTIFY_DONE;
}
static int __init fremont_poweroff_init(void)
{
struct acpi_device *adev;
struct device *dev;
struct resource *res;
u32 v;
if (!dmi_match(DMI_BOARD_NAME, "Fremont"))
return -ENODEV;
adev = acpi_dev_get_first_match_dev("AMDI0030", NULL, -1);
if (!adev)
return -ENODEV;
dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev);
acpi_dev_put(adev);
if (!dev)
return -ENODEV;
res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0);
put_device(dev);
if (!res || resource_size(res) < (FREMONT_GPP6_PIN + 1) * 4)
return -ENODEV;
/* pinctrl-amd owns the region; only this one register is touched. */
pin_reg = ioremap(res->start + FREMONT_GPP6_PIN * 4, 4);
if (!pin_reg)
return -ENOMEM;
v = readl(pin_reg);
pr_info("GPIO %d register 0x%08x, S4/S5 wake %s\n", FREMONT_GPP6_PIN, v,
v & BIT(WAKE_CNTRL_OFF_S4) ? "set (cleared at power-off)" : "clear");
handler = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF_PREPARE,
SYS_OFF_PRIO_DEFAULT, fremont_poweroff_prepare, NULL);
if (IS_ERR(handler)) {
iounmap(pin_reg);
return PTR_ERR(handler);
}
return 0;
}
static void __exit fremont_poweroff_exit(void)
{
unregister_sys_off_handler(handler);
iounmap(pin_reg);
}
module_init(fremont_poweroff_init);
module_exit(fremont_poweroff_exit);
MODULE_DESCRIPTION("Steam Machine: clear GPIO 18's S4 wake bit before power-off");
MODULE_LICENSE("GPL");
MODULE_ALIAS("dmi:*:rnFremont:*");
+2 -2
View File
@@ -15,11 +15,11 @@
set -uo pipefail
# Release version, see CHANGELOG.md.
VERSION=2.1.0
VERSION=2.2.0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for lib in common state packages login-manager single-user steam-desktop steam-machine hdmi-refresh cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu backend; do
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff hdmi-refresh cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu backend; do
# shellcheck source=/dev/null
source "$SCRIPT_DIR/lib/$lib.sh"
done
+5 -5
View File
@@ -67,10 +67,10 @@ ApplicationWindow {
body: "Use Steam with your TV remote, and the TV turns on and off with the PC. Turn on CEC on the TV too (Sony: BRAVIA Sync, Samsung: Anynet+, LG: SimpLink).",
changes: ["Valve's cecd and cec-audio-control", "HDMI CEC section in Steam's Display settings", "Volume buttons for the TV in the Quick Access menu"] },
machine: { label: "Steam Machine support", hint: "LED bar, fan and performance settings in Steam",
body: "The front LED bar works, Steam's hardware settings work, and the power button puts it to sleep like a console.",
changes: ["leds-valve driver for every kernel (DKMS)", "steamos-manager for Steam's settings", "Console-like power handling"] },
kpin: { label: "Pin the kernel", hint: "Fixes rebooting after shutdown",
body: "Newer CachyOS kernels make the Steam Machine reboot instead of shutting down. Untick once CachyOS fixes that.",
body: "The front LED bar works, Steam's hardware settings work, the power button puts it to sleep like a console, and shutting down really turns it off on every kernel.",
changes: ["leds-valve driver for every kernel (DKMS)", "steamos-manager for Steam's settings", "Console-like power handling", "Power-off fix: stays off after shutting down (DKMS)"] },
kpin: { label: "Pin the kernel", hint: "Optional: stay on an older kernel",
body: "Keeps the Steam Machine on CachyOS kernel 7.1.6. Not needed for shutting down any more (Steam Machine support fixes that on every kernel); HDMI refresh boost needs it, since newer kernels do HDMI 2.1 themselves.",
changes: ["linux-cachyos from Steamify's release (signature checked)", "Kept in /var/cache/steamify/kernel", "Added to IgnorePkg"] },
hdmi: { label: "HDMI refresh boost", hint: "Higher refresh rates over HDMI",
body: "The pinned kernel keeps many HDMI displays at 60 Hz. Turning this on shows which refresh rates your display can run at the desktop resolution; you pick them, and each one is tried for 15 seconds so you can check the picture before it's installed.",
@@ -247,7 +247,7 @@ ApplicationWindow {
if (id === "hdmi" && !hdmiChoice && hdmiSaved.length) { openHdmiList(); return; }
if (id === "hdmi" && w.hdmi && !nowOn("hdmi") && !hdmiChoice) { startHdmi(); return; }
if (id === "hdmi" && !w.hdmi) hdmiChoice = "";
if (id === "machine") w.kpin = w.machine;
if (id === "machine" && !w.machine) w.kpin = false;
if (id === "kpin" && w.kpin) w.machine = true;
if (id === "hdmi" && w.hdmi) { w.machine = true; w.kpin = true; }
if (!w.machine || !w.kpin) w.hdmi = false;
+1 -1
View File
@@ -2,7 +2,7 @@
# Steamify CachyOS - get and start the app (v2), for `curl | bash`:
# curl -fsSL https://github.com/theupriser/steamify-cachyos/releases/latest/download/steamify-app.sh | bash
# Downloads the newest release's app package (steamify-app.tar.gz: the app,
# steamify.sh and lib/) to ~/.local/share/steamify/app, installs PySide6 if
# steamify.sh, lib/ and patches/) to ~/.local/share/steamify/app, installs PySide6 if
# it's missing, adds a launcher entry, and starts the app.
# STEAMIFY_RELEASE=<tag> takes that release instead of the newest (the
# v2-ui-preview build's copy of this script sets it). STEAMIFY_BRANCH=<branch>