Detect NVIDIA GPUs without waking them (#6712)

lspci reads PCI config space, and the kernel resumes a runtime-suspended
device to serve that read. On a hybrid laptop the discrete GPU idles in
D3cold, so the first lspci of a Hyprland config load spends over a second
waking it — longer than the 1.5s budget Hyprland gives the whole load.
The reload then fails at whichever line runs next, which is why the error
pointed at default/hypr/apps/1password.lua rather than at nvidia.lua.

Read the vendor, class, and device IDs from sysfs instead. Those are
served from cached fields and never touch config space, so nothing wakes
up. Classify by device ID while we're here: Turing is both the first
generation with GSP firmware and the first at 0x1e00 or above, and
Maxwell opens at 0x1340, one ID past the last Kepler part. Bounding the
older detector at both ends keeps pre-Maxwell cards off the 580xx driver
that cannot drive them, and picks up the Maxwell and Pascal parts the
lspci name regex used to miss.

omarchy-hw-nvidia was also checked in without its executable bit, which
it needs now that nvidia.lua runs it.

Fixes #6660

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-11 18:34:07 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent f4b832eba5
commit 08204846ef
5 changed files with 151 additions and 6 deletions
Regular → Executable
+12 -1
View File
@@ -2,4 +2,15 @@
# omarchy:summary=Detect whether the computer has an NVIDIA GPU.
lspci | grep -qi 'nvidia' &>/dev/null
# Read the cached sysfs IDs rather than lspci, which reads PCI config space and
# resumes runtime-suspended GPUs.
pci_devices_path="${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}"
shopt -s nullglob
for device in "$pci_devices_path"/*; do
[[ $(< "$device/vendor") == "0x10de" ]] || continue
[[ $(< "$device/class") == 0x03* ]] && exit 0
done
exit 1
+16 -2
View File
@@ -2,5 +2,19 @@
# omarchy:summary=Detect whether the computer has an NVIDIA GPU with GSP firmware (Turing or newer).
# GTX 16xx, RTX 20xx-50xx, RTX Pro, Quadro RTX, datacenter A/H/T/L series.
lspci | grep -i 'nvidia' | grep -qE "GTX 16[0-9]{2}|RTX [2-5][0-9]{3}|RTX PRO [0-9]{4}|Quadro RTX|RTX A[0-9]{4}|A[1-9][0-9]{2}|H[1-9][0-9]{2}|T4|L[0-9]+"
# Turing is the first generation with GSP firmware, and the first to use device
# IDs at 0x1e00 or above; Maxwell, Pascal, and Volta all sit below that line.
#
# Read the cached sysfs IDs rather than lspci, which reads PCI config space and
# resumes runtime-suspended GPUs.
pci_devices_path="${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}"
shopt -s nullglob
for device in "$pci_devices_path"/*; do
[[ $(< "$device/vendor") == "0x10de" ]] || continue
[[ $(< "$device/class") == 0x03* ]] || continue
(( $(< "$device/device") >= 0x1e00 )) && exit 0
done
exit 1
+19 -2
View File
@@ -2,5 +2,22 @@
# omarchy:summary=Detect whether the computer has an NVIDIA GPU without GSP firmware (Maxwell/Pascal/Volta).
# GTX 9xx/10xx, GT 10xx, Quadro P/M/GV, MX series, Titan X/Xp/V, Tesla V100.
lspci | grep -i 'nvidia' | grep -qE "GTX (9[0-9]{2}|10[0-9]{2})|GT 10[0-9]{2}|Quadro [PM][0-9]{3,4}|Quadro GV100|MX *[0-9]+|Titan (X|Xp|V)|Tesla V100"
# Bounded at both ends, because the callers install the 580xx driver on a match
# and it supports exactly this span. GSP firmware arrived with Turing, which is
# also where device IDs cross 0x1e00. Maxwell opens at 0x1340, one ID after the
# last Kepler part; anything older needs a legacy driver we don't package.
#
# Read the cached sysfs IDs rather than lspci, which reads PCI config space and
# resumes runtime-suspended GPUs.
pci_devices_path="${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}"
shopt -s nullglob
for device in "$pci_devices_path"/*; do
[[ $(< "$device/vendor") == "0x10de" ]] || continue
[[ $(< "$device/class") == 0x03* ]] || continue
device_id=$(< "$device/device")
(( device_id >= 0x1340 && device_id < 0x1e00 )) && exit 0
done
exit 1