Friday 26 July 2013

EDID Reading

I haven't posted in a while, so here's a little bit of a brain dump about EDID on Beagle hardware with some sample debugging output from the BeagleBoard-xM towards the end.

Lately, I've been working on implementing support in Minix for reading Extended Display Identification Data (EDID). EDID contains information about your monitor (resolution, etc). The data resides on a chip in your monitor. It's read using I2C (well, technically I think it's DDC, but it's on the I2C bus). The general idea is that the frame buffer driver will query the EDID and configure itself with the optimal resolution, sync rates, etc. On the BeagleBoard-xM, the EDID is at slave address 0x50 on the third I2C bus. For the original BeagleBone (White), the EDID is at slave address 0x50 on the second I2C bus, assuming you're using the DVI cape. The programming for doing the reading is rather simple, it's done the same way as reading from an EEPROM: write 0x00 with a STOP and then do a 128 byte read.

For the BeagleBone Black, it's a lot more complicated. EDID reading goes through the TDA19988. The TDA19988 has two slave addresses (0x34 for CEC and 0x70 for HDMI). When the chip powers up, the HDMI interface is disabled by default. You have to enable it through the CEC interface. Then you need to setup interrupts, send a read request, poll a status register waiting for the interrupt to fire, and then you can read the EDID. Last week I got the point where my TDA19988 driver can detect if a monitor is connected, enable the HDMI interface, and read the TDA19988 revision information through the HDMI interface. I've written the code for the rest, but I'm waiting on a cable to fully test it (my uHDMI to VGA adapter doesn't support EDID -- I double checked in Linux); I should have the cable this weekend.

I did manage to get the right HDMI to DVI cable to do some testing of my work in progress code on the BeagleBoard-xM. Below is a screen dump of the debug output. I start the EEPROM driver for slave address 0x50 on I2C bus 3, I start the frame buffer driver with arguments to point it at the EEPROM driver, and then I run a program which feeds the frame buffer driver some images to display. You'll see that when the frame buffer init code runs, it looks up the EEPROM driver and requests the data. Then the frame buffer driver validates, parses, and displays the EDID. I'm using the NetBSD EDID code for that last part. I committed some EDID documentation fixes back to NetBSD.

# cd /dev && MAKEDEV eepromb3s50
# service up /usr/sbin/cat24c256 -dev /dev/eepromb3s50 -label cat24c256.3.50 -args 'bus=3 address=0x50'
# service up /usr/sbin/fb -dev /dev/fb0 -args edid.0=cat24c256.3.50
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+67(fb_edid_args_parse):Found key:edid.0 value:cat24c256.3.50
framebuffer fresh: pid 140
# splash
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+154(fb_edid_read):Contacting cat24c256.3.50 to get EDID.
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+123(do_read):REP=0
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+178(fb_edid_read):EDID Retrieved and Parsed OK
fb(debug):/home/tcort/repos/i2c/src/drivers/fb/arch/earm/fb_arch.c+311(arch_fb_init):Configuring Settings based on EDID...
fb(debug):/home/tcort/repos/i2c/src/drivers/fb/arch/earm/fb_arch.c+142(configure_with_edid):--- EDID - START ---
Vendor: [AOC] AOC
Product: [1902] G19LWk
Serial number: 93169CA001110
Manufactured 2006 Week 36
EDID Version 1.3
EDID Comment: 
Video Input: 81
Digital (DFP 1.x compatible)
Gamma: 2.20
Max Size: 41 cm x 26 cm
Features: 2a
DPMS active-off
RGB
Preferred timing
Chroma Info:
Red X: 0.635
Red Y: 0.635
Grn X: 0.290
Grn Y: 0.588
Blu X: 0.142
Blu Y: 0.080
Wht X: 0.313
Wht Y: 0.329
Range:
Horizontal: 30 - 83 kHz
Vertical: 50 - 76 Hz
Max Dot Clock: 140 MHz
Video modes:
720x400 @ 70Hz (28320 738 846 900 412 414 449 -H +V)
640x480 @ 60Hz (25175 656 752 800 490 492 525 -H -V)
640x480 @ 73Hz (31500 664 704 832 489 492 520 -H -V)
640x480 @ 75Hz (31500 656 720 840 481 484 500 -H -V)
800x600 @ 56Hz (36000 824 896 1024 601 603 625 +H +V)
800x600 @ 60Hz (40000 840 968 1056 601 605 628 +H +V)
800x600 @ 72Hz (50000 856 976 1040 637 643 666 +H +V)
800x600 @ 75Hz (49500 816 896 1056 601 604 625 +H +V)
832x624 @ 75Hz (57284 864 928 1152 625 628 667 -H -V)
1024x768 @ 60Hz (65000 1048 1184 1344 771 777 806 -H -V)
1024x768 @ 70Hz (75000 1048 1184 1328 771 777 806 -H -V)
1024x768 @ 75Hz (78750 1040 1136 1312 769 772 800 +H +V)
1280x1024 @ 75Hz (135000 1296 1440 1688 1025 1028 1066 +H +V)
1280x1024 @ 60Hz (108000 1328 1440 1688 1025 1028 1066 +H +V)
1152x864 @ 75Hz (108000 1216 1344 1600 865 868 900 +H +V)
1280x960 @ 60Hz (108000 1376 1488 1800 961 964 1000 +H +V)
1440x900 @ 75Hz (136492 1536 1688 1936 901 904 940 +H +V)
1440x900 @ 60Hz (106470 1520 1672 1904 901 904 932 +H +V)
1440x900 @ 61Hz (108000 1520 1672 1904 903 909 934 +H +V)
Preferred mode: 1440x900 @ 61Hz
fb(debug):/home/tcort/repos/i2c/src/drivers/fb/arch/earm/fb_arch.c+144(configure_with_edid):--- EDID - END ---

Now that the frame buffer driver can get the EDID, the next step is to actually configure the frame buffer driver using the EDID information. This will be a bit of a learning, but I'm looking forward to learning the details of graphics drivers like what a "horizontal front porch" is. Another next step is testing the TDA19988 driver. I'll let you know how it goes in my report on Sunday.

No comments:

Post a Comment