header image
Home arrow Blog arrow Tips arrow Fix the resolution problem on machines with Nvidia card
Fix the resolution problem on machines with Nvidia card PDF Print E-mail
Written by Han   
Jul 18, 2008 at 10:59 AM

  My Thinkpad T61p (Native resolution 1400x1050) has been running Ubuntu
Linux well in general since I bought it last September. However, after
upgraded to Ubuntu 8.04(Hardy), I have not been able to set the
resolution into 1024x768 or 800x600, even though these resolutions
work perfectly fine both under Windows or under Linux when the open
sourced driver is installed.

 

  At first, I tried to add these modes manually into
 /etc/X11/xorg.conf, unfortunately the binary Nvidia driver is
 designed so that it would read the EDID data from the monitor
 every time X starts, and then those modes which the driver thinks the
 monitor is not capable to run would be dropped, therefore even I had
 inserted those modelines into xorg.conf, they are not available as
 soon as the machine boot into X.

  An old post in the nvnew forum suggested a possible solution, which
 makes use of the "CustomEDID" option that is provided by the binary
 driver and the Phoenix EDID Designer (PED) software(which works flawless
 under wine).

  So here is the proceedure:

   1) Use PED to read the raw EDID data from the monitor (since PED
  reads the data from the register, you will need a windows machine,
  or in my case, I booted into my Windows partition on the T61p)

  2) Manually added (you will need to disable the "read-only" option
  in the "File" menu ) the the 800x600 and 1024x768 modeline using PED,
  and then save the data into ASCII file "mod-edid.dat" via the "save
  as" option. The file should reads something like this:

EDID BYTES:
0x   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
    ------------------------------------------------
00: 00 FF FF FF FF FF FF 00 30 AE 22 40 00 00 00 00
10: 22 11 01 03 80 1D 15 78 EA 6F 95 9C 54 4C 87 26
20: 21 50 54 21 08 00 01 01 01 01 01 01 01 01 01 01
30: 01 01 01 01 01 01 30 2A 78 20 51 1A 10 40 30 70
40: 13 00 1F D7 10 00 00 18 25 23 78 20 51 1A 10 40
50: 30 70 13 00 1F D7 10 00 00 18 00 00 00 0F 00 90
60: 43 32 90 43 28 0F 01 00 30 64 00 55 00 00 00 FE
70: 00 4C 54 44 31 34 31 45 4E 39 42 0A 20 20 00 CE




  3) Edit the file using whatever text editor to remove the first 3
  lines and the first 4 character of each line, and then save it into
  file named "strip-mod-edid.dat", so that the file looks like this:

00 FF FF FF FF FF FF 00 30 AE 22 40 00 00 00 00
22 11 01 03 80 1D 15 78 EA 6F 95 9C 54 4C 87 26
21 50 54 21 08 00 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 30 2A 78 20 51 1A 10 40 30 70
13 00 1F D7 10 00 00 18 25 23 78 20 51 1A 10 40
30 70 13 00 1F D7 10 00 00 18 00 00 00 0F 00 90
43 32 90 43 28 0F 01 00 30 64 00 55 00 00 00 FE
00 4C 54 44 31 34 31 45 4E 39 42 0A 20 20 00 CE

 
  4) compile the following C code, which basically convert the ASCII
  file into binary EDID file that the Nvidia driver could read.

 /* comp.c */ 
#include <stdio.h>
int main()
{
    unsigned int i;
  while (!feof(stdin))
  {
    scanf("%02X ", &i);
    printf("%c", i);
  }
  return 0;
}


 # gcc comp.c -o comp
 # ./comp < strip-mod-edid.dat > strip-mod-edid.edid

  5) copy the file strip-mod-edid.edid to /etc/X11

  6) Modify /etc/X11/xorg.conf, and added the following line into the
  Device section for the Nvidia card:

 option "CustomEDID" "DFP-0:/etc/X11/strip-mod-edid.dat"

  7) restart the computer, and the modelines are now available!

 

EDIT: Because PED requires reading the Windows register to get the EDID data, you can not use it to read the EDID data via Wine as suggested in Step 1). However, the binary Nvidia driver for Linux does provide a way to dump binary EDID data, I have wrote this following C code to convert the Nvidia binary data into .dat file that PED can read and modify.

 /* decomp.c */
#include <stdio.h>
int main()
{
  int n=0;
  unsigned char i;
  printf("EDID BYTES:\r\n");
  printf("0x   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n");
  printf("    ------------------------------------------------");
  while (!feof(stdin) && n<16*8)
  {
    if ((n%16)==0)
        printf("\r\n%d0 | ",n/16);
    else
        printf(" ");
    scanf("%c", &i);
    printf("%02X", i);
    n++;
  }
  printf("\r\n");
  return 0;
}

 

# gcc decomp.c -o decomp

# ./decomp < edidfile.nvidia.bin > edid.for.PED.dat

Edit2: Changed the "unsigned char i" into "unsigned int i" to avoid gcc warning and possible segmentation fault (as suggested by user Korn from the nvnews forum).

 Note: I simply copied the comp.c from the post in nvnews forum, and I wrote the decomp.c for my own uses. I post them here because I think they will be useful for other people. I provide absolutely no warranties or tech support. So use them at your own risk.


User Comments

Comment by on 2009-07-26 12:19:13
PLease help how you add the custom resolution in PED. Can you give a step by step guide. 
 
Thank you.
Your Name / Email Address
Security Check. Please enter this code Listen to code

Last Updated ( Jul 22, 2008 at 11:45 AM )