summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYong Zhi <a0132969@dirac.dal.design.ti.com>2009-12-02 18:00:57 -0600
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2009-12-04 15:26:24 +0530
commitd298ae1f582675e414ddd4e22b98eeee9abbf7b8 (patch)
treea03a9786b1c9ff4b11a04e844cc7b7aa64d199d2
parentbcfb70de4ea4e395b2d4243ee8b26f5b63e40bee (diff)
HDMI: added EDID reading for default resolution
-rw-r--r--drivers/video/omap2/dss/hdmi.c335
-rw-r--r--drivers/video/omap2/dss/hdmi.h226
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
+
+