I couldn’t set the native resolution on one of my monitors after I installed ATI/AMD’s proprietary Catalyst drivers. With the open-source radeon drivers, you could at least throw some badly documented settings into a custom xorg.conf file and have X ignore a corrupt EDID and accept custom ModeLines. Sadly, the fglrx (Catalyst) drivers don’t play that.
Forcing EDID with closed-source undocumented fglrx/Catalyst drivers was a mystery. Took me 2 days to go through all the methods that don’t work until I found this gem of instructions by ubuntuforum’s @lukax at the bottom of page 4. All praise be to lukax and chris from this obscure impossible to find forum.
I extended their instructions a tad for my specific problem: dual screens (a pair of 1920×1200@60hz puppies), one of which has a fried EDID. X/fglrx detects one screen’s native resolution just fine, but force the other screen to be 640×480. So instead of wrestling with ModeLines/xrandr, I grabbed one screen’s EDID data and forced it on the other screen.
Fixing a screen with a bad EDID using a good screen
Note: the screens should have the same resolution and refresh-rate. No idea what will happen if they don’t :)
DFP4 (my Samsung SyncMaster) has a working EDID that I will use to override the other monitor (an otherwise lovely Benq, sporting the same native resolution and refresh-rate).
Using no third-party EDID extracting tools, lets dig the Xorg log for treasure. The good screen, having been detected by fglrx will have a nice juicy EDID in hex for us :)
aleckz@kronos:/var/log$ cat Xorg.0.log ... [ 29.695] (II) fglrx(0): Ranges: V min: 50 V max: 63 Hz, H min: 30 H max: 81 kHz, PixClock max 175 MHz [ 29.695] (II) fglrx(0): Monitor name: SyncMaster [ 29.695] (II) fglrx(0): Serial No: HCLZC01539 [ 29.695] (II) fglrx(0): Number of EDID sections to follow: 1 [ 29.695] (II) fglrx(0): EDID (in hex): [ 29.695] (II) fglrx(0): 00ffffffffffff004c2d87053949315a [ 29.695] (II) fglrx(0): 30140103803420782aee91a3544c9926 [ 29.696] (II) fglrx(0): 0f5054230800a9408180814081009500 [ 29.696] (II) fglrx(0): b30001010101283c80a070b023403020 [ 29.696] (II) fglrx(0): 360006442100001a000000fd00323f1e [ 29.696] (II) fglrx(0): 5111000a202020202020000000fc0053 [ 29.696] (II) fglrx(0): 796e634d61737465720a2020000000ff [ 29.696] (II) fglrx(0): 0048434c5a4330313533390a20200186 [ 29.696] (II) fglrx(0): Printing probed modes for output DFP4 [ 29.696] (II) fglrx(0): Modeline "1920x1200"x60.0 154.00 1920 1968 2000 2080 1200 1203 1209 1235 +hsync -vsync (74.0 kHz eP) [ 29.696] (II) fglrx(0): Modeline "1920x1080"x60.0 154.00 1920 1968 2000 2080 1080 1203 1209 1235 +hsync -vsync (74.0 kHz e) [ 29.696] (II) fglrx(0): Modeline "1600x1200"x60.0 162.00 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync (75.0 kHz e) ...
Take the EDID hex, strip all the spaces and debug cruft, and create one nice string: “00ffffffffffff004c2d87053949315a30140103803420782aee91a3544c99260f5054230800a9408180814081009500b30001010101283c80a070b023403020360006442100001a000000fd00323f1e5111000a202020202020000000fc0053796e634d61737465720a2020000000ff0048434c5a4330313533390a20200186”
Apply any of the many possible GNU one-liners to convert the hex stream into a binary blob:
aleckz@kronos:~$ echo -n "00ffffffffffff004c2d87053949315a30140103803420782aee91a3544c99260f5054230800a9408180814081009500b30001010101283c80a070b023403020360006442100001a000000fd00323f1e5111000a202020202020000000fc0053796e634d61737465720a2020000000ff0048434c5a4330313533390a20200186" | perl -nE 'print pack "H*", $_' > edid.bin
We can verify the EDID binary using parse-edid tool (apt-get install read-edid in ubuntu):
aleckz@kronos:~$ parse-edid edid.bin parse-edid: parse-edid version 2.0.0 parse-edid: EDID checksum passed. # EDID version 1 revision 3 Section "Monitor" # Block type: 2:0 3:fd # Block type: 2:0 3:fc Identifier "SyncMaster" VendorName "SAM" ModelName "SyncMaster" # Block type: 2:0 3:fd HorizSync 30-81 VertRefresh 50-63 # Max dot clock (video bandwidth) 170 MHz # Block type: 2:0 3:fc # Block type: 2:0 3:ff # DPMS capabilities: Active off:yes Suspend:no Standby:no Mode "1920x1200" # vfreq 59.950Hz, hfreq 74.038kHz DotClock 154.000000 HTimings 1920 1968 2000 2080 VTimings 1200 1203 1209 1235 Flags "-HSync" "+VSync" EndMode # Block type: 2:0 3:fd # Block type: 2:0 3:fc # Block type: 2:0 3:ff EndSection
Excellent! Captured my good screen’s EDID!
How do you make fglrx use the custom EDID binary for a bad screen?
Well we can either read the instructions from @lukax, or figure it out ourselves!
Let’s snoop on ATI/AMD’s proprietary closed-source drivers using strace, and see what files X server is trying to open while its booting up.
Switch to a different virtual console (CTRL+ALT+F1)
Stop X nicely (service stop gdm , or service stop lightdm , whichever is applicable. don’t forget to sudo up)
Use strace to log X’s open() system calls:
aleckz@kronos:~$ strace -e "trace=open" X -retro 2> xtrace.log
This should open up an old fashioned X server. Give it a few seconds, then switch back to the virtual console and kill it (CTRL+C).
A few pages into xtrace.log you should see something wonderful:
open("/proc/ati/major", O_RDONLY) = 15 open("/dev/ati/card0", O_RDWR) = 15 open("/sys/bus/pci/devices/0000:01:00.0/config", O_RDONLY|O_CLOEXEC) = 16 open("/sys/bus/pci/devices/0000:01:00.0/config", O_WRONLY|O_CLOEXEC) = 16 open("/sys/bus/pci/devices/0000:01:00.0/resource2", O_RDWR|O_CLOEXEC) = 16 open("/usr/lib/xorg/modules/libfb.so", O_RDONLY|O_CLOEXEC) = 16 open("/etc/ati/amdpcsdb", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 16 open("/etc/ati/DFP3.edid", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ati/dfp3.edid", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ati/DFP3.edid", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ati/dfp3.edid", O_RDONLY) = -1 ENOENT (No such file or directory) open("/proc/mtrr", O_RDWR) = 16 Loading extension ATIFGLRXDRI open("/proc/ati/major", O_RDONLY) = 16
fglrx is making X look for EDID files in the /etc/ati folder! And the names of the files correspond to the port-names ATI assigns to your screens (DFP is their name for DVI?)
So now just copy the custom edid.bin to /etc/ati/DFP3.edid and /etc/ati/DFP4.edid (using whatever names appear in your trace log). No secret xorg.conf settings necessary :)
Now when we restart X we will see something glorious in the new /var/log/Xorg.0.log
[ 43592.103] (II) fglrx(0): Successfully loaded EDID override file - /etc/ati/DFP3.edid - bytes:128 [ 43592.103] (II) fglrx(0): EDID vendor "SAM", prod id 1415 [ 43592.103] (II) fglrx(0): Using EDID range info for horizontal sync [ 43592.103] (II) fglrx(0): Using EDID range info for vertical refresh [ 43592.103] (II) fglrx(0): Printing DDC gathered Modelines: [ 43592.103] (II) fglrx(0): Modeline "1920x1200"x0.0 154.00 1920 1968 2000 2080 1200 1203 1209 1235 +hsync -vsync (74.0 kHz eP) [ 43592.103] (II) fglrx(0): Modeline "800x600"x0.0 40.00 800 840 968 1056 600 601 605 628 +hsync +vsync (37.9 kHz e)
Now we have native-resolution support throughout X and every window manager and tweaking tool you want :)
Pingback: ATI Binärtreiber (fglrx) benutzt nur Modes die via EDID ausgelesen werden / Faken von EDID Informationen | Blog de imo
I’ve a problem related to this.
If that works the way you described it, it might save me a lot! of troublem thanks!
wow !! it works. It took me two days of frustating searching and many, many unsuccessful tweaks of xorg.conf till I finally found your link – and discovered that flgrx drivers are ignoring all those settings anyway!
So I followed your guide…
I simply copied my screen’s EDID binary file to /etc/ati then renamed it to “CRT2.edid” (as i am using a VGA port), rebooted and voila !!
I now have 1680×1050 working via VGA. Grin.
Many thanks for your persistance in discovering how to workaround this “flgrx driver anomaly”, and more importantly publishing it so succinctly for us.
PS – I am using a Chimei CMV 221D monitor on VGA port of ATI Radeon HD 5570, Linux Mint 16 on Core 2 Duo 6600. Smooth as silk for a 7 yr old machine !
Woohoo! Good job Neil :D
Nice tips for spelunking, not just the given problem. Syntax goof alert: on Arch Linux I had to do
$ parse-edid < edid.bin
with the redirect operator. Otherwise parse-edid hangs waiting for input. The install package in Arch is "read-edid".
Samsungs are very good but I once found errors in onboard EDID data and so put modelines in xorg.conf derived straight from the Samsung user manual.