[Intel-gfx] [PATCH] drm/edid: Adding common CVT inferred modes when monitor allows range limited ones trough EDID.

Rodrigo Vivi rodrigo.vivi at gmail.com
Thu Apr 12 02:59:28 CEST 2012


There are many bugs open on fd.o regarding missing modes that are supported on Windows and other closed source drivers.
>From EDID spec we can (might?) infer modes using GTF and CVT when monitor allows it trough range limited flag... obviously limiting by the range.
>From our code:
 * EDID spec says modes should be preferred in this order:
 * - preferred detailed mode
 * - other detailed modes from base block
 * - detailed modes from extension blocks
 * - CVT 3-byte code modes
 * - standard timing codes
 * - established timing codes
 * - modes inferred from GTF or CVT range information
 *
 * We get this pretty much right.

Not actually so right... We were inferring just using GTF... not CVT or even GTF2.
This patch not just add some common cvt modes but also allows some modes been inferred when using gtf2 as well.

Cheers,
Rodrigo.

>From 4b7a88d0d812583d850ca691d1ac491355230d11 Mon Sep 17 00:00:00 2001
From: Rodrigo Vivi <rodrigo.vivi at intel.com>
Date: Wed, 11 Apr 2012 15:36:31 -0300
Subject: [PATCH] drm/edid: Adding common CVT inferred modes when monitor
 allows range limited ones trough EDID.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
---
 drivers/gpu/drm/drm_edid.c       |   37 +++++++++++++-
 drivers/gpu/drm/drm_edid_modes.h |  101 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7ee7be1..3179572 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1020,17 +1020,50 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
 	return modes;
 }
 
+static int
+drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
+			struct detailed_timing *timing)
+{
+	int i, modes = 0;
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+
+	for (i = 0; i < drm_num_cvt_inferred_modes; i++) {
+		if (mode_in_range(drm_cvt_inferred_modes + i, edid, timing)) {
+			newmode = drm_mode_duplicate(dev, &drm_cvt_inferred_modes[i]);
+			if (newmode) {
+				drm_mode_probed_add(connector, newmode);
+				modes++;
+			}
+		}
+	}
+
+	return modes;
+}
+
 static void
 do_inferred_modes(struct detailed_timing *timing, void *c)
 {
 	struct detailed_mode_closure *closure = c;
 	struct detailed_non_pixel *data = &timing->data.other_data;
-	int gtf = (closure->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF);
+	int timing_level = standard_timing_level(closure->edid);
 
-	if (gtf && data->type == EDID_DETAIL_MONITOR_RANGE)
+	if (data->type == EDID_DETAIL_MONITOR_RANGE)
+	    switch (timing_level) {
+	    case LEVEL_DMT:
+		break;
+	    case LEVEL_GTF:
+	    case LEVEL_GTF2:
 		closure->modes += drm_gtf_modes_for_range(closure->connector,
 							  closure->edid,
 							  timing);
+		break;
+	    case LEVEL_CVT:
+		closure->modes += drm_cvt_modes_for_range(closure->connector,
+							  closure->edid,
+							  timing);
+		break;
+	    }
 }
 
 static int
diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
index a91ffb1..7e14a32 100644
--- a/drivers/gpu/drm/drm_edid_modes.h
+++ b/drivers/gpu/drm/drm_edid_modes.h
@@ -266,6 +266,107 @@ static const struct drm_display_mode drm_dmt_modes[] = {
 static const int drm_num_dmt_modes =
 	sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 
+static const struct drm_display_mode drm_cvt_inferred_modes[] = {
+	/* 640x480 at 60Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 23750  640, 664,
+		   720, 800, 0, 480, 483, 487, 500, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 800x600 at 60Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 38250, 800, 832,
+		   912, 1024, 0, 600, 603, 607, 624, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 900x600 at 60Hz */
+	{ DRM_MODE("900x600", DRM_MODE_TYPE_DRIVER, 45250, 960, 992,
+		   1088, 1216, 0, 600, 603, 609, 624, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1024x576 at 60Hz */
+	{ DRM_MODE("1024x576", DRM_MODE_TYPE_DRIVER, 46500, 1024, 1064,
+		   1160, 1296, 0, 576, 579, 584, 599, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1024x768 at 60Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 63500, 1024, 1072,
+		   1176, 1328, 0, 768, 771, 775, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1152x864 at 60Hz */
+	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 81750, 1152, 1216,
+		   1336, 1520, 0, 864, 867, 871, 897, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x720 at 60Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74500, 1280, 1344,
+		   1472, 1664, 0, 720, 723, 728, 748, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x768 at 60Hz */
+	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
+		   1472, 1664, 0, 768, 771, 781, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x800 at 60Hz */
+	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
+		   1480, 1680, 0, 800, 803, 809, 831, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x1024 at 60Hz */
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 109000, 1280, 1368,
+		   1496, 1712, 0, 1024, 1027, 1034, 1063, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1360x768 at 60Hz */
+	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 84750, 1360, 1432,
+		   1568, 1776, 0, 768, 771, 781, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1366x768 at 60Hz */
+	{ DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85250, 1368, 1440,
+		   1576, 1784, 0, 768, 771, 781, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1440x900 at 60Hz */
+	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1528,
+		   1672, 1904, 0, 900, 903, 909, 934, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1400x1050 at 60Hz */
+	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
+		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1600x900 at 60Hz */
+	{ DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 118250, 1600, 1696,
+		   1856, 2112, 0, 900, 903, 908, 934, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1600x1200 at 60Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 161000, 1600, 1712,
+		   1880, 2160, 0, 1200, 1203, 1207, 1245, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1680x945 at 60Hz */
+	{ DRM_MODE("1680x945", DRM_MODE_TYPE_DRIVER, 130750, 1680, 1776,
+		   1952, 2224, 0, 945, 948, 953, 981, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1680x1050 at 60Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
+		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1920x1080 at 60Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 73000, 1920, 2048,
+		   2248, 2576, 0, 1080, 1083, 1088, 1120, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1920x1200 at 60Hz */
+	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
+		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1920x1440 at 60Hz */
+	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 233500, 1920, 2064,
+		   2264, 2608, 0, 1440, 1443, 1447, 1493, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2048x1152 at 60Hz */
+	{ DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 197000, 2048, 2184,
+		   2400, 2752, 0, 1152, 1155, 1160, 1195, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2048x1536 at 60Hz */
+	{ DRM_MODE("2048x1536", DRM_MODE_TYPE_DRIVER, 272000, 2048, 2208,
+		   2424, 2800, 0, 1563, 1566, 1576, 1620, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2560x1600 at 60Hz */
+	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2760,
+		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+};
+static const int drm_num_cvt_inferred_modes =
+	sizeof(drm_cvt_inferred_modes) / sizeof(struct drm_display_mode);
+
 static const struct drm_display_mode edid_est_modes[] = {
 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
 		   968, 1056, 0, 600, 601, 605, 628, 0,
-- 
1.7.7.6




More information about the Intel-gfx mailing list