An apt upgrade switched the display manager from SDDM to plasmalogin, whose kwin_wayland greeter never runs the SDDM Xsetup hook. Add a plasma-login.service user drop-in that cycles DPMS off/on with kscreen-doctor on 7.x kernels, forcing the full modeset that un-sticks i915 pipe A (a plain resolution change is absorbed by the eDP panel fitter and doesn't help). Verified across a cold reboot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
120 lines
4.2 KiB
Bash
Executable File
120 lines
4.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# setup-i915-kernel7-fix.sh
|
|
#
|
|
# Run on a fresh hp-chell (HP Chromebook 13 "chell", coreboot/MrChromebox
|
|
# firmware, KDE neon) install to apply two things:
|
|
#
|
|
# 1. The kernel 7.x cold-boot black-screen workaround, which forces a
|
|
# second modeset on eDP-1 to un-stick i915's pipe A on 7.x kernels:
|
|
# a /usr/share/sddm/scripts/Xsetup hook (SDDM) and a
|
|
# plasma-login.service drop-in doing a DPMS cycle (Plasma Login).
|
|
# See project CLAUDE.md for the full diagnosis writeup.
|
|
# 2. GRUB_TIMEOUT=5 / GRUB_TIMEOUT_STYLE=menu, so the boot menu is
|
|
# visible for 5 seconds (useful for picking a fallback kernel like
|
|
# 6.17.0-42-generic if a future 7.x point release regresses again).
|
|
#
|
|
# Safe to re-run; idempotent.
|
|
|
|
set -eu
|
|
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "must run as root (sudo $0)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> installing SDDM Xsetup i915 kernel-7.x workaround"
|
|
cat > /usr/share/sddm/scripts/Xsetup << 'EOF'
|
|
#!/bin/sh
|
|
# Xsetup - run as root before the login dialog appears
|
|
|
|
if [ -e /sbin/prime-offload ]; then
|
|
echo running NVIDIA Prime setup /sbin/prime-offload
|
|
/sbin/prime-offload
|
|
fi
|
|
|
|
# Workaround: on kernel 7.x, the first i915 modeset at cold boot (Xorg's
|
|
# auto-modeset to the panel's native 3200x1800) leaves pipe A in a bad
|
|
# state (persistent CPU pipe A FIFO underrun -> blank panel, backlight
|
|
# still on, even though DRM/plane state reports healthy). Forcing a
|
|
# second modeset unsticks it. Rather than cycle back to native, just
|
|
# land on 1600x900 (exact half of 3200x1800, clean 2x integer scaling)
|
|
# and stay there -- it's only the login screen; the logged-in session
|
|
# renews the modeset itself and comes up at full native resolution.
|
|
# Not needed on 6.17.x kernels. See project CLAUDE.md for the full
|
|
# writeup.
|
|
case "$(uname -r)" in
|
|
7.*)
|
|
xrandr --output eDP-1 --mode 1600x900 >/tmp/xsetup-modeset.log 2>&1
|
|
echo "set eDP-1 to 1600x900 (i915 kernel 7.x cold-boot workaround)"
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod 755 /usr/share/sddm/scripts/Xsetup
|
|
|
|
# Plasma Login (plasmalogin, replaced SDDM on neon in 2026-09) runs its
|
|
# greeter under kwin_wayland, so the SDDM Xsetup hook above never fires.
|
|
# Equivalent fix there: a DPMS off/on cycle via kscreen-doctor, run from
|
|
# the greeter's own systemd user manager right after KWin comes up. A
|
|
# plain resolution change is NOT enough under KWin -- the eDP panel
|
|
# fitter absorbs it as a fastset without a real pipe modeset; DPMS off
|
|
# fully disables the CRTC so the "on" is a genuine full modeset.
|
|
echo "==> installing plasmalogin greeter i915 kernel-7.x workaround"
|
|
install -d /usr/local/libexec
|
|
cat > /usr/local/libexec/hp-chell-i915-dpms-cycle << 'EOF'
|
|
#!/bin/sh
|
|
# Run as the plasmalogin greeter user (from plasma-login.service's
|
|
# ExecStartPre). Forces a full modeset on kernel 7.x to un-stick i915
|
|
# pipe A after the cold-boot first modeset. See hp-chell CLAUDE.md.
|
|
case "$(uname -r)" in
|
|
7.*) ;;
|
|
*) exit 0 ;;
|
|
esac
|
|
[ "$(id -un)" = plasmalogin ] || exit 0
|
|
|
|
export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}"
|
|
export QT_QPA_PLATFORM=wayland
|
|
|
|
# wait (up to ~20s) for KWin's output management to answer
|
|
i=0
|
|
until kscreen-doctor -o >/dev/null 2>&1; do
|
|
i=$((i + 1))
|
|
[ "$i" -ge 40 ] && { echo "kscreen-doctor never came up" >&2; exit 0; }
|
|
sleep 0.5
|
|
done
|
|
|
|
kscreen-doctor --dpms off >/dev/null 2>&1
|
|
sleep 1
|
|
kscreen-doctor --dpms on >/dev/null 2>&1
|
|
echo "cycled DPMS off/on (i915 kernel 7.x cold-boot workaround)"
|
|
EOF
|
|
chmod 755 /usr/local/libexec/hp-chell-i915-dpms-cycle
|
|
|
|
install -d /etc/systemd/user/plasma-login.service.d
|
|
cat > /etc/systemd/user/plasma-login.service.d/10-i915-kernel7-dpms-cycle.conf << 'EOF'
|
|
[Service]
|
|
ExecStartPre=-/usr/local/libexec/hp-chell-i915-dpms-cycle
|
|
EOF
|
|
|
|
echo "==> setting GRUB_TIMEOUT=5 / GRUB_TIMEOUT_STYLE=menu"
|
|
grub_conf=/etc/default/grub
|
|
|
|
set_grub_key() {
|
|
key=$1
|
|
value=$2
|
|
if grep -q "^${key}=" "$grub_conf"; then
|
|
sed -i "s|^${key}=.*|${key}=${value}|" "$grub_conf"
|
|
elif grep -q "^#${key}=" "$grub_conf"; then
|
|
sed -i "s|^#${key}=.*|${key}=${value}|" "$grub_conf"
|
|
else
|
|
echo "${key}=${value}" >> "$grub_conf"
|
|
fi
|
|
}
|
|
|
|
set_grub_key GRUB_TIMEOUT 5
|
|
set_grub_key GRUB_TIMEOUT_STYLE menu
|
|
|
|
echo "==> running update-grub"
|
|
update-grub
|
|
|
|
echo "==> done"
|