EDID and Nvidia problems on Xorg

Somewhere in late 2014, i suddenly got very poor resolution on some of my TFT LCD displays after an upgrade; /var/log/Xorg.0.log showed something like:

[    43.531] (WW) NVIDIA(0): The EDID read for display device CRT-1 is invalid:
[    43.532] (WW) NVIDIA(0):     unrecognized EDID Header.
[    43.532] (--) NVIDIA(0):
[    43.532] (--) NVIDIA(0): Raw EDID bytes:
[    43.532] (--) NVIDIA(0):
[    43.532] (--) NVIDIA(0):   00 a0 00 ff ff ff ff 00  42 93 17 10 86 62 04 00
[    43.532] (--) NVIDIA(0):   30 0e 01 03 08 22 1b 78  28 ee a6 9e 54 4c 99 26
[    43.532] (--) NVIDIA(0):   19 4f 54 ad cf 00 81 80  01 01 01 01 01 01 01 01
[    43.532] (--) NVIDIA(0):   01 01 01 01 01 01 30 2a  00 98 51 00 2a 40 30 70
[    43.532] (--) NVIDIA(0):   13 00 51 0e 11 00 00 1e  00 00 00 fc 00 4d 41 2d
[    43.532] (--) NVIDIA(0):   37 38 32 4b 43 0a 20 20  20 20 00 00 00 fd 00 3c
[    43.532] (--) NVIDIA(0):   4b 1e 50 0e 00 0a 20 20  20 20 20 20 00 00 00 ff
[    43.532] (--) NVIDIA(0):   00 46 35 55 51 34 42 30  32 38 37 33 36 36 00 f1
[    43.532] (--) NVIDIA(0):
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
[    43.532] (--) NVIDIA(0):   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

My setup was:

  • Slackware Linux x86-64

  • Nvidia GeForce 780GTX and G92 [GeForce GTS 250]

  • 3.10 <= Linux <= 3.14.33

  • X.Org X Server 1.15.2

  • one monitor on a DVI connector working fine and the other (a PROVIEW 700P MA-782KC for reference) on a VGA connecter with a VGA to DVI converter

At first i suspected Xorg code to break some things, then the VGA converter to be faulty; without great success.

Hopefully an old article on analogbit gave me the solution, with a few adaptations.

First i had to get the EDID from the screen, unfortunately get-edid(1) failed:

root@darkstar:~# get-edid  | od -A x -t x1z -v
This is read-edid version 3.0.1. Prepare for some fun.
Attempting to use i2c interface
No EDID on bus 2
2 potential busses found: 0 1
Will scan through until the first EDID is found.
Pass a bus number as an option to this program to go only for that one.
128-byte EDID successfully retrieved from i2c bus 0
If this isn't what you were looking for, consider the other potential busses.
Looks like i2c was successful. Have a good day.
000000 00 ff ff ff ff ff ff 00 4c 2d b6 02 34 32 55 48  >........L-..42UH<
000010 0e 12 01 03 80 34 20 a0 2a 5a d1 a7 56 4b 9b 24  >.....4 .*Z..VK.$<
000020 13 50 54 bf ef 80 a9 40 81 80 81 40 71 4f 01 01  >.PT....@...@qO..<
000030 01 01 01 01 01 01 28 3c 80 a0 70 b0 23 40 30 20  >......(<..p.#@0 <
000040 36 00 06 44 21 00 00 1a 00 00 00 fd 00 38 4b 1e  >6..D!........8K.<
000050 51 11 00 0a 20 20 20 20 20 20 00 00 00 fc 00 53  >Q...      .....S<
000060 79 6e 63 4d 61 73 74 65 72 0a 20 20 00 00 00 ff  >yncMaster.  ....<
000070 00 48 53 31 51 33 32 33 32 30 37 0a 20 20 00 c4  >.HS1Q323207.  ..<
000080

root@darkstar:~# get-edid -q -b 1 | hexdump -C
NVIDIA00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000080

root@darkstar:~# get-edid -b 1 | od -A x -t x1z -v
1
This is read-edid version 3.0.1. Prepare for some fun.
Attempting to use i2c interface
No EDID on bus 2
2 potential busses found: 0 1
Only trying 1 as per your request.
Bus 1 doesn't really have an EDID...
Couldn't find an accessible EDID on this computer.
Attempting to use the classical VBE interface

        Performing real mode VBE call
        Interrupt 0x10 ax=0x4f00 bx=0x0 cx=0x0
        Function supported
        Call successful

        VBE version 300
        VBE string at 0x11100 "NVIDIA"

VBE/DDC service about to be called
        Report DDC capabilities

        Performing real mode VBE call
        Interrupt 0x10 ax=0x4f15 bx=0x0 cx=0x0
        Function supported
        Call successful

        Monitor and video card combination does not support DDC1 transfers
        Monitor and video card combination supports DDC2 transfers
        0 seconds per 128 byte EDID block transfer
        Screen is not blanked during DDC transfer

Reading next EDID block

VBE/DDC service about to be called
        Read EDID

        Performing real mode VBE call
        Interrupt 0x10 ax=0x4f15 bx=0x1 cx=0x0
        Function supported
        Call failed

The EDID data should not be trusted as the VBE call failed
EDID claims 255 more blocks left
EDID blocks left is wrong.
Your EDID is probably invalid.
Looks like VBE was successful. Have a good day.
000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000030 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  >................<
000080

On different places (and in the previously named article) it is recommanded to use nvidia-settings to get the EDID, but it obviously didn’t work.

Oh but, remember the “Raw EDID bytes” section in the Xorg log file? What if we convert them (using Python)‽

# Note: data = '00 a0 00 ff ...'
open('/tmp/edid.bin', 'wb').write(
   bytearray(int(h, 16) for h in data.split())
)
root@darkstar:~# od -A x -t x1z -v </tmp/edid.bin
000000 00 a0 00 ff ff ff ff 00 42 93 17 10 86 62 04 00  >........B....b..<
000010 30 0e 01 03 08 22 1b 78 28 ee a6 9e 54 4c 99 26  >0....".x(...TL.&<
000020 19 4f 54 ad cf 00 81 80 01 01 01 01 01 01 01 01  >.OT.............<
000030 01 01 01 01 01 01 30 2a 00 98 51 00 2a 40 30 70  >......0*..Q.*@0p<
000040 13 00 51 0e 11 00 00 1e 00 00 00 fc 00 4d 41 2d  >..Q..........MA-<
000050 37 38 32 4b 43 0a 20 20 20 20 00 00 00 fd 00 3c  >782KC.    .....<<
000060 4b 1e 50 0e 00 0a 20 20 20 20 20 20 00 00 00 ff  >K.P...      ....<
000070 00 46 35 55 51 34 42 30 32 38 37 33 36 36 00 f1  >.F5UQ4B0287366..<
000080

root@darkstar:~# parse-edid < /tmp/edid.bin
WARNING: Checksum failed
Trying to continue...
Header incorrect. Probably not an edid
Something strange happened. Please contact the author,
Matthew Kern at <pyrophobicman@gmail.com>

Hum, close but something is still wrong. Asking to the internets one more time… And, thank you StackExchange (and Wikipedia)!

Edid must begin with
00 FF FF FF FF FF FF 00
data = bytearray(int(h, 16) for h in data.split())
data[0:8] = '\x00\xff\xff\xff\xff\xff\xff\x00'
open('/tmp/edid.bin', 'wb').write(data)
root@darkstar:~# parse-edid < /tmp/edid.bin
Checksum Correct

Section "Monitor"
   Identifier "MA-782KC"
   ModelName "MA-782KC"
   VendorName "PTS"
   # Monitor Manufactured week 48 of 2004
   # EDID version 1.3
   # Analog Display
   DisplaySize 340 270
   Gamma 2.20
   Option "DPMS" "true"
   Horizsync 30-80
   VertRefresh 60-75
   # Maximum pixel clock is 140MHz
   #Not giving standard mode: 1280x1024, 60Hz
   Modeline    "Mode 0" 108.00 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
EndSection

Now that’s more like it; move the file somewhere classy.

Modify /etc/X11/xorg.conf to add in the right Section "Monitor" (example from the Kodi wiki):

Option  "CustomEDID" "CRT-1:/etc/X11/proview_MA-782KC.edid"
Option  "IgnoreEDID" "false"
Option  "UseEDID" "true"

Restart X and voilà.