Monitors convey their capabilities, such as supported resolution modes, to computers by way of EDID (Extended Display Identification Data.)
Many monitors exist that only have HDMI inputs. HDMI is, of course, backwards compatible with DVI, so simple HDMI to DVI cables allow you to connect these monitors to PCs.
Since these monitors have HDMI inputs, they provide HDMI modes such as 1080p capability through their EDID dada in the CEA block.
Unfortunately for us, nVidia's drivers see these HDMI modes and assume that you must be connected to a TV, and not a computer monitor. Since it thinks this, it sets a special TV mode that applies multiple filters prior to sending the image to the monitor, and it does weird positioning to compensate for overscan.
My monitor is the LG L246WP-BN. On my monitor, these filters result in pushing the output ~80 pixels to the left, and ~20 pixels up, cutting off the top-left of the display, and showing black borders on the bottom-right. The image is so over-sharpened that all text has halos around them.
Worst of all, there is no way to override this behavior through the driver settings. Well, okay, there is some small degree: if you dump your EDID, you can modify it, and tell your OS to use the customized EDID data instead of reading it from the monitor.
On Windows, this is done via the registry key, "OverrideEdidFlags0". On Linux, this is done via the xorg.conf setting, "CustomEDID". You can Google those for more information on how to use them. But the point of this article, is that there is no such setting on the OS X driver. So if you use OS X, you will be forced to use this TV mode. So in this article, I discuss the only workaround for OS X: you have to overwrite the EDID data inside your monitor.
So this article will walk you through the steps I used to overwrite the EDID on my monitor. The steps are applicable to do this for other monitors as well, but you'll have to adapt certain parts accordingly.
Now, just because this guide is about me fixing a specific problem, doesn't mean you can't use the basic steps for other purposes: maybe your EDID was corrupted, maybe it's missing the native resolution for your monitor, maybe you have some other reason for wanting to modify it.
First is the actual EDID format. This is a 128-byte data block. All we are concerned about is the CEA extension block, however. The second to last byte indicates the presence of such a byte, and the very last byte is the checksum of the entire file. It's a value such that adding all 128 bytes together mod 256 will equal zero.
Since it varies per monitor, it needs to be extracted. On Windows, this can be done with the "Phoenix EDID Designer" tool. On OS X, this can be done with SwitchResX. On Linux, this can be done with read-edid or nvidia-settings.
Here is the EDID data for my monitor, for instance:
00 ff ff ff ff ff ff 00 1e 6d 3f 56 d5 e0 00 00 03 11 01 03 8e 34 20 78 ea 5a d5 a7 56 4b 9b 24 13 50 54 a5 4b 00 a9 40 81 8f b3 00 81 4f 81 80 01 01 01 01 01 01 28 3c 80 a0 70 b0 23 40 30 20 36 00 b0 44 11 00 00 1a 48 3f 40 30 62 b0 32 40 40 c0 13 00 b0 44 11 00 00 1e 00 00 00 fd 00 38 4b 1e 53 11 00 0a 20 20 20 20 20 20 00 00 00 fc 00 4c 32 34 36 57 50 0a 20 20 20 20 20 20[01 f6]
So we look at byte #127, which should be 01 to indicate the presence of the CEA extension block. Technically, this byte being set means that the EDID contains an additional 128 bytes for the CEA data. We want to set this to 00 to say that there is no such extension block. And to fix the checksum: since we subtracted one, we add one to the checksum, byte 128. In this instance, we go from f6 to f7 for the checksum. This gives us:
00 ff ff ff ff ff ff 00 1e 6d 3f 56 d5 e0 00 00 03 11 01 03 8e 34 20 78 ea 5a d5 a7 56 4b 9b 24 13 50 54 a5 4b 00 a9 40 81 8f b3 00 81 4f 81 80 01 01 01 01 01 01 28 3c 80 a0 70 b0 23 40 30 20 36 00 b0 44 11 00 00 1a 48 3f 40 30 62 b0 32 40 40 c0 13 00 b0 44 11 00 00 1e 00 00 00 fd 00 38 4b 1e 53 11 00 0a 20 20 20 20 20 20 00 00 00 fc 00 4c 32 34 36 57 50 0a 20 20 20 20 20 20 00 f7
And now that we have our new EDID file ready, all we have to do is write it to our monitor. Simple, right? Er ... well, no. First, let's cover the software side of things.
This is a DOS program that can be used to read and write to EDID. First, you need to find it. The file is "EDID_Writer.zip", and inside you'll find ddcw.exe. Now you need to make an MS-DOS boot CD. Hopefully you still have a floppy drive, or at least a USB floppy drive. Otherwise, you're on your own to make a DOS bootable CD. Note that Windows command-line mode won't work, it has to be pure DOS.
So with a floppy, right-click on the drive from Windows and choose to format the disk. Choose to make an MS-DOS bootable floppy. Once finished, copy all files inside EDID_writer.zip onto the floppy disk, overwriting files as needed.
Now boot from this CD.
To verify the program works, just run "ddcw" once you've booted from the floppy disk. It should print your EDID data to the console. If it fails to do so for any reason, you can't proceed.
Not all video cards can be used to read and write EDID data. Intel and AMD cards supposedly never work (I didn't try any), so you'll want to use nVidia here. My 8800 GTS and GT 210 cards did not work, but my 8400 GS did. You may also want to try multiple computers in case no cards work in one.
If nothing works, you may as well stop now. But assuming you can read out the EDID, you can possibly write it. And now we move on to how to write to the data ...
Internally, your monitor has a small EEPROM that contains the EDID data. To be more specific, each input has its own EEPROM. For instance, the VGA port has its own for valid VGA modes and formats, and the HDMI port has its own as well.
Per the EDID v1.3+ spec, this EEPROM must be write-protected. So we have to bypass this write protection if we want to modify it.
Some monitors simply allow you to write the EDID data anyway. As per above, you see the formatting in the second example (of the modified EDID data) that ddcw expects. Save your EDID data to a text file in a similar format. You can also dump the data from ddcw via "ddcw > output.txt", boot back over to another OS, and hand-edit the data to disable the CEA block.
So from this point, make sure you have connected your monitor to the port whose EDID you wish to overwrite (ostensibly the HDMI port for this tutorial.) And now to write the EDID data, use "ddcw -f edid.txt". Be patient, it will take roughly a minute or so to write the data. A long time for 128 bytes, but that's how it is. When finished, it should tell you that the update was successful.
(Note that I am showing you a successful write. My monitor required the third method listed below, which is why it is shown taken apart here.)
If you'd like, run ddcw.exe again with no arguments to confirm the data has been modified.
If the write fails, your EEPROM is write-protected. Your best bet now is to enter the service mode for your monitor. You can look online for instructions on how to do this. If you can't find any, you'll have to skip to the next method. For the L246WP-BN, you hold menu down while the power is off, and then turn the monitor on, and then release the menu button. The service menu is now accessible in the regular menu.
Once you're inside the service menu and have it onscreen, try writing the EDID per the above step again. If it works, congratulations! Most monitors unlock the EDID write protection in this mode for easy repairs.
If it fails, you are unlucky like me. My monitor's EEPROM remained write-protected still. So this leaves the scariest method of all.
So all else failed: now you get to take your monitor apart. Search online to try and find the service manual for it. LG is really good in this regard, I was easily able to find this, and it even had the board schematics listed in it.
This isn't a necessity, it just helps in telling you how to safely take apart your monitor and possibly where the EEPROM chip is located.
Now, take your monitor apart. You need to get at the main circuit board, right where the HDMI port connects to the board.
The chip we are looking for is the M24C02. Specifically, on my monitor, it's the M24C02-RMN6T chip. It will most likely vary per monitor, but will be very similar in size and function. It should be eight pins, and pin 7 should be /WC, or write control. Confirm your chip's type by reading the information printed on the top of it, and Google its datasheet. Confirm the write control pin number, and confirm that active high means write protection is enabled.
From here, the proper EE solution is to ground the pin. You can do this by wiring a resistor between it and ground. But the quick-and-dirty way for those who are not good with soldering components and picking out the right resistors, is to simply use a small needle and physically pry the pin up off the board. Make sure not to damage the surrounding pins, and make sure the pin is raised enough so that it is not touching the board or any other pins. By doing this, the pin is technically not grounded, but it's also not getting power, so it will effectively disable the write protection.
Now, put your monitor back together, and go back to the first method's instructions and try writing to your EDID again. If it still fails, you are the unluckiest person on the planet. But it should work, and it certainly did for me.
... and that's it! Reboot into your preferred operating system, and the nVidia driver should no longer detect the CEA modes, and it will output a pristene, unmanipulated image to your monitor. Enjoy!