Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163942
b: refs/heads/master
c: 882f021
h: refs/heads/master
v: v3
  • Loading branch information
Zhao Yakui authored and Dave Airlie committed Aug 30, 2009
1 parent 7d8fc8b commit cd0888c
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 785b93ef8c309730c2de84ce9c229e40e2d01480
refs/heads/master: 882f0219518196a94cd2772004e87b178467139a
120 changes: 119 additions & 1 deletion trunk/drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
/* use +hsync +vsync for detailed mode */
#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
/* define the number of Extension EDID block */
#define MAX_EDID_EXT_NUM 4

#define LEVEL_DMT 0
#define LEVEL_GTF 1
Expand Down Expand Up @@ -597,6 +599,122 @@ static int add_detailed_info(struct drm_connector *connector,

return modes;
}
/**
* add_detailed_mode_eedid - get detailed mode info from addtional timing
* EDID block
* @connector: attached connector
* @edid: EDID block to scan(It is only to get addtional timing EDID block)
* @quirks: quirks to apply
*
* Some of the detailed timing sections may contain mode information. Grab
* it and add it to the list.
*/
static int add_detailed_info_eedid(struct drm_connector *connector,
struct edid *edid, u32 quirks)
{
struct drm_device *dev = connector->dev;
int i, j, modes = 0;
char *edid_ext = NULL;
struct detailed_timing *timing;
struct detailed_non_pixel *data;
struct drm_display_mode *newmode;
int edid_ext_num;
int start_offset, end_offset;
int timing_level;

if (edid->version == 1 && edid->revision < 3) {
/* If the EDID version is less than 1.3, there is no
* extension EDID.
*/
return 0;
}
if (!edid->extensions) {
/* if there is no extension EDID, it is unnecessary to
* parse the E-EDID to get detailed info
*/
return 0;
}

/* Chose real EDID extension number */
edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
MAX_EDID_EXT_NUM : edid->extensions;

/* Find CEA extension */
for (i = 0; i < edid_ext_num; i++) {
edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
/* This block is CEA extension */
if (edid_ext[0] == 0x02)
break;
}

if (i == edid_ext_num) {
/* if there is no additional timing EDID block, return */
return 0;
}

/* Get the start offset of detailed timing block */
start_offset = edid_ext[2];
if (start_offset == 0) {
/* If the start_offset is zero, it means that neither detailed
* info nor data block exist. In such case it is also
* unnecessary to parse the detailed timing info.
*/
return 0;
}

timing_level = standard_timing_level(edid);
end_offset = EDID_LENGTH;
end_offset -= sizeof(struct detailed_timing);
for (i = start_offset; i < end_offset;
i += sizeof(struct detailed_timing)) {
timing = (struct detailed_timing *)(edid_ext + i);
data = &timing->data.other_data;
/* Detailed mode timing */
if (timing->pixel_clock) {
newmode = drm_mode_detailed(dev, edid, timing, quirks);
if (!newmode)
continue;

drm_mode_probed_add(connector, newmode);

modes++;
continue;
}

/* Other timing or info */
switch (data->type) {
case EDID_DETAIL_MONITOR_SERIAL:
break;
case EDID_DETAIL_MONITOR_STRING:
break;
case EDID_DETAIL_MONITOR_RANGE:
/* Get monitor range data */
break;
case EDID_DETAIL_MONITOR_NAME:
break;
case EDID_DETAIL_MONITOR_CPDATA:
break;
case EDID_DETAIL_STD_MODES:
/* Five modes per detailed section */
for (j = 0; j < 5; i++) {
struct std_timing *std;
struct drm_display_mode *newmode;

std = &data->data.timings[j];
newmode = drm_mode_std(dev, std, timing_level);
if (newmode) {
drm_mode_probed_add(connector, newmode);
modes++;
}
}
break;
default:
break;
}
}

return modes;
}

#define DDC_ADDR 0x50
/**
Expand Down Expand Up @@ -656,7 +774,6 @@ static int drm_ddc_read_edid(struct drm_connector *connector,
return ret;
}

#define MAX_EDID_EXT_NUM 4
/**
* drm_get_edid - get EDID data, if available
* @connector: connector we're probing
Expand Down Expand Up @@ -809,6 +926,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
num_modes += add_established_modes(connector, edid);
num_modes += add_standard_modes(connector, edid);
num_modes += add_detailed_info(connector, edid, quirks);
num_modes += add_detailed_info_eedid(connector, edid, quirks);

if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
edid_fixup_preferred(connector, quirks);
Expand Down

0 comments on commit cd0888c

Please sign in to comment.