Virtual Display (Linux / EDID)

Advanced display setup for Linux / KDE Plasma / Wayland.

This page is for Linux / KDE Plasma setups that need a dedicated display mode through EDID. Most users should start with the Linux server section first and only come here when the EDID has to be generated, installed, or verified manually.

The idea is simple: create an EDID file for the display mode you want, install it into /lib/firmware/edid/, bind it to the HDMI output, then verify that KDE Plasma sees the new mode.

Install tools

sudo apt update
sudo apt install -y zsh dos2unix automake edid-decode make gcc

Get the EDID generator

mkdir -p ~/dev
cd ~/dev
git clone https://github.com/akatrevorjay/edid-generator
cd edid-generator

dos2unix modeline2edid
chmod +x modeline2edid

Patch for custom square / small-display modes

Some small-display modes need a small patch in the generator. I will add more known-good display profiles here over time.

python3 - <<'PY'
from pathlib import Path
import re

p = Path("edid.S")
s = p.read_text()

s = re.sub(
    r'std_xres:\s*\.byte\s*\(XPIX/8\)-31',
    'std_xres: .byte 0x01',
    s
)

s = re.sub(
    r'std_vres:\s*\.byte\s*\(XY_RATIO<<6\)\+VFREQ-60',
    'std_vres: .byte 0x01',
    s
)

p.write_text(s)
PY

Select resolution and refresh rate

Pick the resolution and refresh rate for the display setup you want. I often use high refresh rates, for example 240 Hz, because this can reduce overall latency. If an app or hardware path does not behave correctly at high refresh rates, lower it. I recommend the highest stable value your hardware and configuration can handle.

This is an advanced topic. I cannot cover every edge case here, but a chatbot will usually be able to help if you show it this page and your exact command output.

Show current 720x720 example

This is the current example config. Later I will add more known-good configs for more supported displays.

cd ~/dev/edid-generator
rm -f sq72030.S sq72030.bin

cat > modelines.txt <<'MODEL'
Modeline "sq72030" 21.12 720 760 832 944 720 721 724 746 -hsync +vsync ratio=4:3 vfreq=30
MODEL

./modeline2edid modelines.txt
make
edid-decode sq72030.bin

Install the EDID file

Install the generated EDID file. Replace the filename when you generate a different display profile.

cd ~/dev/edid-generator
sudo install -Dm644 sq72030.bin /lib/firmware/edid/sq72030.bin
ls -lh /lib/firmware/edid/sq72030.bin

Select the HDMI output

Check the DRM outputs and select the HDMI connector you want to bind to the EDID. The DRM card number can differ between systems, especially on multi-GPU machines, so identify the connector instead of assuming a fixed card0 or card1 path.

ls /sys/class/drm | grep -E 'HDMI|DP|DVI'

To list only HDMI connectors, you can narrow the result further:

ls /sys/class/drm | grep -E 'card[0-9]+-HDMI-A-[0-9]+'

Proprietary NVIDIA driver: if no HDMI/DP/DVI connector is listed, DRM/KMS may not be enabled yet. Enable nvidia-drm.modeset=1 in the kernel command line first, apply the bootloader configuration, and reboot. Then run the DRM listing again. Once the connector name is visible, continue below and add the EDID binding for that connector. This preliminary step is not normally needed with nouveau just to list the connectors.

The examples below use HDMI-A-1. Replace it if your target connector has a different name.

Bind the EDID at boot

Use one of the following bootloader-specific methods. On a normal Debian/Ubuntu Linux system using GRUB, use the GRUB method. Raspberry Pi systems that boot through /boot/firmware/cmdline.txt use the alternative method shown below.

Normal Linux / GRUB

Edit the GRUB defaults:

sudo nano /etc/default/grub

Add the EDID binding to the existing GRUB_CMDLINE_LINUX_DEFAULT value. Keep any options already present; append these parameters inside the same quotes:

drm.edid_firmware=HDMI-A-1:edid/sq72030.bin video=HDMI-A-1:e nvidia-drm.modeset=1

NVIDIA note: I had trouble getting this setup to work reliably with the nouveau driver. That does not mean nouveau cannot work, but this tutorial uses the proprietary NVIDIA driver for the tested setup. With that driver, enable DRM/KMS using nvidia-drm.modeset=1 as shown here. If you are not using the proprietary NVIDIA driver, omit that parameter.

For example:

GRUB_CMDLINE_LINUX_DEFAULT="quiet drm.edid_firmware=HDMI-A-1:edid/sq72030.bin video=HDMI-A-1:e nvidia-drm.modeset=1"

Apply the GRUB configuration and reboot:

sudo update-grub
sudo reboot
Raspberry Pi as Server

On Raspberry Pi systems that use /boot/firmware/cmdline.txt instead of GRUB, edit that kernel command line directly:

sudo nano /boot/firmware/cmdline.txt

Keep the existing command line on one line and append the same EDID parameters to the end. If this Raspberry Pi is not using the proprietary NVIDIA driver, omit nvidia-drm.modeset=1:

drm.edid_firmware=HDMI-A-1:edid/sq72030.bin video=HDMI-A-1:e nvidia-drm.modeset=1

Then reboot:

sudo reboot

Verify after reboot

cat /proc/cmdline | grep -o 'drm.edid_firmware=[^ ]*\|video=HDMI-A-1:e\|nvidia-drm.modeset=1'

CONNECTOR=HDMI-A-1
for path in /sys/class/drm/card*-"$CONNECTOR"; do
    [ -e "$path" ] || continue
    echo "$path"
    cat "$path/status"
    cat "$path/modes"
done

QT_QPA_PLATFORM=wayland kscreen-doctor
QT_QPA_PLATFORM=wayland kscreen-doctor -o

A good result should show the EDID binding, connected, and the display mode you created.

Show example verify output
drm.edid_firmware=HDMI-A-1:edid/sq72030.bin
video=HDMI-A-1:e
nvidia-drm.modeset=1
connected
720x720

Back to Linux setup