4.5 KiB
Customizing display configuration
This section describes how to customize display configuration using:
- kernel modes
- EDID files
Example situations it can help you with:
- display controllers (external hardware) not advertising EDID at all,
- misbehaving graphics drivers,
- loading custom display configuration before the Display Manager is running,
Forcing display modes
In case of very wrong monitor controller and/or video driver combination you can
force the display to be enabled
and skip some driver-side checks by adding video=<OUTPUT>:e
to boot.kernelParams
.
This is exactly the case with amdgpu
drivers
{
# force enabled output to skip `amdgpu` checks
hardware.display.outputs."DP-1".mode = "e";
# completely disable output no matter what is connected to it
hardware.display.outputs."VGA-2".mode = "d";
/* equals
boot.kernelParams = [ "video=DP-1:e" "video=VGA-2:d" ];
*/
}
Crafting custom EDID files
To make custom EDID binaries discoverable you should first create a derivation storing them at
$out/lib/firmware/edid/
and secondly add that derivation to hardware.display.edid.packages
NixOS option:
{
hardware.display.edid.packages = [
(pkgs.runCommand "edid-custom" {} ''
mkdir -p $out/lib/firmware/edid
base64 -d > "$out/lib/firmware/edid/custom1.bin" <<'EOF'
<insert your base64 encoded EDID file here `base64 < /sys/class/drm/card0-.../edid`>
EOF
base64 -d > "$out/lib/firmware/edid/custom2.bin" <<'EOF'
<insert your base64 encoded EDID file here `base64 < /sys/class/drm/card1-.../edid`>
EOF
'')
];
}
There are 2 options significantly easing preparation of EDID files:
hardware.display.edid.linuxhw
hardware.display.edid.modelines
Assigning EDID files to displays
To assign available custom EDID binaries to your monitor (video output) use hardware.display.outputs."<NAME>".edid
option.
Under the hood it adds drm.edid_firmware
entry to boot.kernelParams
NixOS option for each configured output:
{
hardware.display.outputs."VGA-1".edid = "custom1.bin";
hardware.display.outputs."VGA-2".edid = "custom2.bin";
/* equals:
boot.kernelParams = [ "drm.edid_firmware=VGA-1:edid/custom1.bin,VGA-2:edid/custom2.bin" ];
*/
}
Pulling files from linuxhw/EDID database
hardware.display.edid.linuxhw
utilizes pkgs.linuxhw-edid-fetcher
to extract EDID files
from https://github.com/linuxhw/EDID based on simple string/regexp search identifying exact entries:
{
hardware.display.edid.linuxhw."PG278Q_2014" = [ "PG278Q" "2014" ];
/* equals:
hardware.display.edid.packages = [
(pkgs.linuxhw-edid-fetcher.override {
displays = {
"PG278Q_2014" = [ "PG278Q" "2014" ];
};
})
];
*/
}
Using XFree86 Modeline definitions
hardware.display.edid.modelines
utilizes pkgs.edid-generator
package allowing you to
conveniently use XFree86 Modeline
entries as EDID binaries:
{
hardware.display.edid.modelines."PG278Q_60" = " 241.50 2560 2608 2640 2720 1440 1443 1448 1481 -hsync +vsync";
hardware.display.edid.modelines."PG278Q_120" = " 497.75 2560 2608 2640 2720 1440 1443 1448 1525 +hsync -vsync";
/* equals:
hardware.display.edid.packages = [
(pkgs.edid-generator.overrideAttrs {
clean = true;
modelines = ''
Modeline "PG278Q_60" 241.50 2560 2608 2640 2720 1440 1443 1448 1481 -hsync +vsync
Modeline "PG278Q_120" 497.75 2560 2608 2640 2720 1440 1443 1448 1525 +hsync -vsync
'';
})
];
*/
}
Complete example for Asus PG278Q
And finally this is a complete working example for a 2014 (first) batch of Asus PG278Q monitor with amdgpu
drivers:
{
hardware.display.edid.modelines."PG278Q_60" = " 241.50 2560 2608 2640 2720 1440 1443 1448 1481 -hsync +vsync";
hardware.display.edid.modelines."PG278Q_120" = " 497.75 2560 2608 2640 2720 1440 1443 1448 1525 +hsync -vsync";
hardware.display.outputs."DP-1".edid = "PG278Q_60.bin";
hardware.display.outputs."DP-1".mode = "e";
}