summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2009-10-02 14:49:27 -0400
committerAdam Jackson <ajax@redhat.com>2009-10-02 14:49:55 -0400
commit532577ebc796596b52b54d89ff967e0ef3070381 (patch)
treecdafbf7598d4edd911a35a96aec34625fc6bd4be
parent99fa31ff43dd5c24fa38b4f52860fa93438d20f9 (diff)
EDID standard timing parse
-rw-r--r--edid.c117
-rw-r--r--minitru.h4
-rw-r--r--mode.c167
3 files changed, 286 insertions, 2 deletions
diff --git a/edid.c b/edid.c
index 2f10b0e..5f3adbb 100644
--- a/edid.c
+++ b/edid.c
@@ -14,6 +14,18 @@ edid_valid_checksum(uint8_t *x)
return !sum;
}
+static int
+edid_version(uint8_t *block)
+{
+ return block[0x12];
+}
+
+static int
+edid_revision(uint8_t *block)
+{
+ return block[0x13];
+}
+
static uint32_t edid_probe(struct mt_monitor *mon)
{
uint8_t *block = mon->block;
@@ -29,6 +41,9 @@ static uint32_t edid_probe(struct mt_monitor *mon)
if (!memcmp(block, header, 8))
return 0;
+ if (edid_version(block) != 1)
+ return 0;
+
for (i = 0; i < 128; i++)
if (!edid_valid_checksum(block + (i * 128)))
return 0;
@@ -87,9 +102,111 @@ edid_established_modes(struct mt_monitor *mon, struct mt_mode *list)
return list;
}
+/* XXX might also be in extension blocks */
+static int
+edid_cvt_supported(uint8_t *block)
+{
+ return block[10] == 0x04;
+}
+
+static int
+edid_monitor_supports_reduced_blanking(uint8_t *block)
+{
+ /* XXX wrong for 1.4 */
+ return block[0x14] && 0x80;
+}
+
+#define LEVEL_DMT 0
+#define LEVEL_GTF 1
+#define LEVEL_CVT 2
+
+static int
+standard_timing_level(uint8_t *block)
+{
+ int revision = edid_revision(block);
+
+ if (revision >= 2) {
+ if (revision >= 4 && edid_cvt_supported(block))
+ return LEVEL_CVT;
+ return LEVEL_GTF;
+ }
+ return LEVEL_DMT;
+}
+
+static uint32_t
+edid_standard_get_vsize(uint8_t *block, uint32_t hsize, uint32_t aspect)
+{
+ switch (aspect) {
+ case 0:
+ if (edid_revision(block) < 3)
+ return hsize;
+ return hsize * 10 / 16;
+ default: /* can't happen */
+ case 1:
+ return hsize * 3 / 4;
+ case 2:
+ return hsize * 4 / 5;
+ case 3:
+ return hsize * 9 / 16;
+ }
+}
+
+static struct mt_mode *
+edid_standard_mode(uint8_t *block, uint32_t hsize, uint32_t aspect,
+ uint32_t refresh)
+{
+ struct mt_mode *mode;
+ uint32_t vsize = edid_standard_get_vsize(block, hsize, aspect);
+ uint32_t rb = edid_monitor_supports_reduced_blanking(block);
+
+ if (hsize == 1360 && vsize == 765 && refresh == 60) {
+ mode = mt_cvt_mode(1366, 768, 60, 0);
+ mode->hdisplay = 1366;
+ mode->vsyncstart--;
+ mode->vsyncend--;
+ return mode;
+ }
+
+ mode = find_dmt_mode(hsize, vsize, refresh, rb);
+
+ if (!mode) {
+ int timing_level = standard_timing_level(block);
+ if (timing_level == LEVEL_CVT)
+ /* XXX maybe RB? */
+ return mt_cvt_mode(hsize, vsize, refresh, 0);
+ if (timing_level == LEVEL_GTF)
+ return mt_gtf_mode(hsize, vsize, refresh, 0);
+ }
+
+ return NULL;
+}
+
+static int
+bad_standard_code(uint8_t b1, uint8_t b2)
+{
+ return (b1 == 0x00 && b2 == 0x00) ||
+ (b1 == 0x01 && b2 == 0x01) ||
+ (b1 == 0x20 && b2 == 0x20);
+}
+
static struct mt_mode *
edid_standard_modes(struct mt_monitor *mon, struct mt_mode *list)
{
+ uint8_t i, *block = mon->block;
+
+ for (i = 0; i < 8; i++) {
+ uint8_t b1 = block[0x26 + i * 2], b2 = block[0x26 + i * 2 + 1];
+
+ if (bad_standard_code(b1, b2))
+ continue;
+
+ list = mt_modes_add(list,
+ edid_standard_mode(block,
+ (b1 + 31) * 8,
+ (b2 >> 6) & 0x3,
+ 60 + (b2 & 0x3f)));
+ }
+
return list;
}
diff --git a/minitru.h b/minitru.h
index adffce3..4256321 100644
--- a/minitru.h
+++ b/minitru.h
@@ -80,8 +80,8 @@ extern struct mt_mode *mt_gtf_mode(uint32_t width, uint32_t height,
extern struct mt_mode *mt_modes_add(struct mt_mode *modes, struct mt_mode *);
extern struct mt_mode *mt_mode_copy(const struct mt_mode *mode);
-extern float mt_mode_hsync(struct mt_mode *mode);
-extern float mt_mode_vsync(struct mt_mode *mode);
+extern float mt_mode_hsync(const struct mt_mode *mode);
+extern float mt_mode_vsync(const struct mt_mode *mode);
extern uint32_t mt_mode_is_reduced_blanking(struct mt_mode *mode);
diff --git a/mode.c b/mode.c
new file mode 100644
index 0000000..714aa9e
--- /dev/null
+++ b/mode.c
@@ -0,0 +1,167 @@
+#include "minitru-int.h"
+
+struct mt_mode *
+mt_modes_add(struct mt_mode *modes, struct mt_mode *new)
+{
+ if (!modes)
+ return new;
+
+ if (new) {
+ struct mt_mode *m = modes;
+
+ while (m->next)
+ m = m->next;
+
+ m->next = new;
+ }
+
+ return modes;
+}
+
+hidden struct mt_mode *
+mt_mode_alloc(void)
+{
+ return calloc(1, sizeof(struct mt_mode));
+}
+
+struct mt_mode *
+mt_mode_copy(const struct mt_mode *mode)
+{
+ struct mt_mode *ret = mt_mode_alloc();
+
+ memcpy(ret, mode, sizeof(*ret));
+
+ return ret;
+}
+
+float
+mt_mode_hsync(const struct mt_mode *mode)
+{
+ return (float)mode->clock / (float)mode->htotal;
+}
+
+float
+mt_mode_vsync(const struct mt_mode *mode)
+{
+ float refresh = mode->clock * 1000.0 / mode->htotal / mode->vtotal;
+
+ if (mode->flags & MT_FLAG_INTERLACED)
+ refresh *= 2;
+ if (mode->flags & MT_FLAG_DBLSCAN)
+ refresh /= 2;
+
+ return refresh;
+}
+
+static int
+mode_refresh(const struct mt_mode *mode)
+{
+ return (int)(mt_mode_vsync(mode) + 0.5);
+}
+
+/* XXX fix RB flags */
+static const struct mt_mode dmt_modes[] = {
+ { 0, 0, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC }, /* 640x350@85Hz */
+ { 0, 0, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 640x400@85Hz */
+ { 0, 0, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 720x400@85Hz */
+ { 0, 0, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@60Hz */
+ { 0, 0, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@72Hz */
+ { 0, 0, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@75Hz */
+ { 0, 0, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@85Hz */
+ { 0, 0, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@56Hz */
+ { 0, 0, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@60Hz */
+ { 0, 0, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@72Hz */
+ { 0, 0, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@75Hz */
+ { 0, 0, 56250, 800, 832, 896, 1048, 0, 600, 601, 604, 631, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@85Hz */
+ { 0, 0, 73250, 800, 848, 880, 960, 0, 600, 603, 607, 636, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 800x600@120Hz RB */
+ { 0, 0, 33750, 848, 864, 976, 1088, 0, 480, 486, 494, 517, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 848x480@60Hz */
+ { 0, 0, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC | MT_FLAG_INTERLACED }, /* 1024x768@43Hz (interlaced) */
+ { 0, 0, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 1024x768@60Hz */
+ { 0, 0, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 1024x768@70Hz */
+ { 0, 0, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1024x768@75Hz */
+ { 0, 0, 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1024x768@85Hz */
+ { 0, 0, 115500, 1024, 1072, 1104, 1184, 0, 768, 771, 775, 813, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1024x768@120Hz RB */
+ { 0, 0, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1152x864@75Hz */
+ { 0, 0, 68250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 790, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x768@60Hz RB */
+ { 0, 0, 79500, 1280, 1344, 1472, 1664, 0, 768, 771, 778, 798, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x768@60Hz */
+ { 0, 0, 102250, 1280, 1360, 1488, 1696, 0, 768, 771, 778, 805, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x768@75Hz */
+ { 0, 0, 117500, 1280, 1360, 1496, 1712, 0, 768, 771, 778, 809, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x768@85Hz */
+ { 0, 0, 140250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 813, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x768@120Hz RB */
+ { 0, 0, 71000, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 823, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x800@60Hz RB */
+ { 0, 0, 83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x800@60Hz */
+ { 0, 0, 106500, 1280, 1360, 1488, 1696, 0, 800, 803, 809, 838, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x800@75Hz */
+ { 0, 0, 122500, 1280, 1360, 1496, 1712, 0, 800, 803, 809, 843, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x800@85Hz */
+ { 0, 0, 146250, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 847, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x800@120Hz RB */
+ { 0, 0, 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x960@60Hz */
+ { 0, 0, 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x960@85Hz */
+ { 0, 0, 175500, 1280, 1328, 1360, 1440, 0, 960, 963, 967, 1017, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x960@120Hz RB */
+ { 0, 0, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x1024@60Hz */
+ { 0, 0, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x1024@75Hz */
+ { 0, 0, 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x1024@85Hz */
+ { 0, 0, 187250, 1280, 1328, 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x1024@120Hz RB */
+ { 0, 0, 85500, 1360, 1424, 1536, 1792, 0, 768, 771, 777, 795, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1360x768@60Hz */
+ { 0, 0, 148250, 1360, 1408, 1440, 1520, 0, 768, 771, 776, 813, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1360x768@120Hz RB */
+ { 0, 0, 101000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1400x1050@60Hz RB */
+ { 0, 0, 121750, 1400, 1488, 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1400x1050@60Hz */
+ { 0, 0, 156000, 1400, 1504, 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1400x1050@75Hz */
+ { 0, 0, 179500, 1400, 1504, 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1400x1050@85Hz */
+ { 0, 0, 208000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1400x1050@120Hz RB */
+ { 0, 0, 88750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1440x900@60Hz RB */
+ { 0, 0, 106500, 1440, 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1440x900@60Hz */
+ { 0, 0, 136750, 1440, 1536, 1688, 1936, 0, 900, 903, 909, 942, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1440x900@75Hz */
+ { 0, 0, 157000, 1440, 1544, 1696, 1952, 0, 900, 903, 909, 948, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1440x900@85Hz */
+ { 0, 0, 182750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 953, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1440x900@120Hz RB */
+ { 0, 0, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@60Hz */
+ { 0, 0, 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@65Hz */
+ { 0, 0, 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@70Hz */
+ { 0, 0, 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@75Hz */
+ { 0, 0, 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@85Hz */
+ { 0, 0, 268250, 1600, 1648, 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1600x1200@120Hz RB */
+ { 0, 0, 119000, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1680x1050@60Hz RB */
+ { 0, 0, 146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1680x1050@60Hz */
+ { 0, 0, 187000, 1680, 1800, 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1680x1050@75Hz */
+ { 0, 0, 214750, 1680, 1808, 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1680x1050@85Hz */
+ { 0, 0, 245500, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1680x1050@120Hz RB */
+ { 0, 0, 204750, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1792x1344@60Hz */
+ { 0, 0, 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1792x1344@75Hz */
+ { 0, 0, 333250, 1792, 1840, 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1792x1344@120Hz RB */
+ { 0, 0, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1856x1392@60Hz */
+ { 0, 0, 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1856x1392@75Hz */
+ { 0, 0, 356500, 1856, 1904, 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1856x1392@120Hz RB */
+ { 0, 0, 154000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1920x1200@60Hz RB */
+ { 0, 0, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1200@60Hz */
+ { 0, 0, 245250, 1920, 2056, 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1200@75Hz */
+ { 0, 0, 281250, 1920, 2064, 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1200@85Hz */
+ { 0, 0, 317000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1920x1200@120Hz RB */
+ { 0, 0, 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1440@60Hz */
+ { 0, 0, 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1440@75Hz */
+ { 0, 0, 380500, 1920, 1968, 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1920x1440@120Hz RB */
+ { 0, 0, 268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 2560x1600@60Hz RB */
+ { 0, 0, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 2560x1600@60Hz */
+ { 0, 0, 443250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 2560x1600@75Hz */
+ { 0, 0, 505250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 2560x1600@85Hz */
+ { 0, 0, 552750, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 2560x1600@120Hz RB */
+};
+
+static const int num_dmt_modes;
+
+hidden struct mt_mode *
+find_dmt_mode(uint32_t hsize, uint32_t vsize, uint32_t refresh, uint32_t rb)
+{
+ const struct mt_mode *ret;
+ int i;
+
+ for (i = 0; i < num_dmt_modes; i++) {
+ ret = dmt_modes + i;
+
+ if (!rb && (ret->flags & MT_FLAG_REDUCED))
+ continue;
+
+ if (ret->hdisplay == hsize &&
+ ret->vdisplay == vsize &&
+ refresh == mode_refresh(ret))
+ return mt_mode_copy(ret);
+ }
+
+ return NULL;
+}