summaryrefslogtreecommitdiff
path: root/mode.c
blob: 714aa9e0e9ba4eff5c6bd42bec12a6df0d89a480 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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;
}