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.v...@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.v...@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to