From 7c57fb7aa86d38aeb121008c90bce5e8341f7802 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 3 Dec 2009 17:44:40 -0500 Subject: [PATCH] --- yaml --- r: 174498 b: refs/heads/master c: 9340d8cfeacd16cef1cbe94527f7baaed7640669 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/drm_edid.c | 48 ++++++++++++++++++++++++++++++++ trunk/include/drm/drm_edid.h | 5 ++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index e46be132c970..0dcb6fc2befa 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2dbdc52c8162291aa7541b8ba6e1c1587f50c1dd +refs/heads/master: 9340d8cfeacd16cef1cbe94527f7baaed7640669 diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index cc8e69682714..30af8f3e6427 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -897,6 +897,51 @@ static int drm_gtf_modes_for_range(struct drm_connector *connector, return modes; } +static int drm_cvt_modes(struct drm_connector *connector, + struct detailed_timing *timing) +{ + int i, j, modes = 0; + struct drm_display_mode *newmode; + struct drm_device *dev = connector->dev; + struct cvt_timing *cvt; + const int rates[] = { 60, 85, 75, 60, 50 }; + + for (i = 0; i < 4; i++) { + int width, height; + cvt = &(timing->data.other_data.data.cvt[i]); + + height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; + switch (cvt->code[1] & 0xc0) { + case 0x00: + width = height * 4 / 3; + break; + case 0x40: + width = height * 16 / 9; + break; + case 0x80: + width = height * 16 / 10; + break; + case 0xc0: + width = height * 15 / 9; + break; + } + + for (j = 1; j < 5; j++) { + if (cvt->code[2] & (1 << j)) { + newmode = drm_cvt_mode(dev, width, height, + rates[j], j == 0, + false, false); + if (newmode) { + drm_mode_probed_add(connector, newmode); + modes++; + } + } + } + } + + return modes; +} + static int add_detailed_modes(struct drm_connector *connector, struct detailed_timing *timing, struct edid *edid, u32 quirks, int preferred) @@ -941,6 +986,9 @@ static int add_detailed_modes(struct drm_connector *connector, } } break; + case EDID_DETAIL_CVT_3BYTE: + modes += drm_cvt_modes(connector, timing); + break; default: break; } diff --git a/trunk/include/drm/drm_edid.h b/trunk/include/drm/drm_edid.h index 9087557fd83d..d33c3e038606 100644 --- a/trunk/include/drm/drm_edid.h +++ b/trunk/include/drm/drm_edid.h @@ -106,6 +106,10 @@ struct detailed_data_color_point { u8 wpindex2[3]; } __attribute__((packed)); +struct cvt_timing { + u8 code[3]; +} __attribute__((packed)); + struct detailed_non_pixel { u8 pad1; u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name @@ -117,6 +121,7 @@ struct detailed_non_pixel { struct detailed_data_monitor_range range; struct detailed_data_wpindex color; struct std_timing timings[5]; + struct cvt_timing cvt[4]; } data; } __attribute__((packed));