Skip to content

Instantly share code, notes, and snippets.

@sbng
Last active April 11, 2024 06:33
Show Gist options
  • Save sbng/85ab951e76a04c4000c5b3d4be4e5b22 to your computer and use it in GitHub Desktop.
Save sbng/85ab951e76a04c4000c5b3d4be4e5b22 to your computer and use it in GitHub Desktop.
amdgpu cause external display to go blank after suspend - workaround

wayland

admgpu experiences a bug where external dispaly goes black coming back from suspend. The build-in display (eDP) does not experience this issue. The workaound is to toggle the external display manually or via scripts. Depending on the compositor used (sway or hyperland). The approach adopted to fix this issue is illustrated below:

sway

Create a script to force the following command (chvt x) to toggle from graphical display back to graphical mode. This is a workaround to get the external display working again. The script is called by systemd in the POST resume operation. The location of the script is /usr/lib/systemd/system-sleep/reset-external-display.sh

#!/bin/bash

PATH=/sbin:/usr/sbin:/bin:/usr/bin

DISPLAY=$(cat /sys/class/drm/*/status | grep "^connected" | wc -l)

# Reset system by switching to tty and back only if there are external 
# monitor connected $DISPLAY > 1, no action is needed if no external display 
# is present
if [[ "${1}" == "post" ]] && [[ ${DISPLAY} != 1 ]] ; then
##  # swicth tty to fix the back from suspension external monitor black out issue
  echo "Reset external monitor" >> /tmp/suspend_back.log
  chvt 3 
  sleep 1
  chvt 2
fi

hyprland

hyprland eco system provides a idle detection daemon hypridle. In this tool, hypridle have the capabilities of running command after suspend and resume as a user. Unlike systemd script, this method do not require tty switching to force the change of graphic mode. Instead a simple command to turn off and on dpms is suffice. This approach is more desirabe. The hypride.conf is as follows:

general {
    lock_cmd = pidof swaylock || swaylock -f -k -i lock.img  # avoid starting multiple hyprlock instances.
    before_sleep_cmd = loginctl lock-session    # lock before suspend.
    after_sleep_cmd = hyprctl dispatch dpms off;sleep1;hyprctl dispatch dpms on  # to avoid having to press a key twice to turn on the display.
}

listener {
    timeout = 300                                 # 5min
    on-timeout = loginctl lock-session            # lock screen when timeout has passed
}

listener {
    timeout = 330                                 # 5.5min
    on-timeout = hyprctl dispatch dpms off        # screen off when timeout has passed
    on-resume = hyprctl dispatch dpms on          # screen on when activity is detected after timeout has fired.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment