diff options
author | Yong Zhi <a0132969@dirac.dal.design.ti.com> | 2009-12-02 18:00:57 -0600 |
---|---|---|
committer | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2009-12-04 15:26:24 +0530 |
commit | d298ae1f582675e414ddd4e22b98eeee9abbf7b8 (patch) | |
tree | a03a9786b1c9ff4b11a04e844cc7b7aa64d199d2 | |
parent | bcfb70de4ea4e395b2d4243ee8b26f5b63e40bee (diff) |
HDMI: added EDID reading for default resolution
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 335 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.h | 226 |
2 files changed, 536 insertions, 25 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 9a788313adbe..6203ab376e0f 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -37,6 +37,7 @@ #include <mach/gpio.h> #include "dss.h" +#include "hdmi.h" #define HDMI_PLLCTRL 0x58006200 #define HDMI_PHY 0x58006300 @@ -55,8 +56,9 @@ #define HDMI_TXPHY_DIGITAL_CTRL 0x4ul #define HDMI_TXPHY_POWER_CTRL 0x8ul -void hdmi_read_edid(void); - +static int hdmi_read_edid(void); +static int get_edid_timing_data(u8 *edid, u16 *pixel_clk, u16 *horizontal_res, + u16 *vertical_res); /* CEA-861-D Codes */ const struct omap_video_timings cea861d1 = \ {640, 480, 25200, 96, 16, 48, 2, 10, 33}; @@ -86,8 +88,11 @@ static struct { void __iomem *base_pll; struct mutex lock; int code; + HDMI_Timing_t ti; } hdmi; +struct omap_video_timings omap_dss_hdmi_timings; + static inline void hdmi_write_reg(u32 base, u16 idx, u32 val) { void __iomem *b; @@ -425,6 +430,9 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev) case 10: dssdev->panel.timings = vesad10; break; + case 30: + dssdev->panel.timings = cea861d30; + break; case 16: default: dssdev->panel.timings = cea861d16; @@ -517,14 +525,65 @@ void hdmi_exit(void) iounmap(hdmi.base_phy); } +static void hdmi_gpio_config(int enable) +{ + u32 val; + + if (enable) { + /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ + omap_writel(0x01180118, 0x4A100098); + /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ + omap_writel(0x01180118 , 0x4A10009C); + /* CONTROL_HDMI_TX_PHY */ + omap_writel(0x10000000, 0x4A100610); + + /* GPIO 41 line being muxed */ + val = omap_readl(0x4A100060); + val = FLD_MOD(val, 3, 18, 16); + omap_writel(val, 0x4A100060); + + /* GPIO 60 line being muxed */ + val = omap_readl(0x4A100088); + val = FLD_MOD(val, 1, 19, 19); + val = FLD_MOD(val, 3, 2, 0); + omap_writel(0x3, 0x4A100088); + + /* DATA_OUT */ + val = omap_readl(0x4805513c); + val = FLD_MOD(val, 1, 29, 27); + val = FLD_MOD(val, 1, 10, 7); + omap_writel(val, 0x4805513c); + + /* GPIO_OE */ + val = omap_readl(0x48055134); + val = FLD_MOD(val, 0, 28, 28); + val = FLD_MOD(val, 0, 9, 9); + omap_writel(val, 0x48055134); + + /* GPIO_SETDATAOUT */ + val = omap_readl(0x48055194); + val = FLD_MOD(val, 1, 28, 28); + val = FLD_MOD(val, 1, 9, 9); + omap_writel(val, 0x48055194); + + mdelay(120); + } else { + /* GPIO_OE */ + val = omap_readl(0x48055134); + val = FLD_MOD(val, 1, 28, 28); + val = FLD_MOD(val, 1, 9, 9); + omap_writel(val, 0x48055134); + } +} + static int hdmi_power_on(struct omap_dss_device *dssdev) { int format, pll_idx, mode; int r; hdmi_pll_info *ptr; + struct omap_video_timings *p; mode = 1; - /* use EDID in the future */ switch (hdmi.code) { case 1: case 11: @@ -543,21 +602,44 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) format = 10; pll_idx = 10; break; + case 30: + format = 30; + pll_idx = 6; + break; default: BUG(); } if (hdmi.code == 1 || hdmi.code == 10) - mode = 0; /* DVI mode */ + mode = 0; /* DVI mode */ hdmi_enable_clocks(1); + hdmi_gpio_config(1); + + p = &dssdev->panel.timings; + + /* Try E-DID readings for default settings */ + if (16 == format) { + if (0 == hdmi_read_edid()) + p = &omap_dss_hdmi_timings; + else + DSSERR("Grrr, failed to read E-DID\n"); + } + + hdmi.ti.pixelPerLine = p->x_res; + hdmi.ti.linePerPanel = p->y_res; + hdmi.ti.horizontalBackPorch = p->hbp; + hdmi.ti.horizontalFrontPorch = p->hfp; + hdmi.ti.horizontalSyncPulse = p->hsw; + hdmi.ti.verticalBackPorch = p->vbp; + hdmi.ti.verticalFrontPorch = p->vfp; + hdmi.ti.verticalSyncPulse = p->vsw; + HDMI_W1_StopVideoFrame(HDMI_WP); dispc_enable_digit_out(0); - dispc_go(OMAP_DSS_CHANNEL_DIGIT); - /* config the PLL and PHY first */ ptr = &coef_hdmi[pll_idx]; r = hdmi_pll_program(ptr); @@ -569,8 +651,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) if (r) DSSERR("Failed to start PHY\n"); - DSS_HDMI_CONFIG(HDMI_CORE_SYS, HDMI_CORE_AV, - HDMI_WP, format, mode); + DSS_HDMI_CONFIG(hdmi.ti, format, mode); /* these settings are independent of overlays */ dss_switch_tv_hdmi(1); @@ -603,9 +684,10 @@ static void hdmi_power_off(struct omap_dss_device *dssdev) hdmi_phy_off(HDMI_WP); - /* power off PLL */ HDMI_W1_SetWaitPllPwrState(HDMI_WP, HDMI_PLLPWRCMD_ALLOFF); + hdmi_gpio_config(0); + if (dssdev->platform_disable) dssdev->platform_disable(dssdev); @@ -631,11 +713,11 @@ static int hdmi_enable_display(struct omap_dss_device *dssdev) goto err; } + mutex_unlock(&hdmi.lock); hdmi_power_on(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; err: - mutex_unlock(&hdmi.lock); + return r; } @@ -725,24 +807,227 @@ int hdmi_init_display(struct omap_dss_device *dssdev) return 0; } +static int hdmi_read_edid(void) +{ + int err = -1; + u8 edid[HDMI_EDID_MAX_LENGTH]; + u16 horizontal_res; + u16 vertical_res; + u16 pixel_clk; -#define HDMI_EDID_MAX_LENGTH 256 + memset(edid, 0, HDMI_EDID_MAX_LENGTH); + + if (HDMI_CORE_DDC_READEDID(HDMI_CORE_SYS, edid) == 0) { + if (get_edid_timing_data(edid, &pixel_clk, + &horizontal_res, + &vertical_res)) + err = 0; + } + + return err; +} -void hdmi_read_edid(void) +u16 current_descriptor_addrs; + +void get_horz_vert_timing_info(u8 *edid) { - u32 edid[HDMI_EDID_MAX_LENGTH]; + /*HORIZONTAL FRONT PORCH */ + omap_dss_hdmi_timings.hfp = edid[current_descriptor_addrs + 8]; + /*HORIZONTAL SYNC WIDTH */ + omap_dss_hdmi_timings.hsw = edid[current_descriptor_addrs + 9]; + /*HORIZONTAL BACK PORCH */ + omap_dss_hdmi_timings.hbp = (((edid[current_descriptor_addrs + 4] + & 0x0F) << 8) | + edid[current_descriptor_addrs + 3]) - + (omap_dss_hdmi_timings.hfp + omap_dss_hdmi_timings.hsw); + /*VERTICAL FRONT PORCH */ + omap_dss_hdmi_timings.vfp = ((edid[current_descriptor_addrs + 10] & + 0xF0) >> 4); + /*VERTICAL SYNC WIDTH */ + omap_dss_hdmi_timings.vsw = (edid[current_descriptor_addrs + 10] & + 0x0F); + /*VERTICAL BACK PORCH */ + omap_dss_hdmi_timings.vbp = (((edid[current_descriptor_addrs + 7] & + 0x0F) << 8) | + edid[current_descriptor_addrs + 6]) - + (omap_dss_hdmi_timings.vfp + omap_dss_hdmi_timings.vsw); + + DSSDBG("hfp = %d\n" + "hsw = %d\n" + "hbp = %d\n" + "vfp = %d\n" + "vsw = %d\n" + "vbp = %d\n", + omap_dss_hdmi_timings.hfp, + omap_dss_hdmi_timings.hsw, + omap_dss_hdmi_timings.hbp, + omap_dss_hdmi_timings.vfp, + omap_dss_hdmi_timings.vsw, + omap_dss_hdmi_timings.vbp + ); - omap_writel(0x01180118, 0x4A100098); - omap_writel(0x01180118, 0x4A10009C); - omap_writel(0x10000000, 0x4A100610); +} - /* Do muxing for CEC etc. */ - omap_writel(0x3, 0x4A100060); /* GPIO 40 line being muxed */ - omap_writel(0x3, 0x4A10008A); /*GPIO 61 line being muxed */ - omap_writel(((0x1<<8)|(0x1<<29)), 0x48055130); /* GPIO_ctrl */ - omap_writel(((0x1<<8)|(0x1<<29)), 0x48055134); /*GPIO_OE */ - omap_writel(((0x1<<8)|(0x1<<29)), 0x4805513C); /*GPIO_DATAOUT */ +/*------------------------------------------------------------------------------ + | Function : get_edid_timing_data + +------------------------------------------------------------------------------ + | Description : This function gets the resolution information from EDID + | + | Parameters : void + | + | Returns : void + +----------------------------------------------------------------------------*/ +static int get_edid_timing_data(u8 *edid, u16 *pixel_clk, u16 *horizontal_res, + u16 *vertical_res) +{ + u8 offset, effective_addrs; + u8 count; + u8 i; + u8 flag = false; + /*check for 1080P timing in block0 */ + for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) { + current_descriptor_addrs = + EDID_DESCRIPTOR_BLOCK0_ADDRESS + + count * EDID_TIMING_DESCRIPTOR_SIZE; + *horizontal_res = + (((edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 4 + + count * EDID_TIMING_DESCRIPTOR_SIZE] & 0xF0) << 4) | + edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 2 + + count * EDID_TIMING_DESCRIPTOR_SIZE]); + *vertical_res = + (((edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 7 + + count * EDID_TIMING_DESCRIPTOR_SIZE] & 0xF0) << 4) | + edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 5 + + count * EDID_TIMING_DESCRIPTOR_SIZE]); + + DSSDBG("***Block-0-Timing-descriptor[%d]***\n", count); + for (i = current_descriptor_addrs; + i < + (current_descriptor_addrs+EDID_TIMING_DESCRIPTOR_SIZE); + i++) + DSSDBG("%d ==> %x\n", i, edid[i]); + + DSSDBG("E-EDID Buffer Index = %d\n" + "horizontal_res = %d\n" + "vertical_res = %d\n", + current_descriptor_addrs, + *horizontal_res, + *vertical_res + ); + + if (*horizontal_res == HDMI_XRES && + *vertical_res == HDMI_YRES) { + DSSDBG("Found EDID Data for %d x %dp\n", + *horizontal_res, *vertical_res); + flag = true; + break; + } + else + get_horz_vert_timing_info(edid); + } - memset(edid, 0, HDMI_EDID_MAX_LENGTH); - HDMI_CORE_DDC_READEDID(HDMI_CORE_SYS, edid); + /*check for the 1080p Timing in block1 */ + if (flag != true) { + offset = edid[EDID_DESCRIPTOR_BLOCK1_ADDRESS + 2]; + if (offset != 0) { + effective_addrs = EDID_DESCRIPTOR_BLOCK1_ADDRESS + + offset; + /*to determine the number of descriptor blocks */ + for (count = 0; + count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR; + count++) { + current_descriptor_addrs = effective_addrs + + count * EDID_TIMING_DESCRIPTOR_SIZE; + *horizontal_res = + (((edid[effective_addrs + 4 + + count*EDID_TIMING_DESCRIPTOR_SIZE] & + 0xF0) << 4) | + edid[effective_addrs + 2 + + count * EDID_TIMING_DESCRIPTOR_SIZE]); + *vertical_res = + (((edid[effective_addrs + 7 + + count*EDID_TIMING_DESCRIPTOR_SIZE] & + 0xF0) << 4) | + edid[effective_addrs + 5 + + count * EDID_TIMING_DESCRIPTOR_SIZE]); + + DSSDBG("Block1-Timing-descriptor[%d]\n", count); + + for (i = current_descriptor_addrs; + i < (current_descriptor_addrs+ + EDID_TIMING_DESCRIPTOR_SIZE); i++) + DSSDBG("%x ==> %x\n", + i, edid[i]); + + DSSDBG("current_descriptor = %d\n" + "horizontal_res = %d\n" + "vertical_res = %d\n", + current_descriptor_addrs, + *horizontal_res, *vertical_res); + + if (*horizontal_res == HDMI_XRES && + *vertical_res == HDMI_YRES) { + DSSDBG("Found EDID Data for " + "%d x %dp\n", + *horizontal_res, + *vertical_res + ); + flag = true; + break; + } + else /* yong: print the info */ + get_horz_vert_timing_info(edid); + } + } + } + + if (flag == true) { + *pixel_clk = ((edid[current_descriptor_addrs + 1] << 8) | + edid[current_descriptor_addrs]); + + omap_dss_hdmi_timings.x_res = *horizontal_res; + omap_dss_hdmi_timings.y_res = *vertical_res; + omap_dss_hdmi_timings.pixel_clock = *pixel_clk*10; + DSSDBG("EDID TIMING DATA for 1080p FOUND\n" + "EDID DTD block address = %d\n" + "pixel_clk = %d\n" + "horizontal res = %d\n" + "vertical res = %d\n", + current_descriptor_addrs, + omap_dss_hdmi_timings.pixel_clock, + omap_dss_hdmi_timings.x_res, + omap_dss_hdmi_timings.y_res + ); + + get_horz_vert_timing_info(edid); + } else { + + DSSDBG( + "EDID TIMING DATA supported for 1080p NOT FOUND\n" + "setting default timing values for 720p\n" + "pixel_clk = %d\n" + "horizontal res = %d\n" + "vertical res = %d\n", + __func__, + omap_dss_hdmi_timings.pixel_clock, + omap_dss_hdmi_timings.x_res, + omap_dss_hdmi_timings.y_res + ); + + *pixel_clk = omap_dss_hdmi_timings.pixel_clock; + *horizontal_res = omap_dss_hdmi_timings.x_res; + *vertical_res = omap_dss_hdmi_timings.y_res; + } + + return flag; } + +void hdmi_dump_regs(struct seq_file *s) +{ + DSSDBG("0x4a100060 x%x\n", omap_readl(0x4A100060)); + DSSDBG("0x4A100088 x%x\n", omap_readl(0x4A100088)); + DSSDBG("0x48055134 x%x\n", omap_readl(0x48055134)); + DSSDBG("0x48055194 x%x\n", omap_readl(0x48055194)); +} + + diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h new file mode 100644 index 000000000000..787187c0fdfb --- /dev/null +++ b/drivers/video/omap2/dss/hdmi.h @@ -0,0 +1,226 @@ +/* + * drivers/media/video/omap2/dss/hdmi.h + * + * Copyright (C) 2009 Texas Instruments + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + * hdmi driver + */ +#ifndef _OMAP4_HDMI_H_ +#define _OMAP4_HDMI_H_ + +#define HDMI_XRES 1920 +#define HDMI_YRES 1080 + +#define HDMI_EDID_DETAILED_TIMING_OFFSET 0x36 /*EDID Detailed Timing + Info 0 begin offset*/ +#define HDMI_EDID_PIX_CLK_OFFSET 0 +#define HDMI_EDID_H_ACTIVE_OFFSET 2 +#define HDMI_EDID_H_BLANKING_OFFSET 3 +#define HDMI_EDID_V_ACTIVE_OFFSET 5 +#define HDMI_EDID_V_BLANKING_OFFSET 6 +#define HDMI_EDID_H_SYNC_OFFSET 8 +#define HDMI_EDID_H_SYNC_PW_OFFSET 9 +#define HDMI_EDID_V_SYNC_OFFSET 10 +#define HDMI_EDID_V_SYNC_PW_OFFSET 10 +#define HDMI_EDID_H_IMAGE_SIZE_OFFSET 12 +#define HDMI_EDID_V_IMAGE_SIZE_OFFSET 13 +#define HDMI_EDID_H_BORDER_OFFSET 15 +#define HDMI_EDID_V_BORDER_OFFSET 16 +#define HDMI_EDID_FLAGS_OFFSET 17 + + +#define EDID_TIMING_DESCRIPTOR_SIZE 0x12 +#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36 +#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80 +#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 +#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 + +/* HDMI Connected States */ +#define HDMI_STATE_NOMONITOR 0 /* No HDMI monitor connected*/ +#define HDMI_STATE_CONNECTED 1 /* HDMI monitor connected but powered off*/ +#define HDMI_STATE_ON 2 /* HDMI monitor connected and powered on*/ + + +/* HDMI EDID Length */ +#define HDMI_EDID_MAX_LENGTH 256 + +/* HDMI EDID DTDs */ +#define HDMI_EDID_MAX_DTDS 4 + +/* HDMI EDID DTD Tags */ +#define HDMI_EDID_DTD_TAG_MONITOR_NAME 0xFC +#define HDMI_EDID_DTD_TAG_MONITOR_SERIALNUM 0xFF +#define HDMI_EDID_DTD_TAG_MONITOR_LIMITS 0xFD + + +/* HDMI EDID Extension Data Block Tags */ +#define HDMI_EDID_EX_DATABLOCK_TAG_MASK 0xE0 +#define HDMI_EDID_EX_DATABLOCK_LEN_MASK 0x1F + +#define HDMI_EDID_EX_DATABLOCK_AUDIO 0x20 +#define HDMI_EDID_EX_DATABLOCK_VIDEO 0x40 +#define HDMI_EDID_EX_DATABLOCK_VENDOR 0x60 +#define HDMI_EDID_EX_DATABLOCK_SPEAKERS 0x80 + +/* HDMI EDID Extenion Data Block Values: Video */ +#define HDMI_EDID_EX_VIDEO_NATIVE 0x80 +#define HDMI_EDID_EX_VIDEO_MASK 0x7F +#define HDMI_EDID_EX_VIDEO_MAX 35 + +#define HDMI_EDID_EX_VIDEO_640x480p_60Hz_4_3 1 +#define HDMI_EDID_EX_VIDEO_720x480p_60Hz_4_3 2 +#define HDMI_EDID_EX_VIDEO_720x480p_60Hz_16_9 3 +#define HDMI_EDID_EX_VIDEO_1280x720p_60Hz_16_9 4 +#define HDMI_EDID_EX_VIDEO_1920x1080i_60Hz_16_9 5 +#define HDMI_EDID_EX_VIDEO_720x480i_60Hz_4_3 6 +#define HDMI_EDID_EX_VIDEO_720x480i_60Hz_16_9 7 +#define HDMI_EDID_EX_VIDEO_720x240p_60Hz_4_3 8 +#define HDMI_EDID_EX_VIDEO_720x240p_60Hz_16_9 9 +#define HDMI_EDID_EX_VIDEO_2880x480i_60Hz_4_3 10 +#define HDMI_EDID_EX_VIDEO_2880x480i_60Hz_16_9 11 +#define HDMI_EDID_EX_VIDEO_2880x480p_60Hz_4_3 12 +#define HDMI_EDID_EX_VIDEO_2880x480p_60Hz_16_9 13 +#define HDMI_EDID_EX_VIDEO_1440x480p_60Hz_4_3 14 +#define HDMI_EDID_EX_VIDEO_1440x480p_60Hz_16_9 15 +#define HDMI_EDID_EX_VIDEO_1920x1080p_60Hz_16_9 16 +#define HDMI_EDID_EX_VIDEO_720x576p_50Hz_4_3 17 +#define HDMI_EDID_EX_VIDEO_720x576p_50Hz_16_9 18 +#define HDMI_EDID_EX_VIDEO_1280x720p_50Hz_16_9 19 +#define HDMI_EDID_EX_VIDEO_1920x1080i_50Hz_16_9 20 +#define HDMI_EDID_EX_VIDEO_720x576i_50Hz_4_3 21 +#define HDMI_EDID_EX_VIDEO_720x576i_50Hz_16_9 22 +#define HDMI_EDID_EX_VIDEO_720x288p_50Hz_4_3 23 +#define HDMI_EDID_EX_VIDEO_720x288p_50Hz_16_9 24 +#define HDMI_EDID_EX_VIDEO_2880x576i_50Hz_4_3 25 +#define HDMI_EDID_EX_VIDEO_2880x576i_50Hz_16_9 26 +#define HDMI_EDID_EX_VIDEO_2880x288p_50Hz_4_3 27 +#define HDMI_EDID_EX_VIDEO_2880x288p_50Hz_16_9 28 +#define HDMI_EDID_EX_VIDEO_1440x576p_50Hz_4_3 29 +#define HDMI_EDID_EX_VIDEO_1440x576p_50Hz_16_9 30 +#define HDMI_EDID_EX_VIDEO_1920x1080p_50Hz_16_9 31 +#define HDMI_EDID_EX_VIDEO_1920x1080p_24Hz_16_9 32 +#define HDMI_EDID_EX_VIDEO_1920x1080p_25Hz_16_9 33 +#define HDMI_EDID_EX_VIDEO_1920x1080p_30Hz_16_9 34 + +/*--------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Video Descriptor Block */ +typedef struct { + u8 pixel_clock[2]; /* 54-55 */ + u8 horiz_active; /* 56 */ + u8 horiz_blanking; /* 57 */ + u8 horiz_high; /* 58 */ + u8 vert_active; /* 59 */ + u8 vert_blanking; /* 60 */ + u8 vert_high; /* 61 */ + u8 horiz_sync_offset; /* 62 */ + u8 horiz_sync_pulse; /* 63 */ + u8 vert_sync_pulse; /* 64 */ + u8 sync_pulse_high; /* 65 */ + u8 horiz_image_size; /* 66 */ + u8 vert_image_size; /* 67 */ + u8 image_size_high; /* 68 */ + u8 horiz_border; /* 69 */ + u8 vert_border; /* 70 */ + u8 misc_settings; /* 71 */ +} +HDMI_EDID_DTD_VIDEO; + + +/* Monitor Limits Descriptor Block */ +typedef struct { + u8 pixel_clock[2]; /* 54-55*/ + u8 _reserved1; /* 56 */ + u8 block_type; /* 57 */ + u8 _reserved2; /* 58 */ + u8 min_vert_freq; /* 59 */ + u8 max_vert_freq; /* 60 */ + u8 min_horiz_freq; /* 61 */ + u8 max_horiz_freq; /* 62 */ + u8 pixel_clock_mhz; /* 63 */ + + u8 GTF[2]; /* 64 -65 */ + u8 start_horiz_freq; /* 66 */ + u8 C; /* 67 */ + u8 M[2]; /* 68-69 */ + u8 K; /* 70 */ + u8 J; /* 71 */ +} +HDMI_EDID_DTD_MONITOR; + + +/* Text Descriptor Block */ +typedef struct { + u8 pixel_clock[2]; /* 54-55 */ + u8 _reserved1; /* 56 */ + u8 block_type; /* 57 */ + u8 _reserved2; /* 58 */ + + u8 text[13]; /* 59-71 */ +} +HDMI_EDID_DTD_TEXT; + + +/* DTD Union */ +typedef union { + HDMI_EDID_DTD_VIDEO video; + HDMI_EDID_DTD_TEXT monitor_name; + HDMI_EDID_DTD_TEXT monitor_serial_number; + HDMI_EDID_DTD_MONITOR monitor_limits; +} +HDMI_EDID_DTD; + + +/* EDID struct */ +typedef struct { + u8 header[8]; /* 00-07 */ + u8 manufacturerID[2]; /* 08-09 */ + u8 product_id[2]; /* 10-11 */ + u8 serial_number[4]; /* 12-15 */ + u8 week_manufactured; /* 16 */ + u8 year_manufactured; /* 17 */ + u8 edid_version; /* 18 */ + u8 edid_revision; /* 19 */ + + u8 video_in_definition; /* 20 */ + u8 max_horiz_image_size; /* 21 */ + u8 max_vert_image_size; /* 22 */ + u8 display_gamma; /* 23 */ + u8 power_features; /* 24 */ + u8 chroma_info[10]; /* 25-34 */ + u8 timing_1; /* 35 */ + u8 timing_2; /* 36 */ + u8 timing_3; /* 37 */ + u8 std_timings[16]; /* 38-53 */ + + HDMI_EDID_DTD DTD[4]; /* 72-125 */ + + u8 extension_edid; /* 126 */ + u8 checksum; /* 127 */ + + u8 extension_tag; /* 00 (extensions follow EDID) */ + u8 extention_rev; /* 01 */ + u8 offset_dtd; /* 02 */ + u8 num_dtd; /* 03 */ + + u8 data_block[123]; /* 04 - 126 */ + u8 extension_checksum; /* 127 */ + } +HDMI_EDID; + +#ifdef __cplusplus +}; +#endif + +#endif + + |