Skip to content

linuxnow/edid-generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

EDID Generator

Generate custom EDID binaries with proper CVT 1.1 timing for non-standard display resolutions.

Useful for LED video walls (NovaStar, Linsn, Colorlight), digital signage, and any display that needs a custom resolution on Linux/Wayland where xrandr --newmode is not available.

Why

Wayland compositors (GNOME/Mutter, KDE/KWin) don't support adding custom display modes at runtime. The only way to use a non-standard resolution is to provide an EDID binary that advertises it, injected via the kernel's drm.edid_firmware parameter.

This tool generates spec-compliant EDID binaries with timing values that exactly match the VESA CVT 1.1 standard (verified against libxcvt/cvt).

Requirements

Python 3.6+ (no external dependencies).

Usage

# Standard CVT timing (recommended)
python3 edid-gen.py 3840 648

# Custom refresh rate
python3 edid-gen.py 3840 648 50

# CVT Reduced Blanking (lower bandwidth, tighter timing margins)
python3 edid-gen.py 3840 648 -r

# Custom monitor name and output path
python3 edid-gen.py 3840 648 -n "NovaStar LED" -o /tmp/novastar.bin

Output:

Mode: 3840x648 59.87 Hz (CVT)
Pixel clock: 199.50 MHz

Modeline "3840x648_60.00"  199.50  3840 4000 4392 4944  648 651 661 674 -hsync +vsync

Horizontal: 3840 + fp=160 + sync=392 + bp=552 = 4944 total  (blank=1104)
Vertical:   648 + fp=3 + sync=10 + bp=13 = 674 total  (blank=26)

EDID written to /tmp/3840x648.bin (128 bytes, checksum OK)

Installation

After generating the EDID binary:

# 1. Copy to firmware directory
sudo mkdir -p /lib/firmware/edid
sudo cp /tmp/3840x648.bin /lib/firmware/edid/

# 2. Find your display connector
ls /sys/class/drm/ | grep -E "HDMI|DP"

# 3. Add kernel parameter (replace HDMI-A-1 with your connector)
sudo grubby --update-kernel=ALL \
  --args="drm.edid_firmware=HDMI-A-1:edid/3840x648.bin"

# 4. Reboot
sudo reboot

# 5. Verify
cat /sys/class/drm/card*-HDMI-A-*/modes

Validation

The generated modelines match cvt (libxcvt) output exactly:

# Compare against system cvt
python3 edid-gen.py 1920 1080 | grep Modeline
cvt 1920 1080 60 | grep Modeline
# Identical output

EDID binaries pass edid-decode validation with zero errors and zero warnings:

python3 edid-gen.py 3840 648 -o /tmp/test.bin
edid-decode /tmp/test.bin

EDID Encoding Limits

The EDID Detailed Timing Descriptor has encoding limits. The tool validates these and rejects values that can't be encoded:

Field Max value
Horizontal active/blanking 4095 pixels (12-bit)
Vertical active/blanking 4095 lines (12-bit)
H sync offset/width 1023 pixels (10-bit)
V sync offset/width 63 lines (6-bit)
Pixel clock 655.35 MHz (16-bit, 10 kHz units)

Resolutions that exceed these limits (e.g., 5120x2880) will still show the modeline but won't generate an EDID binary.

Standard vs Reduced Blanking

Mode H blanking Bandwidth Use when
Standard (default) Large (~1100px for 3840 wide) Higher Display needs generous timing margins (LED processors, older hardware)
Reduced (-r) Fixed 160px Lower Display handles tight timing (modern LCDs, bandwidth-limited connections)

For LED video processors (NovaStar, etc.), always use standard timing — the larger blanking periods give the processor more time to synchronize, avoiding pixel offset issues.

How it Works

The tool implements the VESA CVT 1.1 algorithm (from the CVT calculation spreadsheet by Graham Loveridge), matching the reference implementation in libxcvt. Key steps:

  1. Round width to character cell granularity (8 pixels)
  2. Determine V sync lines from aspect ratio (4:3=4, 16:9=5, 16:10=6, 5:4=7, other=10)
  3. Calculate blanking duty cycle from the GTF secondary curve
  4. Compute H/V blanking, sync, and porch values
  5. Round pixel clock to nearest 250 kHz step
  6. Encode into a 128-byte EDID 1.3 base block with proper descriptors

The EDID binary includes all four required descriptors:

  • DTD 1: The custom timing (preferred mode)
  • Monitor name: Configurable via -n flag
  • Range limits: Computed from the timing parameters
  • Dummy descriptor: Required by EDID 1.3 spec

License

Copyright (C) 2026 Pau Aliagas linuxnow@gmail.com

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

About

No description, website, or topics provided.

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages