Native brightness control and full HDR (1107 nits) for the Razer Blade 16 (2026) OLED on Linux.
A custom EDID firmware overlay re-encodes the panel's HDR/colorimetry data into the CTA-861 block the kernel actually reads - no daemon, no ICC workaround, no patches.
KDE Plasma 6 · Wayland · Intel Xe + NVIDIA · Samsung ATNA60HU06-0
Run this single command:
bash <(curl -fsSL https://raw.githubusercontent.com/visorcraft/razer_16_2026_linux_oled_brightness/master/quick-fix.sh)This targets the CachyOS + Limine setup documented here.
It installs the EDID overlay, updates Limine and the initramfs, applies the 120Hz mode, and finishes HDR, WCG, and OLED brightness setup after one reboot.
Working setup for native brightness control AND full HDR (1107 nits peak) on the Samsung ATNA60HU06-0 16" 240Hz OLED panel that ships in the Razer Blade 16 (2026, model RZ09-0581) on Linux + KDE Plasma 6 / Wayland.
TL;DR: Provide a custom EDID firmware overlay that re-encodes the panel's HDR/colorimetry data into a CTA-861 Extension Block (the format the kernel DRM parser actually reads). Once the kernel marks the connector as HDR-capable, KWin's native software brightness AND HDR mode both unlock. No daemon, no ICC profile workaround, no patches to upstream code.
This was tested on:
- CachyOS rolling, kernel
7.0.5-cachyosand7.1.0-rc2-cachyos-rc - KDE Plasma 6.6.4 / KWin 6.6.4 / Wayland
linux-cachyos-nvidia-open(nvidia open kernel modules, driver 595.71.05)- Razer Blade 16 (2026) RZ09-0581 with BIOS 2.01
It will likely work on any distro using a recent kernel + KDE Plasma 6.6+ and the same panel. AMD Ryzen variants of the Razer Blade 16 (2025/2026) likely have the same panel and should benefit identically - kernel parameter form is independent of GPU vendor.
Symptom: at the panel's native 240Hz under KWin Wayland, the Intel xe
driver cannot retire KMS atomic commits fast enough. KWin floods the journal
with atomic commit failed: Device or resource busy (~8–13/min), the kernel
periodically logs:
xe 0000:00:02.0: [drm:drm_atomic_helper_setup_commit] [PLANE:64:plane 2A] busy with a previous commit
and after enough accumulated EBUSY pressure the GPU engine resets:
xe 0000:00:02.0: [drm] Tile0: GT0: Engine reset: engine_class=rcs, ... in kwin_wayland
xe 0000:00:02.0: [drm] Xe device coredump has been created
The display "glitches" from that point and the system hard-freezes within
~10–60 minutes. Reproduced reliably on Razer Blade 16 (2026, RZ09-0581) with
kernels linux-cachyos 7.0.8 and linux-cachyos-rc 7.1.0-rc3 - same rate on
both, so this is not RC-specific. The 120Hz fix below also works
identically on both kernels (verified by A/B-testing each rate on each
kernel).
Diagnosis: the xe driver's per-commit latency exceeds the 4.17 ms 240Hz vsync interval but fits within the 8.33 ms 120Hz interval. It's a driver throughput ceiling specific to Panther Lake-era xe code, not a feature/EDID issue - HDR, Wide Color Gamut, EDID overlay, and the brightness slider are all innocent and can stay enabled.
Fix: add and select a custom 120Hz mode. The panel's EDID exposes only 240Hz and 60Hz natively (no 120Hz), but the panel itself accepts a 120Hz timing fine.
# add custom 2560x1600@120Hz mode (CVT reduced blanking)
kscreen-doctor output.eDP-1.addCustomMode.2560.1600.120000.reduced
# list modes to find the new index - it gets appended at the end
kscreen-doctor --outputs
# select it (replace 23 with whatever index the previous command shows)
kscreen-doctor output.eDP-1.mode.23Or run the idempotent installer from this repository:
./install-120hz-mode.shPass a different connector name as the first argument if needed. The script adds the custom mode only when missing, then selects it.
KWin persists this in ~/.config/kwinoutputconfig.json as
mode.refreshRate: 119963. Survives reboot.
Why 60Hz didn't work either: counter-intuitively, the panel's native 60Hz mode also produces atomic-commit failures at roughly the same rate as 240Hz. Best guess is that KWin renders animations / cursor / plane updates at a logical rate that happens to align cleanly with 120Hz but not 60Hz on this panel. The 120Hz custom mode is the only setting that drops failures to ~0.
Verify:
journalctl --since "5 minutes ago" --no-pager | grep -c "atomic commit failed: Device or resource busy"
# 0–2 in 5 min = fine. Sustained ≥5/min = throughput is racing again.To capture the kernel-side fingerprint yourself:
sudo sh -c 'echo 0x1e > /sys/module/drm/parameters/debug'
# reproduce; watch journalctl for "busy with a previous commit"
sudo sh -c 'echo 0 > /sys/module/drm/parameters/debug'This caveat is independent of the EDID overlay below - you'll hit it whether or not you apply the brightness/HDR fix, as long as you're on Panther Lake + xe + KWin Wayland at 240Hz. The EDID overlay is purely additive metadata; it doesn't affect commit-path performance.
Status: filed as a xe-driver throughput limitation. May be resolved by
newer kernels - worth re-testing 240Hz every few minor kernel bumps. Tracking
commits touching drm_atomic_helper, fence retirement, or plane completion
in the xe driver subdirectory.
If you have intel_lpmd (Intel Low Power Mode Daemon) installed and active -
default on CachyOS and several other distros for Panther Lake - you'll still
see ~0.5 atomic-commit-failed events per minute even after the 120Hz fix. The
events correlate 1:1 with intel_lpmd workload-type transitions:
intel_lpmd[...]: [ Enter] [ AUTO] [ UTIL_IDLE_BURSTY ]: WLT [ 3] CPUMASK [8] ...
kwin_wayland[...]: atomic commit failed: Device or resource busy
intel_lpmd dynamically gates CPU clusters (P-cores vs E-cores vs LPE-cores)
based on detected workload. Each transition causes a brief iGPU clock stall,
during which KWin's next atomic commit lands while a previous one is still
pending -> single EBUSY -> recovered on the next vsync.
These residual failures are harmless - single-event, self-recovering, never accumulate fence pressure. They don't lead to engine resets. But to eliminate them entirely (cosmetic log silence + a tiny iGPU clock-stability gain) you can either:
# Quick test - stop it for the current session:
sudo systemctl stop intel_lpmd.service
# Permanent - disable so it doesn't start at boot:
sudo systemctl disable --now intel_lpmd.serviceTradeoff: intel_lpmd does provide measurable battery savings under light
workloads. A reasonable middle ground is to keep it enabled but stop/start
it automatically based on AC/battery state via a small udev-driven systemd
service.
- Brightness slider in System Settings does nothing.
- Fn+F8 / Fn+F9 brightness keys do nothing.
- Direct
sudo sh -c 'echo X > /sys/class/backlight/intel_backlight/brightness'(and same fornvidia_0,nvidia_wmi_ec_backlight,acpi_video0/1) all succeed at the sysfs level but the panel doesn't actually dim. kscreen-doctor --outputsreportsHDR: incapableandWide Color Gamut: incapable.- Setting
kscreen-doctor output.eDP-1.brightness.Nstores the value but doesn't change the panel.
This is an OLED panel - there is literally no LED backlight to control. "Dimming" on OLED has to be done by scaling pixel intensity in the compositor.
KWin (Plasma 6.6) supports software pixel-level brightness on OLED
(allowSdrSoftwareBrightness), but gates it on the connector being
HDR-capable. KWin checks for HDR-capable by looking at the kernel's parsed
EDID - specifically the CTA-861 HDR Static Metadata Block + a
CTA-861 Colorimetry Data Block.
Samsung put both pieces of information in the panel's EDID, but in a DisplayID v2.0 Extension Block rather than the older CTA-861 format. The Linux DRM HDR parser doesn't read DisplayID v2.0 HDR data (as of kernel 7.x). So the kernel reports the connector as non-HDR, KWin agrees, software brightness stays off, HDR stays off, panel feels broken.
The fix is to provide an EDID firmware override that adds a CTA-861 Extension Block carrying the same data that's already in the DisplayID block.
Run as root where shown. Replace any kernel-cmdline / bootloader commands with the equivalent for your bootloader (this guide shows systemd-boot, GRUB, and Limine variants).
Clone this repo (or just download build-oled-hdr-edid.py), then:
python3 build-oled-hdr-edid.py
# writes /tmp/oled-hdr.binThe script reads /sys/class/drm/card0-eDP-1/edid (the panel's stock EDID),
strips any existing CTA-861 extensions, and adds one carrying:
- Colorimetry Data Block declaring BT.2020 RGB / YCC / cYCC and DCI-P3 RGB D65 (extended tag 0x05).
- HDR Static Metadata Data Block declaring PQ (SMPTE ST 2084) EOTF, static metadata type 1, ~1107 nits content max luminance, ~497 nits frame-average max, and 0.044 nits min (extended tag 0x06).
Verify the result:
edid-decode /tmp/oled-hdr.bin | grep -A8 'CTA-861 Extension'You should see both blocks listed cleanly.
sudo mkdir -p /lib/firmware/edid
sudo install -m 0644 /tmp/oled-hdr.bin /lib/firmware/edid/oled-hdr.binThe Intel xe (or i915) display driver loads early in boot, before the
root filesystem is mounted, so the firmware file must live inside the
initramfs.
For mkinitcpio (Arch / CachyOS / EndeavourOS / Manjaro):
# add to FILES=()
sudo sed -i 's|^FILES=()|FILES=(/lib/firmware/edid/oled-hdr.bin)|' /etc/mkinitcpio.conf
# (or edit the file by hand if FILES=() isn't on a line by itself)
sudo mkinitcpio -PFor dracut (Fedora / openSUSE / RHEL):
sudo tee /etc/dracut.conf.d/oled-hdr.conf <<'EOF'
install_items+=" /lib/firmware/edid/oled-hdr.bin "
EOF
sudo dracut --regenerate-all --forceFor Debian / Ubuntu (initramfs-tools):
echo /lib/firmware/edid/oled-hdr.bin | sudo tee -a /etc/initramfs-tools/conf.d/oled-hdr-firmware
sudo update-initramfs -u -k allAdd drm.edid_firmware=eDP-1:edid/oled-hdr.bin to your kernel cmdline.
The DRM module is built into the kernel on most modern distros, so the parameter prefix is
drm.rather thandrm_kms_helper.(which was the old name; it errors silently). Verify on your system with:ls /sys/module/drm/parameters/edid_firmware
For systemd-boot:
Edit /boot/loader/entries/<your-entry>.conf and append to the options
line.
For GRUB:
Edit /etc/default/grub, append the param to GRUB_CMDLINE_LINUX_DEFAULT,
then:
sudo grub-mkconfig -o /boot/grub/grub.cfgFor Limine (CachyOS default):
Edit /etc/default/limine, append the param inside the KERNEL_CMDLINE[default]
quotes, then:
sudo limine-updatesudo rebootAfter login, run:
sudo dmesg | grep -i 'edid'You should NOT see Requesting EDID firmware ... failed (err=-2). If you
do, the firmware file isn't in the initramfs - repeat step 3.
kscreen-doctor --outputs | grep -E 'HDR|Wide Color|Peak|SDR|Color resolution'You should see:
HDR: enabled (or "disabled", which means capable but currently off)
...
Peak brightness: 1107 nits
Wide Color Gamut: enabled (or disabled)
If HDR shows disabled (not incapable), KWin recognized the panel -
enable HDR + WCG with:
kscreen-doctor output.eDP-1.hdr.enable output.eDP-1.wcg.enable(or via System Settings → Display & Monitor → eDP-1 → toggles)
The sdrBrightness value in nits is what KWin treats as "100% on the
brightness slider" for non-HDR content. Default is usually 200, which feels
dim on this panel. Try:
# Comfortable indoor:
kscreen-doctor output.eDP-1.sdr-brightness.500
# Sun-readable, slider-100% feels like outdoor brightness:
kscreen-doctor output.eDP-1.sdr-brightness.1100This panel happily takes 1100 even though kscreen-doctor documents the
range as 100..1000. Caveat: don't camp at >900 nits sustained on
always-bright UI elements - OLED burn-in risk. Daily-use slider position
of ~25% of a 1100-nit reference (= ~275 nits) is comfortable indoors.
# Kernel actually loaded our EDID firmware (no err=-2):
sudo dmesg | grep -i edid
# EDID is in the initramfs (mkinitcpio example; adjust for your tools):
sudo lsinitcpio /boot/initramfs-linux*.img | grep edid
# KWin sees HDR as capable:
kscreen-doctor --outputs | grep -E 'HDR|Wide Color|Peak'
# Brightness slider works (test by pressing Fn+F8/F9 or moving the slider).If HDR: enabled regresses to incapable after a kernel update,
re-check that your initramfs builder still includes the firmware file
(some distro upgrades reset config files).
For the dGPU half of the hybrid setup - confirmed healthy on 2026-05-11:
- Driver: 595.71.05 (open kernel modules via
linux-cachyos-nvidia-open) - GPU: RTX 5080 Mobile at PCI
01:00.0,nvidiakernel driver bound, 16 GB VRAM, idle ~33 °C / 19 W - Modules loaded:
nvidia,nvidia_drm,nvidia_modeset,nvidia_uvm,nvidia_wmi_ec_backlight - PRIME render offload: working - default rendering stays on the Intel
Panther Lake iGPU (
xedriver);prime-run <app>(or__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia <app>) routes GL to the RTX 5080, confirmed viaglxinforeportingOpenGL renderer string: NVIDIA GeForce RTX 5080 Laptop GPU.
Quick checks to re-verify after kernel/driver updates:
nvidia-smi # driver loaded, GPU visible
lsmod | grep -i nvidia # modules present
lspci -k | grep -A3 -i nvidia # kernel driver bound to the dGPU
prime-run glxinfo | grep -i 'OpenGL renderer' # offload reaches the dGPUThe nvidia_wmi_ec_backlight module loads on this laptop but does not
actually drive panel brightness - see the OLED note above; the panel has no
backlight to control.
# Remove EDID firmware
sudo rm /lib/firmware/edid/oled-hdr.bin
# Remove kernel cmdline parameter (depends on bootloader; reverse step 4)
# Remove from initramfs (mkinitcpio)
sudo sed -i 's|FILES=(/lib/firmware/edid/oled-hdr.bin)|FILES=()|' /etc/mkinitcpio.conf
sudo mkinitcpio -P
# Reboot
sudo rebootYou'll lose HDR and the brightness slider will go back to being non-functional
unless you set up the ICC fallback (see icc-fallback/ in this repo).
Some compositors don't recognize HDR even with proper CTA-861 metadata
(they may want additional EDID extensions, or have different gates). In that
case the EDID overlay won't help and you're stuck with software brightness
only. The icc-fallback/ directory in this repo contains a userspace
daemon that simulates dimming on OLED via dynamically-applied dim ICC
profiles, intercepting KDE PowerDevil brightness DBus signals. It works on
Plasma 6 even when HDR remains off. See icc-fallback/README.md.
Long version is in the linked sources - short version:
- Initially looked like a "wrong backlight device" issue (the laptop has
four phantom
/sys/class/backlight/*entries -intel_backlight,nvidia_0,nvidia_wmi_ec_backlight,acpi_video*- and they all accept writes silently). Wasted time trying every standard kernel parameter (acpi_backlight=video|native|vendor|nvidia_wmi_ec,xe.enable_dpcd_backlight=0). - The Arch Wiki Backlight page has a single sentence note: "OLED screens have no backlight." That was the unlock - the entire sysfs backlight subsystem is irrelevant on this panel. Dimming has to come from the compositor.
- Built an ICC-profile-based daemon as a workaround that dimmed via KWin's color management pipeline. Worked, but capped at SDR ~400 nits and felt like a kludge.
- Investigated WHY KWin reported
HDR: incapabledespite the panel being spec'd as ~1100 nits HDR.edid-decodeshowed the kernel was reading the panel's EDID fine - the HDR/colorimetry data was simply in a DisplayID v2.0 Extension Block that the kernel's CTA-861 HDR parser doesn't look at. - Built a custom EDID firmware overlay re-encoding the same data into a
CTA-861 block. After the third reboot iteration (wrong module-name
prefix, then forgot to add to initramfs, then missing the Colorimetry
Data Block),
HDR: incapablefinally flipped toHDR: enabled→ software brightness unlocked too → ICC daemon retired.
mihirwagle/icc-brightness-kde: the upstream ICC profile generator used by the fallback daemon.- Arch Wiki: Backlight, Razer Blade.
- CachyOS forum: Black screen at login + missing backlight on Razer Blade 16
(Strix Point)
- same EDID issue, AMD variant.
- ArchBBS: Legion S7 15ACH6 panel brightness does not change
and related thread
for confirmation that
acpi_backlight=nvidia_wmi_ecis not the answer for OLED Razer Blades (it's a different fix for LCD Lenovo Legions where the WMI EC actually drives a backlight).
Licensed under the MIT License - see LICENSE for the full text.
© 2026 VisorCraft LLC. Provided as-is, without warranty of any kind. The EDID overlay, kernel command-line parameters, and sysfs / systemctl commands here modify low-level display and boot configuration - use them at your own risk.