Wednesday, March 2, 2011

Adding custom video timings in kernel display subsystem.

Early this year I got a 42'' NEC display with a touchscreen sensor integrated to test with my BeagleBoard (BB) C2 rev. I had tested it with an Android FS gotten from rowboat in other displays (LG and ViewSonic) just setting up the video bootargs and it worked nicely with all standard resolutions. To my surprise the NEC display only was supporting one standard resolutions, for the rest of the resolutions I was getting "input not supported" message in the display. In this post I am going to go over the steps I followed to overcome this issue (rather than copy-paste info from other sites I will use links to give them credit).

This is an example of the video bootargs I use to set a resolution of 720p:
vram=4M omapdss.def_disp=dvi omapfb.mode=dvi:1280x720MR-16@60

For more info about these params take a look at frame buffer documentation.

First thing I did was to set these resolutions  (1280x1024, 720p, 800x600, etc) from Ubuntu just to make sure there were no HW limitations from the display. In Ubuntu all resolutions work as expected.

Then using the program moninfo in Windows I got the EDID information from the display to make sure that the modelines that were getting set by the BB were within the operation range.

More information about modelines and calculating timing parameters can be found in the following links:
http://www.epanorama.net/documents/vga2rgb/timings.html
http://sgf-dma.blogspot.com/2011/01/notes-for-xfree86-video-timings-howto.html
http://groups.google.com/group/beagleboard/browse_thread/thread/155dc4da296be2e9/2bfbaa25cd74c913?lnk=gst&q=fbmode#2bfbaa25cd74c913

To get the current modeline configured by the video driver I used the following command:
 # cat /sys/devices/platform/omapdss/display0/timings
 Which returns the video timings in the following format:
<pixel_clock>,<xres/hfp/hbp/hsw>,<yres/vfp/vbp/vsw>

Other useful commands can be found at:
http://processors.wiki.ti.com/index.php/DSS2_SYSFS_Examples

The output of the timing information was compliant with the EDID requirements from the Display so not sure why the display was so picky.

Looking at modedb.c and fbcvt.c (in androidRoot/kernel/drivers/video) I realized that when the omapfb.mode argument had "MR" option specified the video subsystem dinamically computed the timings based on CVT standard. Using "MR" the only video bootarg that worked was omapfb.mode=dvi: 1440x1050MR-16@60'. However it did not worked quiet good, when I queried the timing information the following was returned:
86400,1440/80/48/32,1050/3/17/10

Pixel clock 86.4 MHz,
Total Horizontal pixels 1440+80+48+32 = 1600
Total Vertical pixels  1050+3+17+10= 1080
So the frame rate is 86.4MHz/(1600*1080) = 50Hz  but the frame rate I specified was 60Hz!.. any way at least I was happy one resolution was working.

If "MR" is not specified in the omapfb.mode bootarg, the video subsystem tries different entries from the array modedb in modedb.c and uses the best match. I tested again all the resolution without including "MR" and only omapfb.mode=dvi:800x600-16@60 worked correctly.


Then I realized that if I generated modelines based on the timings
from the modelines of the working resolutions ( 1440x1050@50 or
800x600@60) any resolution (smaller than the base resolution) can be
displayed:
i.e., if I want 720p I base on:
"1440x1050" 86.4 1440 1520 1552 1600 1050 1053 1063 1080
and just modify the horizontal and vertical front porch:
"1280x720" 86.4 1280 1520 1552 1600 720 1053 1063 1080
To get a resolution of 640x480@60 I did something similar, I based on: "800x600" 40 800 888 1016 1056 600 623 627 628
And modify it to:
"640x480" 40 640 888 1016 1056 480 623 627 628

Following this approach, I added new entries to the structure modedb in modedb.c.

This works, but it has at least three drawbacks I have had identified:

1. The pixel clock is higher than the ideal.
2. When I use 1440x1050 as the base resolution the best refresh rate I can get is 50 fps which could cause flicker effect.
3. Without "MR" CVT is not used. CVT as I understand has features to reduce the blanking period (this is needed for CRT monitors to do the retrace from right to left) and thus reducing the video bandwidth.

My next step is to identify what is the modeline set by Windows or Ubuntu for the resolutions I want to use and then add those entries to the modedb array. In this link it is explained how to get the current modelines from Windows and Ubuntu but I have not tried it yet:
http://www.x.org/wiki/FAQVideoModes#ObtainingmodelinesfromWindowsprogramPowerStrip

If you have other ideas, please let me know.

P.O. I did three programs to convert among the video timing formats return by the:
1) cat /sys/devices/platform/omapdss/display0/timings
2) modeline format in modedb array
3) output returned by cvt command.
 I did not find a way to attach the files here but if you need them I will be glad to share them.

3 comments:

  1. Gari,
    Thanks for the wonderful posts , would you share your programs to convert the display timings. Also I would need advice on how to change the Android Color space according to my requirements .

    Thanks a lot , again...

    ReplyDelete
  2. Hi Shar,

    Sure, I copied the files to http://www.calltimerpro.com/files.zip.

    Regarding the Android Color spaces I have not worked with it..

    Regards!

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete