[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg
Subject:    [PATCH 8/9] construct video block unified interface, insert SVD
From:       Ma Ling <ling.ma () intel ! com>
Date:       2009-02-27 8:31:56
Message-ID: 1235723516.4119.38.camel () maling-gfx
[Download RAW message or body]

construct unified video block interface, and insert mode into mode list 
according to video short descriptor from CEA extension

---
 hw/xfree86/ddc/interpret_edid.c  |   71 +++++++++++++++++++++++++++
 hw/xfree86/ddc/xf86DDC.h         |    6 ++
 hw/xfree86/modes/xf86EdidModes.c |   98 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index d2a9fb4..91ed930 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -253,6 +253,77 @@ void xf86ForEachDetailedBlock(xf86MonPtr mon,
     }
 }
 
+static struct cea_data_block *
+extract_cea_data_block(Uchar *ext, int data_type)
+{
+    struct cea_ext_body *cea;
+    struct cea_data_block *data_collection;
+    struct cea_data_block *data_end;
+
+    cea = (struct cea_ext_body *)ext;
+
+    if (cea->dt_offset <= CEA_EXT_MIN_DATA_OFFSET)
+        return NULL;
+
+    data_collection = &cea->data_collection;
+    data_end = (struct cea_data_block *)(cea->dt_offset + ext);
+
+    for ( ;data_collection < data_end;) {
+
+	if (data_type == data_collection->tag) {
+	    return data_collection;
+	}
+	data_collection = (unsigned char *)data_collection +
+	    data_collection->len + 1 ;
+    }
+
+    return NULL;
+}
+
+static void handle_cea_video_block(Uchar *ext, handle_video_fn fn, void *data)
+{
+    struct cea_video_block *video;
+    struct cea_video_block *video_end;
+    struct cea_data_block *data_collection;
+
+    data_collection = extract_cea_data_block(ext, CEA_VIDEO_BLK);
+    if (data_collection == NULL)
+        return;
+
+    video = &data_collection->u.video;
+    video_end = (struct cea_video_block *)
+	((Uchar *)video + data_collection->len);
+
+    for (; video < video_end; video = video + 1) {
+	fn(video, data);
+    }
+}
+
+void xf86ForEachVideoBlock(xf86MonPtr mon,
+	                   handle_video_fn fn,
+                           void *data)
+{
+    int i;
+    Uchar *ext;
+
+    if (mon == NULL)
+	return;
+
+    for (i = 0; i < mon->no_sections; i++) {
+	ext = mon->rawData + EDID1_LEN * (i + 1);
+	switch (ext[EXT_TAG]) {
+	case CEA_EXT:
+	    handle_cea_video_block(ext, fn, data);
+	    break;
+	case VTB_EXT:
+	case DI_EXT:
+	case LS_EXT:
+	case MI_EXT:
+	    break;
+	}
+    }
+}
+
 xf86MonPtr
 xf86InterpretEEDID(int scrnIndex, Uchar *block)
 {
diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
index 0f4f65f..d168626 100644
--- a/hw/xfree86/ddc/xf86DDC.h
+++ b/hw/xfree86/ddc/xf86DDC.h
@@ -106,4 +106,10 @@ xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool \
verbose);  void xf86DetTimingApplyQuirks(struct detailed_monitor_section *det_mon,
                               ddc_quirk_t quirks, int hsize, int vsize);
 
+typedef void (* handle_video_fn)(struct cea_video_block *, void *);
+
+void xf86ForEachVideoBlock(xf86MonPtr,
+                           handle_video_fn,
+                           void *);
+
 #endif
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index f7a9916..c522255 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -741,6 +741,100 @@ xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
 	    best->type |= M_T_PREFERRED;
 }
 
+#define CEA_VIDEO_MODES_NUM  64
+static const DisplayModeRec CEAVideoModes[CEA_VIDEO_MODES_NUM] = {
+    { MODEPREFIX,    25175,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, \
V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 1:640x480@60Hz */ +    { MODEPREFIX,    \
27000,  720,  736,  798,  858, 0,  480,  489,  495,  525, 0, V_NHSYNC | V_NVSYNC, \
MODESUFFIX }, /* VIC 2:720x480@60Hz */ +    { MODEPREFIX,    27000,  720,  736,  798, \
858, 0,  480,  489,  495,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC \
3:720x480@60Hz */ +    { MODEPREFIX,    74250, 1280, 1390, 1430, 1650, 0,  720,  725, \
730,  750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 4: 1280x720@60Hz */ +    { \
MODEPREFIX,    74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC \
| V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 5:1920x1080i@60Hz */ +    { \
MODEPREFIX,    27000, 1440, 1478, 1602, 1716, 0,  480,  488,  494,  525, 0, V_NHSYNC \
| V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 6:1440x480i@60Hz */ +    { MODEPREFIX, \
27000, 1440, 1478, 1602, 1716, 0,  480,  488,  494,  525, 0, V_NHSYNC | V_NVSYNC | \
V_INTERLACE, MODESUFFIX }, /* VIC 7:1440x480i@60Hz */ +    { MODEPREFIX,    27000, \
1440, 1478, 1602, 1716, 0,  240,  244,  247,  262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX \
}, /* VIC 8:1440x240@60Hz */ +    { MODEPREFIX,    27000, 1440, 1478, 1602, 1716, 0,  \
240,  244,  247,  262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 9:1440x240@60Hz \
*/ +    { MODEPREFIX,    54000, 2880, 2956, 3204, 3432, 0,  480,  488,  494,  525, 0, \
V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 10:2880x480i@60Hz */ +    { \
MODEPREFIX,    54000, 2880, 2956, 3204, 3432, 0,  480,  488,  494,  525, 0, V_NHSYNC \
| V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 11:2880x480i@60Hz */ +    { \
MODEPREFIX,    54000, 2880, 2956, 3204, 3432, 0,  240,  244,  247,  262, 0, V_NHSYNC \
| V_NVSYNC, MODESUFFIX }, /* VIC 12:2880x240@60Hz */ +    { MODEPREFIX,    54000, \
2880, 2956, 3204, 3432, 0,  240,  244,  247,  262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX \
}, /* VIC 13:2880x240@60Hz */ +    { MODEPREFIX,    54000, 1440, 1472, 1596, 1716, 0, \
480,  489,  495,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 14:1440x480@60Hz \
*/ +    { MODEPREFIX,    54000, 1440, 1472, 1596, 1716, 0,  480,  489,  495,  525, 0, \
V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 15:1440x480@60Hz */ +    { MODEPREFIX,   \
148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, \
MODESUFFIX }, /* VIC 16:1920x1080@60Hz */ +    { MODEPREFIX,    27000,  720,  732,  \
796,  864, 0,  576,  581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC \
17:720x576@50Hz */ +    { MODEPREFIX,    27000,  720,  732,  796,  864, 0,  576,  \
581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 18:720x576@50Hz */ +    \
{ MODEPREFIX,    74250, 1280, 1720, 1760, 1980, 0,  720,  725,  730,  750, 0, \
V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 19: 1280x720@50Hz */ +    { MODEPREFIX,    \
74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | \
V_INTERLACE, MODESUFFIX }, /* VIC 20:1920x1080i@50Hz */ +    { MODEPREFIX,    27000, \
1440, 1464, 1590, 1728, 0,  576,  580,  586,  625, 0, V_NHSYNC | V_NVSYNC | \
V_INTERLACE, MODESUFFIX }, /* VIC 21:1440x576i@50Hz */ +    { MODEPREFIX,    27000, \
1440, 1464, 1590, 1728, 0,  576,  580,  586,  625, 0, V_NHSYNC | V_NVSYNC | \
V_INTERLACE, MODESUFFIX }, /* VIC 22:1440x576i@50Hz */ +    { MODEPREFIX,    27000, \
1440, 1464, 1590, 1728, 0,  288,  290,  293,  312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX \
}, /* VIC 23:1440x288@50Hz */ +    { MODEPREFIX,    27000, 1440, 1464, 1590, 1728, 0, \
288,  290,  293,  312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 24:1440x288@50Hz \
*/ +    { MODEPREFIX,    54000, 2880, 2928, 3180, 3456, 0,  576,  580,  586,  625, 0, \
V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 25:2880x576i@50Hz */ +    { \
MODEPREFIX,    54000, 2880, 2928, 3180, 3456, 0,  576,  580,  586,  625, 0, V_NHSYNC \
| V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 26:2880x576i@50Hz */ +    { \
MODEPREFIX,    54000, 2880, 2928, 3180, 3456, 0,  288,  290,  293,  312, 0, V_NHSYNC \
| V_NVSYNC, MODESUFFIX }, /* VIC 27:2880x288@50Hz */ +    { MODEPREFIX,    54000, \
2880, 2928, 3180, 3456, 0,  288,  290,  293,  312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX \
}, /* VIC 28:2880x288@50Hz */ +    { MODEPREFIX,    54000, 1440, 1464, 1592, 1728, 0, \
576,  581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 29:1440x576@50Hz \
*/ +    { MODEPREFIX,    54000, 1440, 1464, 1592, 1728, 0,  576,  581,  586,  625, 0, \
V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 30:1440x576@50Hz */ +    { MODEPREFIX,   \
148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, \
MODESUFFIX }, /* VIC 31:1920x1080@50Hz */ +    { MODEPREFIX,    74250, 1920, 2558, \
2602, 2750, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC \
32:1920x1080@24Hz */ +    { MODEPREFIX,    74250, 1920, 2448, 2492, 2640, 0, 1080, \
1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 33:1920x1080@25Hz */ + \
{ MODEPREFIX,    74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, \
V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 34:1920x1080@30Hz */ +    { MODEPREFIX,   \
108000, 2880, 2944, 3192, 3432, 0,  480,  489,  495,  525, 0, V_NHSYNC | V_NVSYNC, \
MODESUFFIX }, /* VIC 35:2880x480@60Hz */ +    { MODEPREFIX,   108000, 2880, 2944, \
3192, 3432, 0,  480,  489,  495,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC \
36:2880x480@60Hz */ +    { MODEPREFIX,   108000, 2880, 2928, 3184, 3456, 0,  576,  \
581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 37:2880x576@50Hz */ +   \
{ MODEPREFIX,   108000, 2880, 2928, 3184, 3456, 0,  576,  581,  586,  625, 0, \
V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 38:2880x576@50Hz */ +    { MODEPREFIX,    \
72000, 1920, 1952, 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, V_PHSYNC | V_NVSYNC | \
V_INTERLACE, MODESUFFIX }, /* VIC 39:1920x1080i@50Hz */ +    { MODEPREFIX,   148500, \
1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | \
V_INTERLACE, MODESUFFIX }, /* VIC 40:1920x1080i@100Hz */ +    { MODEPREFIX,   148500, \
1280, 1720, 1760, 1980, 0,  720,  725,  730,  750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX \
}, /* VIC 41:1280x720@100Hz */ +    { MODEPREFIX,    54000,  720,  732,  796,  864, \
0,  576,  581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC \
42:720x576@100Hz */ +    { MODEPREFIX,    54000,  720,  732,  796,  864, 0,  576,  \
581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 43:720x576@100Hz */ +   \
{ MODEPREFIX,    54000, 1440, 1464, 1590, 1728, 0,  576,  580,  586,  625, 0, \
V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 44:1440x576i@100Hz */ +    { MODEPREFIX,    \
54000, 1440, 1464, 1590, 1728, 0,  576,  580,  586,  625, 0, V_NHSYNC | V_NVSYNC, \
MODESUFFIX }, /* VIC 45:1440x576i@100Hz */ +    { MODEPREFIX,   148500, 1920, 2008, \
2052, 2200, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, \
MODESUFFIX }, /* VIC 46:1920x1080i@120Hz */ +    { MODEPREFIX,   148500, 1280, 1390, \
1430, 1650, 0,  720,  725,  730,  750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC \
47:1280x720@120Hz */ +    { MODEPREFIX,    54000,  720,  736,  798,  858, 0,  480,  \
489,  495,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 48:720x480@120Hz */ +   \
{ MODEPREFIX,    54000,  720,  736,  798,  858, 0,  480,  489,  495,  525, 0, \
V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 49:720x480@120Hz */ +    { MODEPREFIX,    \
54000, 1440, 1478, 1602, 1716, 0,  480,  488,  494,  525, 0, V_NHSYNC | V_NVSYNC | \
V_INTERLACE, MODESUFFIX },/* VIC 50:1440x480i@120Hz */ +    { MODEPREFIX,    54000, \
1440, 1478, 1602, 1716, 0,  480,  488,  494,  525, 0, V_NHSYNC | V_NVSYNC | \
V_INTERLACE, MODESUFFIX },/* VIC 51:1440x480i@120Hz */ +    { MODEPREFIX,   108000,  \
720,  732,  796,  864, 0,  576,  581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX \
}, /* VIC 52:720x576@200Hz */ +    { MODEPREFIX,   108000,  720,  732,  796,  864, 0, \
576,  581,  586,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 53:720x576@200Hz \
*/ +    { MODEPREFIX,   108000, 1440, 1464, 1590, 1728, 0,  576,  580,  586,  625, 0, \
V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 54:1440x576i@200Hz */ +    { \
MODEPREFIX,   108000, 1440, 1464, 1590, 1728, 0,  576,  580,  586,  625, 0, V_NHSYNC \
| V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 55:1440x576i@200Hz */ +    { \
MODEPREFIX,   108000,  720,  736,  798,  858, 0,  480,  489,  495,  525, 0, V_NHSYNC \
| V_NVSYNC, MODESUFFIX }, /* VIC 56:720x480@240Hz */ +    { MODEPREFIX,   108000,  \
720,  736,  798,  858, 0,  480,  489,  495,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX \
}, /* VIC 57:720x480@240Hz */ +    { MODEPREFIX,   108000, 1440, 1478, 1602, 1716, 0, \
480,  488,  494,  525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC \
58:1440x480i@240 */ +    { MODEPREFIX,   108000, 1440, 1478, 1602, 1716, 0,  480,  \
488,  494,  525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC \
59:1440x480i@240 */ +    { MODEPREFIX,    59400, 1280, 3040, 3080, 3300, 0,  720,  \
725,  730,  750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 60: 1280x720@24Hz */ +  \
{ MODEPREFIX,    74250, 3700, 3740, 1430, 3960, 0,  720,  725,  730,  750, 0, \
V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 61: 1280x720@25Hz */ +    { MODEPREFIX,    \
74250, 1280, 3040, 3080, 3300, 0,  720,  725,  730,  750, 0, V_PHSYNC | V_PVSYNC, \
MODESUFFIX }, /* VIC 62: 1280x720@30Hz */ +    { MODEPREFIX,   297000, 1920, 2008, \
2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC \
63: 1920x1080@120Hz */ +    { MODEPREFIX,   297000, 1920, 2448, 2492, 2640, 0, 1080, \
1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 64:1920x1080@100Hz */ \
+}; +
+/* chose mode line by cea short video descriptor*/
+static void handle_cea_svd(struct cea_video_block *video, void *data)
+{
+    DisplayModePtr Mode;
+    DisplayModePtr *Modes = (DisplayModePtr *) data;
+    int vid;
+
+    vid = video ->video_code & 0x7f;
+    if (vid < CEA_VIDEO_MODES_NUM) {
+	Mode = xf86DuplicateMode(CEAVideoModes + vid);
+	*Modes = xf86ModesAdd(*Modes, Mode);
+    }
+}
+
+static DisplayModePtr
+DDCModesFromCEAExtension(int scrnIndex, xf86MonPtr MonPtr)
+{
+    DisplayModePtr Modes = NULL;
+
+    xf86ForEachVideoBlock(MonPtr,
+                          handle_cea_svd,
+                          &Modes);
+
+    return Modes;
+}
+
 struct det_modes_parameter {
     xf86MonPtr DDC;
     ddc_quirk_t quirks;
@@ -828,6 +922,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
     Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb);
     Modes = xf86ModesAdd(Modes, Mode);
 
+    /* Add cea-extension mode timings */
+    Mode = DDCModesFromCEAExtension(scrnIndex,DDC);
+    Modes = xf86ModesAdd(Modes, Mode);
+
     if (quirks & DDC_QUIRK_PREFER_LARGE_60)
 	xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
 
-- 
1.5.4.4



_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic