Line data Source code
1 : /*
2 : * Copyright (c) 2006 Luc Verhaegen (quirks list)
3 : * Copyright (c) 2007-2008 Intel Corporation
4 : * Jesse Barnes <jesse.barnes@intel.com>
5 : * Copyright 2010 Red Hat, Inc.
6 : *
7 : * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
8 : * FB layer.
9 : * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sub license,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice (including the
19 : * next paragraph) shall be included in all copies or substantial portions
20 : * of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : */
30 : #ifdef __linux__
31 : #include <linux/kernel.h>
32 : #include <linux/slab.h>
33 : #include <linux/hdmi.h>
34 : #include <linux/i2c.h>
35 : #include <linux/module.h>
36 : #endif
37 : #include <dev/pci/drm/drmP.h>
38 : #include <dev/pci/drm/drm_edid.h>
39 : #include <dev/pci/drm/drm_displayid.h>
40 :
41 : #define version_greater(edid, maj, min) \
42 : (((edid)->version > (maj)) || \
43 : ((edid)->version == (maj) && (edid)->revision > (min)))
44 :
45 : #define EDID_EST_TIMINGS 16
46 : #define EDID_STD_TIMINGS 8
47 : #define EDID_DETAILED_TIMINGS 4
48 :
49 : /*
50 : * EDID blocks out in the wild have a variety of bugs, try to collect
51 : * them here (note that userspace may work around broken monitors first,
52 : * but fixes should make their way here so that the kernel "just works"
53 : * on as many displays as possible).
54 : */
55 :
56 : /* First detailed mode wrong, use largest 60Hz mode */
57 : #define EDID_QUIRK_PREFER_LARGE_60 (1 << 0)
58 : /* Reported 135MHz pixel clock is too high, needs adjustment */
59 : #define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1)
60 : /* Prefer the largest mode at 75 Hz */
61 : #define EDID_QUIRK_PREFER_LARGE_75 (1 << 2)
62 : /* Detail timing is in cm not mm */
63 : #define EDID_QUIRK_DETAILED_IN_CM (1 << 3)
64 : /* Detailed timing descriptors have bogus size values, so just take the
65 : * maximum size and use that.
66 : */
67 : #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4)
68 : /* Monitor forgot to set the first detailed is preferred bit. */
69 : #define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
70 : /* use +hsync +vsync for detailed mode */
71 : #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
72 : /* Force reduced-blanking timings for detailed modes */
73 : #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7)
74 : /* Force 8bpc */
75 : #define EDID_QUIRK_FORCE_8BPC (1 << 8)
76 : /* Force 12bpc */
77 : #define EDID_QUIRK_FORCE_12BPC (1 << 9)
78 : /* Force 6bpc */
79 : #define EDID_QUIRK_FORCE_6BPC (1 << 10)
80 : /* Force 10bpc */
81 : #define EDID_QUIRK_FORCE_10BPC (1 << 11)
82 :
83 : struct detailed_mode_closure {
84 : struct drm_connector *connector;
85 : struct edid *edid;
86 : bool preferred;
87 : u32 quirks;
88 : int modes;
89 : };
90 :
91 : #define LEVEL_DMT 0
92 : #define LEVEL_GTF 1
93 : #define LEVEL_GTF2 2
94 : #define LEVEL_CVT 3
95 :
96 : static struct edid_quirk {
97 : char vendor[4];
98 : int product_id;
99 : u32 quirks;
100 : } edid_quirk_list[] = {
101 : /* Acer AL1706 */
102 : { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
103 : /* Acer F51 */
104 : { "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
105 : /* Unknown Acer */
106 : { "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
107 :
108 : /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
109 : { "AEO", 0, EDID_QUIRK_FORCE_6BPC },
110 :
111 : /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
112 : { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
113 :
114 : /* Belinea 10 15 55 */
115 : { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
116 : { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
117 :
118 : /* Envision Peripherals, Inc. EN-7100e */
119 : { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
120 : /* Envision EN2028 */
121 : { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
122 :
123 : /* Funai Electronics PM36B */
124 : { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
125 : EDID_QUIRK_DETAILED_IN_CM },
126 :
127 : /* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
128 : { "LGD", 764, EDID_QUIRK_FORCE_10BPC },
129 :
130 : /* LG Philips LCD LP154W01-A5 */
131 : { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
132 : { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
133 :
134 : /* Philips 107p5 CRT */
135 : { "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
136 :
137 : /* Proview AY765C */
138 : { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
139 :
140 : /* Samsung SyncMaster 205BW. Note: irony */
141 : { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
142 : /* Samsung SyncMaster 22[5-6]BW */
143 : { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
144 : { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
145 :
146 : /* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
147 : { "SNY", 0x2541, EDID_QUIRK_FORCE_12BPC },
148 :
149 : /* ViewSonic VA2026w */
150 : { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
151 :
152 : /* Medion MD 30217 PG */
153 : { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
154 :
155 : /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
156 : { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
157 :
158 : /* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
159 : { "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
160 : };
161 :
162 : /*
163 : * Autogenerated from the DMT spec.
164 : * This table is copied from xfree86/modes/xf86EdidModes.c.
165 : */
166 : static const struct drm_display_mode drm_dmt_modes[] = {
167 : /* 0x01 - 640x350@85Hz */
168 : { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
169 : 736, 832, 0, 350, 382, 385, 445, 0,
170 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
171 : /* 0x02 - 640x400@85Hz */
172 : { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
173 : 736, 832, 0, 400, 401, 404, 445, 0,
174 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
175 : /* 0x03 - 720x400@85Hz */
176 : { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
177 : 828, 936, 0, 400, 401, 404, 446, 0,
178 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
179 : /* 0x04 - 640x480@60Hz */
180 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
181 : 752, 800, 0, 480, 490, 492, 525, 0,
182 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
183 : /* 0x05 - 640x480@72Hz */
184 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
185 : 704, 832, 0, 480, 489, 492, 520, 0,
186 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
187 : /* 0x06 - 640x480@75Hz */
188 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
189 : 720, 840, 0, 480, 481, 484, 500, 0,
190 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
191 : /* 0x07 - 640x480@85Hz */
192 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
193 : 752, 832, 0, 480, 481, 484, 509, 0,
194 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
195 : /* 0x08 - 800x600@56Hz */
196 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
197 : 896, 1024, 0, 600, 601, 603, 625, 0,
198 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
199 : /* 0x09 - 800x600@60Hz */
200 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
201 : 968, 1056, 0, 600, 601, 605, 628, 0,
202 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
203 : /* 0x0a - 800x600@72Hz */
204 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
205 : 976, 1040, 0, 600, 637, 643, 666, 0,
206 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
207 : /* 0x0b - 800x600@75Hz */
208 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
209 : 896, 1056, 0, 600, 601, 604, 625, 0,
210 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
211 : /* 0x0c - 800x600@85Hz */
212 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
213 : 896, 1048, 0, 600, 601, 604, 631, 0,
214 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
215 : /* 0x0d - 800x600@120Hz RB */
216 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
217 : 880, 960, 0, 600, 603, 607, 636, 0,
218 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
219 : /* 0x0e - 848x480@60Hz */
220 : { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
221 : 976, 1088, 0, 480, 486, 494, 517, 0,
222 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
223 : /* 0x0f - 1024x768@43Hz, interlace */
224 : { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
225 : 1208, 1264, 0, 768, 768, 772, 817, 0,
226 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
227 : DRM_MODE_FLAG_INTERLACE) },
228 : /* 0x10 - 1024x768@60Hz */
229 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
230 : 1184, 1344, 0, 768, 771, 777, 806, 0,
231 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
232 : /* 0x11 - 1024x768@70Hz */
233 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
234 : 1184, 1328, 0, 768, 771, 777, 806, 0,
235 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
236 : /* 0x12 - 1024x768@75Hz */
237 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
238 : 1136, 1312, 0, 768, 769, 772, 800, 0,
239 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
240 : /* 0x13 - 1024x768@85Hz */
241 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
242 : 1168, 1376, 0, 768, 769, 772, 808, 0,
243 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
244 : /* 0x14 - 1024x768@120Hz RB */
245 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
246 : 1104, 1184, 0, 768, 771, 775, 813, 0,
247 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
248 : /* 0x15 - 1152x864@75Hz */
249 : { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
250 : 1344, 1600, 0, 864, 865, 868, 900, 0,
251 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
252 : /* 0x55 - 1280x720@60Hz */
253 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
254 : 1430, 1650, 0, 720, 725, 730, 750, 0,
255 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
256 : /* 0x16 - 1280x768@60Hz RB */
257 : { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
258 : 1360, 1440, 0, 768, 771, 778, 790, 0,
259 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
260 : /* 0x17 - 1280x768@60Hz */
261 : { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
262 : 1472, 1664, 0, 768, 771, 778, 798, 0,
263 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
264 : /* 0x18 - 1280x768@75Hz */
265 : { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
266 : 1488, 1696, 0, 768, 771, 778, 805, 0,
267 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
268 : /* 0x19 - 1280x768@85Hz */
269 : { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
270 : 1496, 1712, 0, 768, 771, 778, 809, 0,
271 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
272 : /* 0x1a - 1280x768@120Hz RB */
273 : { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
274 : 1360, 1440, 0, 768, 771, 778, 813, 0,
275 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
276 : /* 0x1b - 1280x800@60Hz RB */
277 : { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
278 : 1360, 1440, 0, 800, 803, 809, 823, 0,
279 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
280 : /* 0x1c - 1280x800@60Hz */
281 : { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
282 : 1480, 1680, 0, 800, 803, 809, 831, 0,
283 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
284 : /* 0x1d - 1280x800@75Hz */
285 : { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
286 : 1488, 1696, 0, 800, 803, 809, 838, 0,
287 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
288 : /* 0x1e - 1280x800@85Hz */
289 : { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
290 : 1496, 1712, 0, 800, 803, 809, 843, 0,
291 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
292 : /* 0x1f - 1280x800@120Hz RB */
293 : { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
294 : 1360, 1440, 0, 800, 803, 809, 847, 0,
295 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
296 : /* 0x20 - 1280x960@60Hz */
297 : { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
298 : 1488, 1800, 0, 960, 961, 964, 1000, 0,
299 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
300 : /* 0x21 - 1280x960@85Hz */
301 : { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
302 : 1504, 1728, 0, 960, 961, 964, 1011, 0,
303 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
304 : /* 0x22 - 1280x960@120Hz RB */
305 : { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
306 : 1360, 1440, 0, 960, 963, 967, 1017, 0,
307 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
308 : /* 0x23 - 1280x1024@60Hz */
309 : { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
310 : 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
311 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
312 : /* 0x24 - 1280x1024@75Hz */
313 : { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
314 : 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
315 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
316 : /* 0x25 - 1280x1024@85Hz */
317 : { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
318 : 1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
319 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
320 : /* 0x26 - 1280x1024@120Hz RB */
321 : { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
322 : 1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
323 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
324 : /* 0x27 - 1360x768@60Hz */
325 : { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
326 : 1536, 1792, 0, 768, 771, 777, 795, 0,
327 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
328 : /* 0x28 - 1360x768@120Hz RB */
329 : { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
330 : 1440, 1520, 0, 768, 771, 776, 813, 0,
331 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
332 : /* 0x51 - 1366x768@60Hz */
333 : { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85500, 1366, 1436,
334 : 1579, 1792, 0, 768, 771, 774, 798, 0,
335 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
336 : /* 0x56 - 1366x768@60Hz */
337 : { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 72000, 1366, 1380,
338 : 1436, 1500, 0, 768, 769, 772, 800, 0,
339 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
340 : /* 0x29 - 1400x1050@60Hz RB */
341 : { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
342 : 1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
343 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
344 : /* 0x2a - 1400x1050@60Hz */
345 : { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
346 : 1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
347 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
348 : /* 0x2b - 1400x1050@75Hz */
349 : { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
350 : 1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
351 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
352 : /* 0x2c - 1400x1050@85Hz */
353 : { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
354 : 1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
355 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
356 : /* 0x2d - 1400x1050@120Hz RB */
357 : { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
358 : 1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
359 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
360 : /* 0x2e - 1440x900@60Hz RB */
361 : { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
362 : 1520, 1600, 0, 900, 903, 909, 926, 0,
363 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
364 : /* 0x2f - 1440x900@60Hz */
365 : { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
366 : 1672, 1904, 0, 900, 903, 909, 934, 0,
367 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
368 : /* 0x30 - 1440x900@75Hz */
369 : { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
370 : 1688, 1936, 0, 900, 903, 909, 942, 0,
371 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
372 : /* 0x31 - 1440x900@85Hz */
373 : { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
374 : 1696, 1952, 0, 900, 903, 909, 948, 0,
375 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
376 : /* 0x32 - 1440x900@120Hz RB */
377 : { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
378 : 1520, 1600, 0, 900, 903, 909, 953, 0,
379 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
380 : /* 0x53 - 1600x900@60Hz */
381 : { DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 108000, 1600, 1624,
382 : 1704, 1800, 0, 900, 901, 904, 1000, 0,
383 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
384 : /* 0x33 - 1600x1200@60Hz */
385 : { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
386 : 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
387 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
388 : /* 0x34 - 1600x1200@65Hz */
389 : { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
390 : 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
391 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
392 : /* 0x35 - 1600x1200@70Hz */
393 : { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
394 : 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
395 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
396 : /* 0x36 - 1600x1200@75Hz */
397 : { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
398 : 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
399 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
400 : /* 0x37 - 1600x1200@85Hz */
401 : { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
402 : 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
403 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
404 : /* 0x38 - 1600x1200@120Hz RB */
405 : { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
406 : 1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
407 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
408 : /* 0x39 - 1680x1050@60Hz RB */
409 : { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
410 : 1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
411 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
412 : /* 0x3a - 1680x1050@60Hz */
413 : { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
414 : 1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
415 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
416 : /* 0x3b - 1680x1050@75Hz */
417 : { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
418 : 1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
419 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
420 : /* 0x3c - 1680x1050@85Hz */
421 : { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
422 : 1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
423 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
424 : /* 0x3d - 1680x1050@120Hz RB */
425 : { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
426 : 1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
427 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
428 : /* 0x3e - 1792x1344@60Hz */
429 : { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
430 : 2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
431 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
432 : /* 0x3f - 1792x1344@75Hz */
433 : { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
434 : 2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
435 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
436 : /* 0x40 - 1792x1344@120Hz RB */
437 : { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
438 : 1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
439 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
440 : /* 0x41 - 1856x1392@60Hz */
441 : { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
442 : 2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
443 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
444 : /* 0x42 - 1856x1392@75Hz */
445 : { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
446 : 2208, 2560, 0, 1392, 1393, 1396, 1500, 0,
447 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
448 : /* 0x43 - 1856x1392@120Hz RB */
449 : { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
450 : 1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
451 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
452 : /* 0x52 - 1920x1080@60Hz */
453 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
454 : 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
455 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
456 : /* 0x44 - 1920x1200@60Hz RB */
457 : { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
458 : 2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
459 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
460 : /* 0x45 - 1920x1200@60Hz */
461 : { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
462 : 2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
463 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
464 : /* 0x46 - 1920x1200@75Hz */
465 : { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
466 : 2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
467 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
468 : /* 0x47 - 1920x1200@85Hz */
469 : { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
470 : 2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
471 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
472 : /* 0x48 - 1920x1200@120Hz RB */
473 : { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
474 : 2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
475 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
476 : /* 0x49 - 1920x1440@60Hz */
477 : { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
478 : 2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
479 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
480 : /* 0x4a - 1920x1440@75Hz */
481 : { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
482 : 2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
483 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
484 : /* 0x4b - 1920x1440@120Hz RB */
485 : { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
486 : 2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
487 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
488 : /* 0x54 - 2048x1152@60Hz */
489 : { DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 162000, 2048, 2074,
490 : 2154, 2250, 0, 1152, 1153, 1156, 1200, 0,
491 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
492 : /* 0x4c - 2560x1600@60Hz RB */
493 : { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
494 : 2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
495 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
496 : /* 0x4d - 2560x1600@60Hz */
497 : { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
498 : 3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
499 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
500 : /* 0x4e - 2560x1600@75Hz */
501 : { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
502 : 3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
503 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
504 : /* 0x4f - 2560x1600@85Hz */
505 : { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
506 : 3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
507 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
508 : /* 0x50 - 2560x1600@120Hz RB */
509 : { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
510 : 2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
511 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
512 : /* 0x57 - 4096x2160@60Hz RB */
513 : { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556744, 4096, 4104,
514 : 4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
515 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
516 : /* 0x58 - 4096x2160@59.94Hz RB */
517 : { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
518 : 4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
519 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
520 : };
521 :
522 : /*
523 : * These more or less come from the DMT spec. The 720x400 modes are
524 : * inferred from historical 80x25 practice. The 640x480@67 and 832x624@75
525 : * modes are old-school Mac modes. The EDID spec says the 1152x864@75 mode
526 : * should be 1152x870, again for the Mac, but instead we use the x864 DMT
527 : * mode.
528 : *
529 : * The DMT modes have been fact-checked; the rest are mild guesses.
530 : */
531 : static const struct drm_display_mode edid_est_modes[] = {
532 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
533 : 968, 1056, 0, 600, 601, 605, 628, 0,
534 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
535 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
536 : 896, 1024, 0, 600, 601, 603, 625, 0,
537 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
538 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
539 : 720, 840, 0, 480, 481, 484, 500, 0,
540 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
541 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
542 : 704, 832, 0, 480, 489, 491, 520, 0,
543 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
544 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
545 : 768, 864, 0, 480, 483, 486, 525, 0,
546 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
547 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
548 : 752, 800, 0, 480, 490, 492, 525, 0,
549 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
550 : { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
551 : 846, 900, 0, 400, 421, 423, 449, 0,
552 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
553 : { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
554 : 846, 900, 0, 400, 412, 414, 449, 0,
555 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
556 : { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
557 : 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
558 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
559 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
560 : 1136, 1312, 0, 768, 769, 772, 800, 0,
561 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
562 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
563 : 1184, 1328, 0, 768, 771, 777, 806, 0,
564 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
565 : { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
566 : 1184, 1344, 0, 768, 771, 777, 806, 0,
567 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
568 : { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
569 : 1208, 1264, 0, 768, 768, 776, 817, 0,
570 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
571 : { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
572 : 928, 1152, 0, 624, 625, 628, 667, 0,
573 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
574 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
575 : 896, 1056, 0, 600, 601, 604, 625, 0,
576 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
577 : { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
578 : 976, 1040, 0, 600, 637, 643, 666, 0,
579 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
580 : { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
581 : 1344, 1600, 0, 864, 865, 868, 900, 0,
582 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
583 : };
584 :
585 : struct minimode {
586 : short w;
587 : short h;
588 : short r;
589 : short rb;
590 : };
591 :
592 : static const struct minimode est3_modes[] = {
593 : /* byte 6 */
594 : { 640, 350, 85, 0 },
595 : { 640, 400, 85, 0 },
596 : { 720, 400, 85, 0 },
597 : { 640, 480, 85, 0 },
598 : { 848, 480, 60, 0 },
599 : { 800, 600, 85, 0 },
600 : { 1024, 768, 85, 0 },
601 : { 1152, 864, 75, 0 },
602 : /* byte 7 */
603 : { 1280, 768, 60, 1 },
604 : { 1280, 768, 60, 0 },
605 : { 1280, 768, 75, 0 },
606 : { 1280, 768, 85, 0 },
607 : { 1280, 960, 60, 0 },
608 : { 1280, 960, 85, 0 },
609 : { 1280, 1024, 60, 0 },
610 : { 1280, 1024, 85, 0 },
611 : /* byte 8 */
612 : { 1360, 768, 60, 0 },
613 : { 1440, 900, 60, 1 },
614 : { 1440, 900, 60, 0 },
615 : { 1440, 900, 75, 0 },
616 : { 1440, 900, 85, 0 },
617 : { 1400, 1050, 60, 1 },
618 : { 1400, 1050, 60, 0 },
619 : { 1400, 1050, 75, 0 },
620 : /* byte 9 */
621 : { 1400, 1050, 85, 0 },
622 : { 1680, 1050, 60, 1 },
623 : { 1680, 1050, 60, 0 },
624 : { 1680, 1050, 75, 0 },
625 : { 1680, 1050, 85, 0 },
626 : { 1600, 1200, 60, 0 },
627 : { 1600, 1200, 65, 0 },
628 : { 1600, 1200, 70, 0 },
629 : /* byte 10 */
630 : { 1600, 1200, 75, 0 },
631 : { 1600, 1200, 85, 0 },
632 : { 1792, 1344, 60, 0 },
633 : { 1792, 1344, 75, 0 },
634 : { 1856, 1392, 60, 0 },
635 : { 1856, 1392, 75, 0 },
636 : { 1920, 1200, 60, 1 },
637 : { 1920, 1200, 60, 0 },
638 : /* byte 11 */
639 : { 1920, 1200, 75, 0 },
640 : { 1920, 1200, 85, 0 },
641 : { 1920, 1440, 60, 0 },
642 : { 1920, 1440, 75, 0 },
643 : };
644 :
645 : static const struct minimode extra_modes[] = {
646 : { 1024, 576, 60, 0 },
647 : { 1366, 768, 60, 0 },
648 : { 1600, 900, 60, 0 },
649 : { 1680, 945, 60, 0 },
650 : { 1920, 1080, 60, 0 },
651 : { 2048, 1152, 60, 0 },
652 : { 2048, 1536, 60, 0 },
653 : };
654 :
655 : /*
656 : * Probably taken from CEA-861 spec.
657 : * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.
658 : */
659 : static const struct drm_display_mode edid_cea_modes[] = {
660 : /* 1 - 640x480@60Hz */
661 : { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
662 : 752, 800, 0, 480, 490, 492, 525, 0,
663 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
664 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
665 : /* 2 - 720x480@60Hz */
666 : { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
667 : 798, 858, 0, 480, 489, 495, 525, 0,
668 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
669 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
670 : /* 3 - 720x480@60Hz */
671 : { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
672 : 798, 858, 0, 480, 489, 495, 525, 0,
673 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
674 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
675 : /* 4 - 1280x720@60Hz */
676 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
677 : 1430, 1650, 0, 720, 725, 730, 750, 0,
678 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
679 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
680 : /* 5 - 1920x1080i@60Hz */
681 : { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
682 : 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
683 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
684 : DRM_MODE_FLAG_INTERLACE),
685 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
686 : /* 6 - 720(1440)x480i@60Hz */
687 : { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
688 : 801, 858, 0, 480, 488, 494, 525, 0,
689 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
690 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
691 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
692 : /* 7 - 720(1440)x480i@60Hz */
693 : { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
694 : 801, 858, 0, 480, 488, 494, 525, 0,
695 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
696 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
697 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
698 : /* 8 - 720(1440)x240@60Hz */
699 : { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
700 : 801, 858, 0, 240, 244, 247, 262, 0,
701 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
702 : DRM_MODE_FLAG_DBLCLK),
703 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
704 : /* 9 - 720(1440)x240@60Hz */
705 : { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
706 : 801, 858, 0, 240, 244, 247, 262, 0,
707 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
708 : DRM_MODE_FLAG_DBLCLK),
709 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
710 : /* 10 - 2880x480i@60Hz */
711 : { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
712 : 3204, 3432, 0, 480, 488, 494, 525, 0,
713 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
714 : DRM_MODE_FLAG_INTERLACE),
715 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
716 : /* 11 - 2880x480i@60Hz */
717 : { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
718 : 3204, 3432, 0, 480, 488, 494, 525, 0,
719 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
720 : DRM_MODE_FLAG_INTERLACE),
721 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
722 : /* 12 - 2880x240@60Hz */
723 : { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
724 : 3204, 3432, 0, 240, 244, 247, 262, 0,
725 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
726 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
727 : /* 13 - 2880x240@60Hz */
728 : { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
729 : 3204, 3432, 0, 240, 244, 247, 262, 0,
730 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
731 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
732 : /* 14 - 1440x480@60Hz */
733 : { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
734 : 1596, 1716, 0, 480, 489, 495, 525, 0,
735 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
736 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
737 : /* 15 - 1440x480@60Hz */
738 : { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
739 : 1596, 1716, 0, 480, 489, 495, 525, 0,
740 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
741 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
742 : /* 16 - 1920x1080@60Hz */
743 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
744 : 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
745 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
746 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
747 : /* 17 - 720x576@50Hz */
748 : { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
749 : 796, 864, 0, 576, 581, 586, 625, 0,
750 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
751 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
752 : /* 18 - 720x576@50Hz */
753 : { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
754 : 796, 864, 0, 576, 581, 586, 625, 0,
755 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
756 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
757 : /* 19 - 1280x720@50Hz */
758 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
759 : 1760, 1980, 0, 720, 725, 730, 750, 0,
760 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
761 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
762 : /* 20 - 1920x1080i@50Hz */
763 : { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
764 : 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
765 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
766 : DRM_MODE_FLAG_INTERLACE),
767 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
768 : /* 21 - 720(1440)x576i@50Hz */
769 : { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
770 : 795, 864, 0, 576, 580, 586, 625, 0,
771 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
772 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
773 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
774 : /* 22 - 720(1440)x576i@50Hz */
775 : { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
776 : 795, 864, 0, 576, 580, 586, 625, 0,
777 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
778 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
779 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
780 : /* 23 - 720(1440)x288@50Hz */
781 : { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
782 : 795, 864, 0, 288, 290, 293, 312, 0,
783 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
784 : DRM_MODE_FLAG_DBLCLK),
785 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
786 : /* 24 - 720(1440)x288@50Hz */
787 : { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
788 : 795, 864, 0, 288, 290, 293, 312, 0,
789 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
790 : DRM_MODE_FLAG_DBLCLK),
791 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
792 : /* 25 - 2880x576i@50Hz */
793 : { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
794 : 3180, 3456, 0, 576, 580, 586, 625, 0,
795 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
796 : DRM_MODE_FLAG_INTERLACE),
797 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
798 : /* 26 - 2880x576i@50Hz */
799 : { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
800 : 3180, 3456, 0, 576, 580, 586, 625, 0,
801 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
802 : DRM_MODE_FLAG_INTERLACE),
803 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
804 : /* 27 - 2880x288@50Hz */
805 : { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
806 : 3180, 3456, 0, 288, 290, 293, 312, 0,
807 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
808 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
809 : /* 28 - 2880x288@50Hz */
810 : { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
811 : 3180, 3456, 0, 288, 290, 293, 312, 0,
812 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
813 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
814 : /* 29 - 1440x576@50Hz */
815 : { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
816 : 1592, 1728, 0, 576, 581, 586, 625, 0,
817 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
818 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
819 : /* 30 - 1440x576@50Hz */
820 : { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
821 : 1592, 1728, 0, 576, 581, 586, 625, 0,
822 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
823 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
824 : /* 31 - 1920x1080@50Hz */
825 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
826 : 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
827 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
828 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
829 : /* 32 - 1920x1080@24Hz */
830 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
831 : 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
832 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
833 : .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
834 : /* 33 - 1920x1080@25Hz */
835 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
836 : 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
837 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
838 : .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
839 : /* 34 - 1920x1080@30Hz */
840 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
841 : 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
842 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
843 : .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
844 : /* 35 - 2880x480@60Hz */
845 : { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
846 : 3192, 3432, 0, 480, 489, 495, 525, 0,
847 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
848 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
849 : /* 36 - 2880x480@60Hz */
850 : { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
851 : 3192, 3432, 0, 480, 489, 495, 525, 0,
852 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
853 : .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
854 : /* 37 - 2880x576@50Hz */
855 : { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
856 : 3184, 3456, 0, 576, 581, 586, 625, 0,
857 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
858 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
859 : /* 38 - 2880x576@50Hz */
860 : { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
861 : 3184, 3456, 0, 576, 581, 586, 625, 0,
862 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
863 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
864 : /* 39 - 1920x1080i@50Hz */
865 : { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
866 : 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
867 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
868 : DRM_MODE_FLAG_INTERLACE),
869 : .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
870 : /* 40 - 1920x1080i@100Hz */
871 : { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
872 : 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
873 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
874 : DRM_MODE_FLAG_INTERLACE),
875 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
876 : /* 41 - 1280x720@100Hz */
877 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
878 : 1760, 1980, 0, 720, 725, 730, 750, 0,
879 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
880 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
881 : /* 42 - 720x576@100Hz */
882 : { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
883 : 796, 864, 0, 576, 581, 586, 625, 0,
884 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
885 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
886 : /* 43 - 720x576@100Hz */
887 : { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
888 : 796, 864, 0, 576, 581, 586, 625, 0,
889 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
890 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
891 : /* 44 - 720(1440)x576i@100Hz */
892 : { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
893 : 795, 864, 0, 576, 580, 586, 625, 0,
894 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
895 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
896 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
897 : /* 45 - 720(1440)x576i@100Hz */
898 : { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
899 : 795, 864, 0, 576, 580, 586, 625, 0,
900 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
901 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
902 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
903 : /* 46 - 1920x1080i@120Hz */
904 : { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
905 : 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
906 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
907 : DRM_MODE_FLAG_INTERLACE),
908 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
909 : /* 47 - 1280x720@120Hz */
910 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
911 : 1430, 1650, 0, 720, 725, 730, 750, 0,
912 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
913 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
914 : /* 48 - 720x480@120Hz */
915 : { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
916 : 798, 858, 0, 480, 489, 495, 525, 0,
917 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
918 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
919 : /* 49 - 720x480@120Hz */
920 : { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
921 : 798, 858, 0, 480, 489, 495, 525, 0,
922 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
923 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
924 : /* 50 - 720(1440)x480i@120Hz */
925 : { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
926 : 801, 858, 0, 480, 488, 494, 525, 0,
927 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
928 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
929 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
930 : /* 51 - 720(1440)x480i@120Hz */
931 : { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
932 : 801, 858, 0, 480, 488, 494, 525, 0,
933 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
934 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
935 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
936 : /* 52 - 720x576@200Hz */
937 : { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
938 : 796, 864, 0, 576, 581, 586, 625, 0,
939 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
940 : .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
941 : /* 53 - 720x576@200Hz */
942 : { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
943 : 796, 864, 0, 576, 581, 586, 625, 0,
944 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
945 : .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
946 : /* 54 - 720(1440)x576i@200Hz */
947 : { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
948 : 795, 864, 0, 576, 580, 586, 625, 0,
949 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
950 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
951 : .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
952 : /* 55 - 720(1440)x576i@200Hz */
953 : { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
954 : 795, 864, 0, 576, 580, 586, 625, 0,
955 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
956 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
957 : .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
958 : /* 56 - 720x480@240Hz */
959 : { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
960 : 798, 858, 0, 480, 489, 495, 525, 0,
961 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
962 : .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
963 : /* 57 - 720x480@240Hz */
964 : { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
965 : 798, 858, 0, 480, 489, 495, 525, 0,
966 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
967 : .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
968 : /* 58 - 720(1440)x480i@240 */
969 : { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
970 : 801, 858, 0, 480, 488, 494, 525, 0,
971 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
972 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
973 : .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
974 : /* 59 - 720(1440)x480i@240 */
975 : { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
976 : 801, 858, 0, 480, 488, 494, 525, 0,
977 : DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
978 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
979 : .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
980 : /* 60 - 1280x720@24Hz */
981 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
982 : 3080, 3300, 0, 720, 725, 730, 750, 0,
983 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
984 : .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
985 : /* 61 - 1280x720@25Hz */
986 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
987 : 3740, 3960, 0, 720, 725, 730, 750, 0,
988 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
989 : .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
990 : /* 62 - 1280x720@30Hz */
991 : { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
992 : 3080, 3300, 0, 720, 725, 730, 750, 0,
993 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
994 : .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
995 : /* 63 - 1920x1080@120Hz */
996 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
997 : 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
998 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
999 : .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1000 : /* 64 - 1920x1080@100Hz */
1001 : { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
1002 : 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
1003 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1004 : .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1005 : };
1006 :
1007 : /*
1008 : * HDMI 1.4 4k modes.
1009 : */
1010 : static const struct drm_display_mode edid_4k_modes[] = {
1011 : /* 1 - 3840x2160@30Hz */
1012 : { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
1013 : 3840, 4016, 4104, 4400, 0,
1014 : 2160, 2168, 2178, 2250, 0,
1015 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1016 : .vrefresh = 30, },
1017 : /* 2 - 3840x2160@25Hz */
1018 : { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
1019 : 3840, 4896, 4984, 5280, 0,
1020 : 2160, 2168, 2178, 2250, 0,
1021 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1022 : .vrefresh = 25, },
1023 : /* 3 - 3840x2160@24Hz */
1024 : { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
1025 : 3840, 5116, 5204, 5500, 0,
1026 : 2160, 2168, 2178, 2250, 0,
1027 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1028 : .vrefresh = 24, },
1029 : /* 4 - 4096x2160@24Hz (SMPTE) */
1030 : { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000,
1031 : 4096, 5116, 5204, 5500, 0,
1032 : 2160, 2168, 2178, 2250, 0,
1033 : DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1034 : .vrefresh = 24, },
1035 : };
1036 :
1037 : /*** DDC fetch and block validation ***/
1038 :
1039 : static const u8 edid_header[] = {
1040 : 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
1041 : };
1042 :
1043 : /**
1044 : * drm_edid_header_is_valid - sanity check the header of the base EDID block
1045 : * @raw_edid: pointer to raw base EDID block
1046 : *
1047 : * Sanity check the header of the base EDID block.
1048 : *
1049 : * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
1050 : */
1051 0 : int drm_edid_header_is_valid(const u8 *raw_edid)
1052 : {
1053 : int i, score = 0;
1054 :
1055 0 : for (i = 0; i < sizeof(edid_header); i++)
1056 0 : if (raw_edid[i] == edid_header[i])
1057 0 : score++;
1058 :
1059 0 : return score;
1060 : }
1061 : EXPORT_SYMBOL(drm_edid_header_is_valid);
1062 :
1063 : static int edid_fixup __read_mostly = 6;
1064 : module_param_named(edid_fixup, edid_fixup, int, 0400);
1065 : MODULE_PARM_DESC(edid_fixup,
1066 : "Minimum number of valid EDID header bytes (0-8, default 6)");
1067 :
1068 : static void drm_get_displayid(struct drm_connector *connector,
1069 : struct edid *edid);
1070 :
1071 0 : static int drm_edid_block_checksum(const u8 *raw_edid)
1072 : {
1073 : int i;
1074 : u8 csum = 0;
1075 0 : for (i = 0; i < EDID_LENGTH; i++)
1076 0 : csum += raw_edid[i];
1077 :
1078 0 : return csum;
1079 : }
1080 :
1081 0 : static bool drm_edid_is_zero(const u8 *in_edid, int length)
1082 : {
1083 0 : if (memchr_inv(in_edid, 0, length))
1084 0 : return false;
1085 :
1086 0 : return true;
1087 0 : }
1088 :
1089 : /**
1090 : * drm_edid_block_valid - Sanity check the EDID block (base or extension)
1091 : * @raw_edid: pointer to raw EDID block
1092 : * @block: type of block to validate (0 for base, extension otherwise)
1093 : * @print_bad_edid: if true, dump bad EDID blocks to the console
1094 : * @edid_corrupt: if true, the header or checksum is invalid
1095 : *
1096 : * Validate a base or extension EDID block and optionally dump bad blocks to
1097 : * the console.
1098 : *
1099 : * Return: True if the block is valid, false otherwise.
1100 : */
1101 0 : bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
1102 : bool *edid_corrupt)
1103 : {
1104 : u8 csum;
1105 0 : struct edid *edid = (struct edid *)raw_edid;
1106 :
1107 0 : if (WARN_ON(!raw_edid))
1108 0 : return false;
1109 :
1110 0 : if (edid_fixup > 8 || edid_fixup < 0)
1111 0 : edid_fixup = 6;
1112 :
1113 0 : if (block == 0) {
1114 0 : int score = drm_edid_header_is_valid(raw_edid);
1115 0 : if (score == 8) {
1116 0 : if (edid_corrupt)
1117 0 : *edid_corrupt = false;
1118 0 : } else if (score >= edid_fixup) {
1119 : /* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
1120 : * The corrupt flag needs to be set here otherwise, the
1121 : * fix-up code here will correct the problem, the
1122 : * checksum is correct and the test fails
1123 : */
1124 0 : if (edid_corrupt)
1125 0 : *edid_corrupt = true;
1126 : DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
1127 0 : memcpy(raw_edid, edid_header, sizeof(edid_header));
1128 : } else {
1129 0 : if (edid_corrupt)
1130 0 : *edid_corrupt = true;
1131 0 : goto bad;
1132 : }
1133 0 : }
1134 :
1135 0 : csum = drm_edid_block_checksum(raw_edid);
1136 0 : if (csum) {
1137 0 : if (print_bad_edid) {
1138 0 : DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
1139 0 : }
1140 :
1141 0 : if (edid_corrupt)
1142 0 : *edid_corrupt = true;
1143 :
1144 : /* allow CEA to slide through, switches mangle this */
1145 0 : if (raw_edid[0] != 0x02)
1146 : goto bad;
1147 : }
1148 :
1149 : /* per-block-type checks */
1150 0 : switch (raw_edid[0]) {
1151 : case 0: /* base */
1152 0 : if (edid->version != 1) {
1153 0 : DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
1154 0 : goto bad;
1155 : }
1156 :
1157 0 : if (edid->revision > 4)
1158 : DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
1159 0 : break;
1160 :
1161 : default:
1162 : break;
1163 : }
1164 :
1165 0 : return true;
1166 :
1167 : bad:
1168 0 : if (print_bad_edid) {
1169 0 : if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
1170 0 : printk(KERN_ERR "EDID block is all zeroes\n");
1171 0 : } else {
1172 0 : printk(KERN_ERR "Raw EDID:\n");
1173 0 : print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
1174 : raw_edid, EDID_LENGTH, false);
1175 : }
1176 : }
1177 0 : return false;
1178 0 : }
1179 : EXPORT_SYMBOL(drm_edid_block_valid);
1180 :
1181 : /**
1182 : * drm_edid_is_valid - sanity check EDID data
1183 : * @edid: EDID data
1184 : *
1185 : * Sanity-check an entire EDID record (including extensions)
1186 : *
1187 : * Return: True if the EDID data is valid, false otherwise.
1188 : */
1189 0 : bool drm_edid_is_valid(struct edid *edid)
1190 : {
1191 : int i;
1192 0 : u8 *raw = (u8 *)edid;
1193 :
1194 0 : if (!edid)
1195 0 : return false;
1196 :
1197 0 : for (i = 0; i <= edid->extensions; i++)
1198 0 : if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
1199 0 : return false;
1200 :
1201 0 : return true;
1202 0 : }
1203 : EXPORT_SYMBOL(drm_edid_is_valid);
1204 :
1205 : #define DDC_SEGMENT_ADDR 0x30
1206 : /**
1207 : * drm_do_probe_ddc_edid() - get EDID information via I2C
1208 : * @data: I2C device adapter
1209 : * @buf: EDID data buffer to be filled
1210 : * @block: 128 byte EDID block to start fetching from
1211 : * @len: EDID data buffer length to fetch
1212 : *
1213 : * Try to fetch EDID information by calling I2C driver functions.
1214 : *
1215 : * Return: 0 on success or -1 on failure.
1216 : */
1217 : static int
1218 0 : drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
1219 : {
1220 0 : struct i2c_adapter *adapter = data;
1221 0 : unsigned char start = block * EDID_LENGTH;
1222 0 : unsigned char segment = block >> 1;
1223 0 : unsigned char xfers = segment ? 3 : 2;
1224 : int ret, retries = 5;
1225 :
1226 : /*
1227 : * The core I2C driver will automatically retry the transfer if the
1228 : * adapter reports EAGAIN. However, we find that bit-banging transfers
1229 : * are susceptible to errors under a heavily loaded machine and
1230 : * generate spurious NAKs and timeouts. Retrying the transfer
1231 : * of the individual block a few times seems to overcome this.
1232 : */
1233 0 : do {
1234 0 : struct i2c_msg msgs[] = {
1235 0 : {
1236 : .addr = DDC_SEGMENT_ADDR,
1237 : .flags = 0,
1238 : .len = 1,
1239 : .buf = &segment,
1240 0 : }, {
1241 : .addr = DDC_ADDR,
1242 : .flags = 0,
1243 : .len = 1,
1244 : .buf = &start,
1245 0 : }, {
1246 : .addr = DDC_ADDR,
1247 : .flags = I2C_M_RD,
1248 0 : .len = len,
1249 : .buf = buf,
1250 : }
1251 : };
1252 :
1253 : /*
1254 : * Avoid sending the segment addr to not upset non-compliant
1255 : * DDC monitors.
1256 : */
1257 0 : ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
1258 :
1259 0 : if (ret == -ENXIO) {
1260 : DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
1261 : adapter->name);
1262 0 : break;
1263 : }
1264 0 : } while (ret != xfers && --retries);
1265 :
1266 0 : return ret == xfers ? 0 : -1;
1267 0 : }
1268 :
1269 : /**
1270 : * drm_do_get_edid - get EDID data using a custom EDID block read function
1271 : * @connector: connector we're probing
1272 : * @get_edid_block: EDID block read function
1273 : * @data: private data passed to the block read function
1274 : *
1275 : * When the I2C adapter connected to the DDC bus is hidden behind a device that
1276 : * exposes a different interface to read EDID blocks this function can be used
1277 : * to get EDID data using a custom block read function.
1278 : *
1279 : * As in the general case the DDC bus is accessible by the kernel at the I2C
1280 : * level, drivers must make all reasonable efforts to expose it as an I2C
1281 : * adapter and use drm_get_edid() instead of abusing this function.
1282 : *
1283 : * Return: Pointer to valid EDID or NULL if we couldn't find any.
1284 : */
1285 0 : struct edid *drm_do_get_edid(struct drm_connector *connector,
1286 : int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
1287 : size_t len),
1288 : void *data)
1289 : {
1290 : int i, j = 0, valid_extensions = 0;
1291 : u8 *block, *new;
1292 0 : bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
1293 :
1294 0 : if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
1295 0 : return NULL;
1296 :
1297 : /* base block fetch */
1298 0 : for (i = 0; i < 4; i++) {
1299 0 : if (get_edid_block(data, block, 0, EDID_LENGTH))
1300 : goto out;
1301 0 : if (drm_edid_block_valid(block, 0, print_bad_edid,
1302 0 : &connector->edid_corrupt))
1303 : break;
1304 0 : if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
1305 0 : connector->null_edid_counter++;
1306 0 : goto carp;
1307 : }
1308 : }
1309 0 : if (i == 4)
1310 : goto carp;
1311 :
1312 : /* if there's no extensions, we're done */
1313 0 : if (block[0x7e] == 0)
1314 0 : return (struct edid *)block;
1315 :
1316 0 : new = kmalloc((block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
1317 0 : if (!new)
1318 : goto out;
1319 0 : memcpy(new, block, EDID_LENGTH);
1320 0 : kfree(block);
1321 : block = new;
1322 :
1323 0 : for (j = 1; j <= block[0x7e]; j++) {
1324 0 : for (i = 0; i < 4; i++) {
1325 0 : if (get_edid_block(data,
1326 0 : block + (valid_extensions + 1) * EDID_LENGTH,
1327 : j, EDID_LENGTH))
1328 : goto out;
1329 0 : if (drm_edid_block_valid(block + (valid_extensions + 1)
1330 : * EDID_LENGTH, j,
1331 : print_bad_edid,
1332 : NULL)) {
1333 : valid_extensions++;
1334 0 : break;
1335 : }
1336 : }
1337 :
1338 0 : if (i == 4 && print_bad_edid) {
1339 0 : dev_warn(connector->dev->dev,
1340 : "%s: Ignoring invalid EDID block %d.\n",
1341 : connector->name, j);
1342 :
1343 0 : connector->bad_edid_counter++;
1344 0 : }
1345 : }
1346 :
1347 0 : if (valid_extensions != block[0x7e]) {
1348 0 : block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
1349 0 : block[0x7e] = valid_extensions;
1350 0 : new = kmalloc((valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
1351 0 : if (!new)
1352 : goto out;
1353 0 : memcpy(new, block, (valid_extensions + 1) * EDID_LENGTH);
1354 0 : kfree(block);
1355 : block = new;
1356 0 : }
1357 :
1358 0 : return (struct edid *)block;
1359 :
1360 : carp:
1361 0 : if (print_bad_edid) {
1362 0 : dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
1363 : connector->name, j);
1364 0 : }
1365 0 : connector->bad_edid_counter++;
1366 :
1367 : out:
1368 0 : kfree(block);
1369 0 : return NULL;
1370 0 : }
1371 :
1372 : /**
1373 : * drm_probe_ddc() - probe DDC presence
1374 : * @adapter: I2C adapter to probe
1375 : *
1376 : * Return: True on success, false on failure.
1377 : */
1378 : bool
1379 0 : drm_probe_ddc(struct i2c_adapter *adapter)
1380 : {
1381 0 : unsigned char out;
1382 :
1383 0 : return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
1384 0 : }
1385 : EXPORT_SYMBOL(drm_probe_ddc);
1386 :
1387 : /**
1388 : * drm_get_edid - get EDID data, if available
1389 : * @connector: connector we're probing
1390 : * @adapter: I2C adapter to use for DDC
1391 : *
1392 : * Poke the given I2C channel to grab EDID data if possible. If found,
1393 : * attach it to the connector.
1394 : *
1395 : * Return: Pointer to valid EDID or NULL if we couldn't find any.
1396 : */
1397 0 : struct edid *drm_get_edid(struct drm_connector *connector,
1398 : struct i2c_adapter *adapter)
1399 : {
1400 : struct edid *edid;
1401 :
1402 0 : if (!drm_probe_ddc(adapter))
1403 0 : return NULL;
1404 :
1405 0 : edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
1406 0 : if (edid)
1407 0 : drm_get_displayid(connector, edid);
1408 0 : return edid;
1409 0 : }
1410 : EXPORT_SYMBOL(drm_get_edid);
1411 :
1412 : /**
1413 : * drm_edid_duplicate - duplicate an EDID and the extensions
1414 : * @edid: EDID to duplicate
1415 : *
1416 : * Return: Pointer to duplicated EDID or NULL on allocation failure.
1417 : */
1418 0 : struct edid *drm_edid_duplicate(const struct edid *edid)
1419 : {
1420 0 : return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
1421 : }
1422 : EXPORT_SYMBOL(drm_edid_duplicate);
1423 :
1424 : /*** EDID parsing ***/
1425 :
1426 : /**
1427 : * edid_vendor - match a string against EDID's obfuscated vendor field
1428 : * @edid: EDID to match
1429 : * @vendor: vendor string
1430 : *
1431 : * Returns true if @vendor is in @edid, false otherwise
1432 : */
1433 0 : static bool edid_vendor(struct edid *edid, char *vendor)
1434 : {
1435 0 : char edid_vendor[3];
1436 :
1437 0 : edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
1438 0 : edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
1439 0 : ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
1440 0 : edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
1441 :
1442 0 : return !strncmp(edid_vendor, vendor, 3);
1443 0 : }
1444 :
1445 : /**
1446 : * edid_get_quirks - return quirk flags for a given EDID
1447 : * @edid: EDID to process
1448 : *
1449 : * This tells subsequent routines what fixes they need to apply.
1450 : */
1451 0 : static u32 edid_get_quirks(struct edid *edid)
1452 : {
1453 : struct edid_quirk *quirk;
1454 : int i;
1455 :
1456 0 : for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
1457 0 : quirk = &edid_quirk_list[i];
1458 :
1459 0 : if (edid_vendor(edid, quirk->vendor) &&
1460 0 : (EDID_PRODUCT_ID(edid) == quirk->product_id))
1461 0 : return quirk->quirks;
1462 : }
1463 :
1464 0 : return 0;
1465 0 : }
1466 :
1467 : #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
1468 : #define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
1469 :
1470 : /**
1471 : * edid_fixup_preferred - set preferred modes based on quirk list
1472 : * @connector: has mode list to fix up
1473 : * @quirks: quirks list
1474 : *
1475 : * Walk the mode list for @connector, clearing the preferred status
1476 : * on existing modes and setting it anew for the right mode ala @quirks.
1477 : */
1478 0 : static void edid_fixup_preferred(struct drm_connector *connector,
1479 : u32 quirks)
1480 : {
1481 : struct drm_display_mode *t, *cur_mode, *preferred_mode;
1482 : int target_refresh = 0;
1483 : int cur_vrefresh, preferred_vrefresh;
1484 :
1485 0 : if (list_empty(&connector->probed_modes))
1486 0 : return;
1487 :
1488 0 : if (quirks & EDID_QUIRK_PREFER_LARGE_60)
1489 0 : target_refresh = 60;
1490 0 : if (quirks & EDID_QUIRK_PREFER_LARGE_75)
1491 0 : target_refresh = 75;
1492 :
1493 0 : preferred_mode = list_first_entry(&connector->probed_modes,
1494 : struct drm_display_mode, head);
1495 :
1496 0 : list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
1497 0 : cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
1498 :
1499 0 : if (cur_mode == preferred_mode)
1500 : continue;
1501 :
1502 : /* Largest mode is preferred */
1503 0 : if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
1504 0 : preferred_mode = cur_mode;
1505 :
1506 0 : cur_vrefresh = cur_mode->vrefresh ?
1507 0 : cur_mode->vrefresh : drm_mode_vrefresh(cur_mode);
1508 0 : preferred_vrefresh = preferred_mode->vrefresh ?
1509 0 : preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode);
1510 : /* At a given size, try to get closest to target refresh */
1511 0 : if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
1512 0 : MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
1513 0 : MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
1514 : preferred_mode = cur_mode;
1515 0 : }
1516 : }
1517 :
1518 0 : preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
1519 0 : }
1520 :
1521 : static bool
1522 0 : mode_is_rb(const struct drm_display_mode *mode)
1523 : {
1524 0 : return (mode->htotal - mode->hdisplay == 160) &&
1525 0 : (mode->hsync_end - mode->hdisplay == 80) &&
1526 0 : (mode->hsync_end - mode->hsync_start == 32) &&
1527 0 : (mode->vsync_start - mode->vdisplay == 3);
1528 : }
1529 :
1530 : /*
1531 : * drm_mode_find_dmt - Create a copy of a mode if present in DMT
1532 : * @dev: Device to duplicate against
1533 : * @hsize: Mode width
1534 : * @vsize: Mode height
1535 : * @fresh: Mode refresh rate
1536 : * @rb: Mode reduced-blanking-ness
1537 : *
1538 : * Walk the DMT mode list looking for a match for the given parameters.
1539 : *
1540 : * Return: A newly allocated copy of the mode, or NULL if not found.
1541 : */
1542 0 : struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
1543 : int hsize, int vsize, int fresh,
1544 : bool rb)
1545 : {
1546 : int i;
1547 :
1548 0 : for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
1549 0 : const struct drm_display_mode *ptr = &drm_dmt_modes[i];
1550 0 : if (hsize != ptr->hdisplay)
1551 0 : continue;
1552 0 : if (vsize != ptr->vdisplay)
1553 0 : continue;
1554 0 : if (fresh != drm_mode_vrefresh(ptr))
1555 0 : continue;
1556 0 : if (rb != mode_is_rb(ptr))
1557 0 : continue;
1558 :
1559 0 : return drm_mode_duplicate(dev, ptr);
1560 : }
1561 :
1562 0 : return NULL;
1563 0 : }
1564 : EXPORT_SYMBOL(drm_mode_find_dmt);
1565 :
1566 : typedef void detailed_cb(struct detailed_timing *timing, void *closure);
1567 :
1568 : static void
1569 0 : cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
1570 : {
1571 : int i, n = 0;
1572 0 : u8 d = ext[0x02];
1573 0 : u8 *det_base = ext + d;
1574 :
1575 0 : n = (127 - d) / 18;
1576 0 : for (i = 0; i < n; i++)
1577 0 : cb((struct detailed_timing *)(det_base + 18 * i), closure);
1578 0 : }
1579 :
1580 : static void
1581 0 : vtb_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
1582 : {
1583 0 : unsigned int i, n = min((int)ext[0x02], 6);
1584 0 : u8 *det_base = ext + 5;
1585 :
1586 0 : if (ext[0x01] != 1)
1587 0 : return; /* unknown version */
1588 :
1589 0 : for (i = 0; i < n; i++)
1590 0 : cb((struct detailed_timing *)(det_base + 18 * i), closure);
1591 0 : }
1592 :
1593 : static void
1594 0 : drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure)
1595 : {
1596 : int i;
1597 0 : struct edid *edid = (struct edid *)raw_edid;
1598 :
1599 0 : if (edid == NULL)
1600 0 : return;
1601 :
1602 0 : for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
1603 0 : cb(&(edid->detailed_timings[i]), closure);
1604 :
1605 0 : for (i = 1; i <= raw_edid[0x7e]; i++) {
1606 0 : u8 *ext = raw_edid + (i * EDID_LENGTH);
1607 0 : switch (*ext) {
1608 : case CEA_EXT:
1609 0 : cea_for_each_detailed_block(ext, cb, closure);
1610 0 : break;
1611 : case VTB_EXT:
1612 0 : vtb_for_each_detailed_block(ext, cb, closure);
1613 0 : break;
1614 : default:
1615 : break;
1616 : }
1617 : }
1618 0 : }
1619 :
1620 : static void
1621 0 : is_rb(struct detailed_timing *t, void *data)
1622 : {
1623 0 : u8 *r = (u8 *)t;
1624 0 : if (r[3] == EDID_DETAIL_MONITOR_RANGE)
1625 0 : if (r[15] & 0x10)
1626 0 : *(bool *)data = true;
1627 0 : }
1628 :
1629 : /* EDID 1.4 defines this explicitly. For EDID 1.3, we guess, badly. */
1630 : static bool
1631 0 : drm_monitor_supports_rb(struct edid *edid)
1632 : {
1633 0 : if (edid->revision >= 4) {
1634 0 : bool ret = false;
1635 0 : drm_for_each_detailed_block((u8 *)edid, is_rb, &ret);
1636 0 : return ret;
1637 0 : }
1638 :
1639 0 : return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0);
1640 0 : }
1641 :
1642 : static void
1643 0 : find_gtf2(struct detailed_timing *t, void *data)
1644 : {
1645 0 : u8 *r = (u8 *)t;
1646 0 : if (r[3] == EDID_DETAIL_MONITOR_RANGE && r[10] == 0x02)
1647 0 : *(u8 **)data = r;
1648 0 : }
1649 :
1650 : /* Secondary GTF curve kicks in above some break frequency */
1651 : static int
1652 0 : drm_gtf2_hbreak(struct edid *edid)
1653 : {
1654 0 : u8 *r = NULL;
1655 0 : drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1656 0 : return r ? (r[12] * 2) : 0;
1657 0 : }
1658 :
1659 : static int
1660 0 : drm_gtf2_2c(struct edid *edid)
1661 : {
1662 0 : u8 *r = NULL;
1663 0 : drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1664 0 : return r ? r[13] : 0;
1665 0 : }
1666 :
1667 : static int
1668 0 : drm_gtf2_m(struct edid *edid)
1669 : {
1670 0 : u8 *r = NULL;
1671 0 : drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1672 0 : return r ? (r[15] << 8) + r[14] : 0;
1673 0 : }
1674 :
1675 : static int
1676 0 : drm_gtf2_k(struct edid *edid)
1677 : {
1678 0 : u8 *r = NULL;
1679 0 : drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1680 0 : return r ? r[16] : 0;
1681 0 : }
1682 :
1683 : static int
1684 0 : drm_gtf2_2j(struct edid *edid)
1685 : {
1686 0 : u8 *r = NULL;
1687 0 : drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1688 0 : return r ? r[17] : 0;
1689 0 : }
1690 :
1691 : /**
1692 : * standard_timing_level - get std. timing level(CVT/GTF/DMT)
1693 : * @edid: EDID block to scan
1694 : */
1695 0 : static int standard_timing_level(struct edid *edid)
1696 : {
1697 0 : if (edid->revision >= 2) {
1698 0 : if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
1699 0 : return LEVEL_CVT;
1700 0 : if (drm_gtf2_hbreak(edid))
1701 0 : return LEVEL_GTF2;
1702 0 : return LEVEL_GTF;
1703 : }
1704 0 : return LEVEL_DMT;
1705 0 : }
1706 :
1707 : /*
1708 : * 0 is reserved. The spec says 0x01 fill for unused timings. Some old
1709 : * monitors fill with ascii space (0x20) instead.
1710 : */
1711 : static int
1712 0 : bad_std_timing(u8 a, u8 b)
1713 : {
1714 0 : return (a == 0x00 && b == 0x00) ||
1715 0 : (a == 0x01 && b == 0x01) ||
1716 0 : (a == 0x20 && b == 0x20);
1717 : }
1718 :
1719 : /**
1720 : * drm_mode_std - convert standard mode info (width, height, refresh) into mode
1721 : * @connector: connector of for the EDID block
1722 : * @edid: EDID block to scan
1723 : * @t: standard timing params
1724 : *
1725 : * Take the standard timing params (in this case width, aspect, and refresh)
1726 : * and convert them into a real mode using CVT/GTF/DMT.
1727 : */
1728 : static struct drm_display_mode *
1729 0 : drm_mode_std(struct drm_connector *connector, struct edid *edid,
1730 : struct std_timing *t)
1731 : {
1732 0 : struct drm_device *dev = connector->dev;
1733 : struct drm_display_mode *m, *mode = NULL;
1734 : int hsize, vsize;
1735 : int vrefresh_rate;
1736 0 : unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
1737 0 : >> EDID_TIMING_ASPECT_SHIFT;
1738 0 : unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
1739 : >> EDID_TIMING_VFREQ_SHIFT;
1740 0 : int timing_level = standard_timing_level(edid);
1741 :
1742 0 : if (bad_std_timing(t->hsize, t->vfreq_aspect))
1743 0 : return NULL;
1744 :
1745 : /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
1746 0 : hsize = t->hsize * 8 + 248;
1747 : /* vrefresh_rate = vfreq + 60 */
1748 0 : vrefresh_rate = vfreq + 60;
1749 : /* the vdisplay is calculated based on the aspect ratio */
1750 0 : if (aspect_ratio == 0) {
1751 0 : if (edid->revision < 3)
1752 0 : vsize = hsize;
1753 : else
1754 0 : vsize = (hsize * 10) / 16;
1755 0 : } else if (aspect_ratio == 1)
1756 0 : vsize = (hsize * 3) / 4;
1757 0 : else if (aspect_ratio == 2)
1758 0 : vsize = (hsize * 4) / 5;
1759 : else
1760 0 : vsize = (hsize * 9) / 16;
1761 :
1762 : /* HDTV hack, part 1 */
1763 0 : if (vrefresh_rate == 60 &&
1764 0 : ((hsize == 1360 && vsize == 765) ||
1765 0 : (hsize == 1368 && vsize == 769))) {
1766 : hsize = 1366;
1767 : vsize = 768;
1768 0 : }
1769 :
1770 : /*
1771 : * If this connector already has a mode for this size and refresh
1772 : * rate (because it came from detailed or CVT info), use that
1773 : * instead. This way we don't have to guess at interlace or
1774 : * reduced blanking.
1775 : */
1776 0 : list_for_each_entry(m, &connector->probed_modes, head)
1777 0 : if (m->hdisplay == hsize && m->vdisplay == vsize &&
1778 0 : drm_mode_vrefresh(m) == vrefresh_rate)
1779 0 : return NULL;
1780 :
1781 : /* HDTV hack, part 2 */
1782 0 : if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) {
1783 0 : mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
1784 : false);
1785 0 : mode->hdisplay = 1366;
1786 0 : mode->hsync_start = mode->hsync_start - 1;
1787 0 : mode->hsync_end = mode->hsync_end - 1;
1788 0 : return mode;
1789 : }
1790 :
1791 : /* check whether it can be found in default mode table */
1792 0 : if (drm_monitor_supports_rb(edid)) {
1793 0 : mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate,
1794 : true);
1795 0 : if (mode)
1796 0 : return mode;
1797 : }
1798 0 : mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false);
1799 0 : if (mode)
1800 0 : return mode;
1801 :
1802 : /* okay, generate it */
1803 0 : switch (timing_level) {
1804 : case LEVEL_DMT:
1805 : break;
1806 : case LEVEL_GTF:
1807 0 : mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
1808 0 : break;
1809 : case LEVEL_GTF2:
1810 : /*
1811 : * This is potentially wrong if there's ever a monitor with
1812 : * more than one ranges section, each claiming a different
1813 : * secondary GTF curve. Please don't do that.
1814 : */
1815 0 : mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
1816 0 : if (!mode)
1817 0 : return NULL;
1818 0 : if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
1819 0 : drm_mode_destroy(dev, mode);
1820 0 : mode = drm_gtf_mode_complex(dev, hsize, vsize,
1821 : vrefresh_rate, 0, 0,
1822 0 : drm_gtf2_m(edid),
1823 0 : drm_gtf2_2c(edid),
1824 0 : drm_gtf2_k(edid),
1825 0 : drm_gtf2_2j(edid));
1826 0 : }
1827 : break;
1828 : case LEVEL_CVT:
1829 0 : mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
1830 : false);
1831 0 : break;
1832 : }
1833 0 : return mode;
1834 0 : }
1835 :
1836 : /*
1837 : * EDID is delightfully ambiguous about how interlaced modes are to be
1838 : * encoded. Our internal representation is of frame height, but some
1839 : * HDTV detailed timings are encoded as field height.
1840 : *
1841 : * The format list here is from CEA, in frame size. Technically we
1842 : * should be checking refresh rate too. Whatever.
1843 : */
1844 : static void
1845 0 : drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
1846 : struct detailed_pixel_timing *pt)
1847 : {
1848 : int i;
1849 : static const struct {
1850 : int w, h;
1851 : } cea_interlaced[] = {
1852 : { 1920, 1080 },
1853 : { 720, 480 },
1854 : { 1440, 480 },
1855 : { 2880, 480 },
1856 : { 720, 576 },
1857 : { 1440, 576 },
1858 : { 2880, 576 },
1859 : };
1860 :
1861 0 : if (!(pt->misc & DRM_EDID_PT_INTERLACED))
1862 0 : return;
1863 :
1864 0 : for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) {
1865 0 : if ((mode->hdisplay == cea_interlaced[i].w) &&
1866 0 : (mode->vdisplay == cea_interlaced[i].h / 2)) {
1867 0 : mode->vdisplay *= 2;
1868 0 : mode->vsync_start *= 2;
1869 0 : mode->vsync_end *= 2;
1870 0 : mode->vtotal *= 2;
1871 0 : mode->vtotal |= 1;
1872 0 : }
1873 : }
1874 :
1875 0 : mode->flags |= DRM_MODE_FLAG_INTERLACE;
1876 0 : }
1877 :
1878 : /**
1879 : * drm_mode_detailed - create a new mode from an EDID detailed timing section
1880 : * @dev: DRM device (needed to create new mode)
1881 : * @edid: EDID block
1882 : * @timing: EDID detailed timing info
1883 : * @quirks: quirks to apply
1884 : *
1885 : * An EDID detailed timing block contains enough info for us to create and
1886 : * return a new struct drm_display_mode.
1887 : */
1888 0 : static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
1889 : struct edid *edid,
1890 : struct detailed_timing *timing,
1891 : u32 quirks)
1892 : {
1893 : struct drm_display_mode *mode;
1894 0 : struct detailed_pixel_timing *pt = &timing->data.pixel_data;
1895 0 : unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
1896 0 : unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
1897 0 : unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
1898 0 : unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
1899 0 : unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
1900 0 : unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
1901 0 : unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
1902 0 : unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
1903 :
1904 : /* ignore tiny modes */
1905 0 : if (hactive < 64 || vactive < 64)
1906 0 : return NULL;
1907 :
1908 0 : if (pt->misc & DRM_EDID_PT_STEREO) {
1909 : DRM_DEBUG_KMS("stereo mode not supported\n");
1910 0 : return NULL;
1911 : }
1912 0 : if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
1913 : DRM_DEBUG_KMS("composite sync not supported\n");
1914 : }
1915 :
1916 : /* it is incorrect if hsync/vsync width is zero */
1917 0 : if (!hsync_pulse_width || !vsync_pulse_width) {
1918 : DRM_DEBUG_KMS("Incorrect Detailed timing. "
1919 : "Wrong Hsync/Vsync pulse width\n");
1920 0 : return NULL;
1921 : }
1922 :
1923 0 : if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
1924 0 : mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
1925 0 : if (!mode)
1926 0 : return NULL;
1927 :
1928 : goto set_size;
1929 : }
1930 :
1931 0 : mode = drm_mode_create(dev);
1932 0 : if (!mode)
1933 0 : return NULL;
1934 :
1935 0 : if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
1936 0 : timing->pixel_clock = cpu_to_le16(1088);
1937 :
1938 0 : mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
1939 :
1940 0 : mode->hdisplay = hactive;
1941 0 : mode->hsync_start = mode->hdisplay + hsync_offset;
1942 0 : mode->hsync_end = mode->hsync_start + hsync_pulse_width;
1943 0 : mode->htotal = mode->hdisplay + hblank;
1944 :
1945 0 : mode->vdisplay = vactive;
1946 0 : mode->vsync_start = mode->vdisplay + vsync_offset;
1947 0 : mode->vsync_end = mode->vsync_start + vsync_pulse_width;
1948 0 : mode->vtotal = mode->vdisplay + vblank;
1949 :
1950 : /* Some EDIDs have bogus h/vtotal values */
1951 0 : if (mode->hsync_end > mode->htotal)
1952 0 : mode->htotal = mode->hsync_end + 1;
1953 0 : if (mode->vsync_end > mode->vtotal)
1954 0 : mode->vtotal = mode->vsync_end + 1;
1955 :
1956 0 : drm_mode_do_interlace_quirk(mode, pt);
1957 :
1958 0 : if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
1959 0 : pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
1960 0 : }
1961 :
1962 0 : mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
1963 : DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
1964 0 : mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
1965 : DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
1966 :
1967 : set_size:
1968 0 : mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
1969 0 : mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
1970 :
1971 0 : if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
1972 0 : mode->width_mm *= 10;
1973 0 : mode->height_mm *= 10;
1974 0 : }
1975 :
1976 0 : if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
1977 0 : mode->width_mm = edid->width_cm * 10;
1978 0 : mode->height_mm = edid->height_cm * 10;
1979 0 : }
1980 :
1981 0 : mode->type = DRM_MODE_TYPE_DRIVER;
1982 0 : mode->vrefresh = drm_mode_vrefresh(mode);
1983 0 : drm_mode_set_name(mode);
1984 :
1985 0 : return mode;
1986 0 : }
1987 :
1988 : static bool
1989 0 : mode_in_hsync_range(const struct drm_display_mode *mode,
1990 : struct edid *edid, u8 *t)
1991 : {
1992 : int hsync, hmin, hmax;
1993 :
1994 0 : hmin = t[7];
1995 0 : if (edid->revision >= 4)
1996 0 : hmin += ((t[4] & 0x04) ? 255 : 0);
1997 0 : hmax = t[8];
1998 0 : if (edid->revision >= 4)
1999 0 : hmax += ((t[4] & 0x08) ? 255 : 0);
2000 0 : hsync = drm_mode_hsync(mode);
2001 :
2002 0 : return (hsync <= hmax && hsync >= hmin);
2003 : }
2004 :
2005 : static bool
2006 0 : mode_in_vsync_range(const struct drm_display_mode *mode,
2007 : struct edid *edid, u8 *t)
2008 : {
2009 : int vsync, vmin, vmax;
2010 :
2011 0 : vmin = t[5];
2012 0 : if (edid->revision >= 4)
2013 0 : vmin += ((t[4] & 0x01) ? 255 : 0);
2014 0 : vmax = t[6];
2015 0 : if (edid->revision >= 4)
2016 0 : vmax += ((t[4] & 0x02) ? 255 : 0);
2017 0 : vsync = drm_mode_vrefresh(mode);
2018 :
2019 0 : return (vsync <= vmax && vsync >= vmin);
2020 : }
2021 :
2022 : static u32
2023 0 : range_pixel_clock(struct edid *edid, u8 *t)
2024 : {
2025 : /* unspecified */
2026 0 : if (t[9] == 0 || t[9] == 255)
2027 0 : return 0;
2028 :
2029 : /* 1.4 with CVT support gives us real precision, yay */
2030 0 : if (edid->revision >= 4 && t[10] == 0x04)
2031 0 : return (t[9] * 10000) - ((t[12] >> 2) * 250);
2032 :
2033 : /* 1.3 is pathetic, so fuzz up a bit */
2034 0 : return t[9] * 10000 + 5001;
2035 0 : }
2036 :
2037 : static bool
2038 0 : mode_in_range(const struct drm_display_mode *mode, struct edid *edid,
2039 : struct detailed_timing *timing)
2040 : {
2041 : u32 max_clock;
2042 0 : u8 *t = (u8 *)timing;
2043 :
2044 0 : if (!mode_in_hsync_range(mode, edid, t))
2045 0 : return false;
2046 :
2047 0 : if (!mode_in_vsync_range(mode, edid, t))
2048 0 : return false;
2049 :
2050 0 : if ((max_clock = range_pixel_clock(edid, t)))
2051 0 : if (mode->clock > max_clock)
2052 0 : return false;
2053 :
2054 : /* 1.4 max horizontal check */
2055 0 : if (edid->revision >= 4 && t[10] == 0x04)
2056 0 : if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3))))
2057 0 : return false;
2058 :
2059 0 : if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid))
2060 0 : return false;
2061 :
2062 0 : return true;
2063 0 : }
2064 :
2065 0 : static bool valid_inferred_mode(const struct drm_connector *connector,
2066 : const struct drm_display_mode *mode)
2067 : {
2068 : const struct drm_display_mode *m;
2069 : bool ok = false;
2070 :
2071 0 : list_for_each_entry(m, &connector->probed_modes, head) {
2072 0 : if (mode->hdisplay == m->hdisplay &&
2073 0 : mode->vdisplay == m->vdisplay &&
2074 0 : drm_mode_vrefresh(mode) == drm_mode_vrefresh(m))
2075 0 : return false; /* duplicated */
2076 0 : if (mode->hdisplay <= m->hdisplay &&
2077 0 : mode->vdisplay <= m->vdisplay)
2078 0 : ok = true;
2079 : }
2080 0 : return ok;
2081 0 : }
2082 :
2083 : static int
2084 0 : drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
2085 : struct detailed_timing *timing)
2086 : {
2087 : int i, modes = 0;
2088 : struct drm_display_mode *newmode;
2089 0 : struct drm_device *dev = connector->dev;
2090 :
2091 0 : for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
2092 0 : if (mode_in_range(drm_dmt_modes + i, edid, timing) &&
2093 0 : valid_inferred_mode(connector, drm_dmt_modes + i)) {
2094 0 : newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
2095 0 : if (newmode) {
2096 0 : drm_mode_probed_add(connector, newmode);
2097 0 : modes++;
2098 0 : }
2099 : }
2100 : }
2101 :
2102 0 : return modes;
2103 : }
2104 :
2105 : /* fix up 1366x768 mode from 1368x768;
2106 : * GFT/CVT can't express 1366 width which isn't dividable by 8
2107 : */
2108 0 : static void fixup_mode_1366x768(struct drm_display_mode *mode)
2109 : {
2110 0 : if (mode->hdisplay == 1368 && mode->vdisplay == 768) {
2111 0 : mode->hdisplay = 1366;
2112 0 : mode->hsync_start--;
2113 0 : mode->hsync_end--;
2114 0 : drm_mode_set_name(mode);
2115 0 : }
2116 0 : }
2117 :
2118 : static int
2119 0 : drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
2120 : struct detailed_timing *timing)
2121 : {
2122 : int i, modes = 0;
2123 : struct drm_display_mode *newmode;
2124 0 : struct drm_device *dev = connector->dev;
2125 :
2126 0 : for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
2127 0 : const struct minimode *m = &extra_modes[i];
2128 0 : newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
2129 0 : if (!newmode)
2130 0 : return modes;
2131 :
2132 0 : fixup_mode_1366x768(newmode);
2133 0 : if (!mode_in_range(newmode, edid, timing) ||
2134 0 : !valid_inferred_mode(connector, newmode)) {
2135 0 : drm_mode_destroy(dev, newmode);
2136 0 : continue;
2137 : }
2138 :
2139 0 : drm_mode_probed_add(connector, newmode);
2140 0 : modes++;
2141 0 : }
2142 :
2143 0 : return modes;
2144 0 : }
2145 :
2146 : static int
2147 0 : drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
2148 : struct detailed_timing *timing)
2149 : {
2150 : int i, modes = 0;
2151 : struct drm_display_mode *newmode;
2152 0 : struct drm_device *dev = connector->dev;
2153 0 : bool rb = drm_monitor_supports_rb(edid);
2154 :
2155 0 : for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
2156 0 : const struct minimode *m = &extra_modes[i];
2157 0 : newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
2158 0 : if (!newmode)
2159 0 : return modes;
2160 :
2161 0 : fixup_mode_1366x768(newmode);
2162 0 : if (!mode_in_range(newmode, edid, timing) ||
2163 0 : !valid_inferred_mode(connector, newmode)) {
2164 0 : drm_mode_destroy(dev, newmode);
2165 0 : continue;
2166 : }
2167 :
2168 0 : drm_mode_probed_add(connector, newmode);
2169 0 : modes++;
2170 0 : }
2171 :
2172 0 : return modes;
2173 0 : }
2174 :
2175 : static void
2176 0 : do_inferred_modes(struct detailed_timing *timing, void *c)
2177 : {
2178 0 : struct detailed_mode_closure *closure = c;
2179 0 : struct detailed_non_pixel *data = &timing->data.other_data;
2180 0 : struct detailed_data_monitor_range *range = &data->data.range;
2181 :
2182 0 : if (data->type != EDID_DETAIL_MONITOR_RANGE)
2183 0 : return;
2184 :
2185 0 : closure->modes += drm_dmt_modes_for_range(closure->connector,
2186 0 : closure->edid,
2187 : timing);
2188 :
2189 0 : if (!version_greater(closure->edid, 1, 1))
2190 0 : return; /* GTF not defined yet */
2191 :
2192 0 : switch (range->flags) {
2193 : case 0x02: /* secondary gtf, XXX could do more */
2194 : case 0x00: /* default gtf */
2195 0 : closure->modes += drm_gtf_modes_for_range(closure->connector,
2196 0 : closure->edid,
2197 : timing);
2198 0 : break;
2199 : case 0x04: /* cvt, only in 1.4+ */
2200 0 : if (!version_greater(closure->edid, 1, 3))
2201 : break;
2202 :
2203 0 : closure->modes += drm_cvt_modes_for_range(closure->connector,
2204 0 : closure->edid,
2205 : timing);
2206 0 : break;
2207 : case 0x01: /* just the ranges, no formula */
2208 : default:
2209 : break;
2210 : }
2211 0 : }
2212 :
2213 : static int
2214 0 : add_inferred_modes(struct drm_connector *connector, struct edid *edid)
2215 : {
2216 0 : struct detailed_mode_closure closure = {
2217 : .connector = connector,
2218 : .edid = edid,
2219 : };
2220 :
2221 0 : if (version_greater(edid, 1, 0))
2222 0 : drm_for_each_detailed_block((u8 *)edid, do_inferred_modes,
2223 : &closure);
2224 :
2225 0 : return closure.modes;
2226 0 : }
2227 :
2228 : static int
2229 0 : drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
2230 : {
2231 : int i, j, m, modes = 0;
2232 : struct drm_display_mode *mode;
2233 0 : u8 *est = ((u8 *)timing) + 5;
2234 :
2235 0 : for (i = 0; i < 6; i++) {
2236 0 : for (j = 7; j >= 0; j--) {
2237 0 : m = (i * 8) + (7 - j);
2238 0 : if (m >= ARRAY_SIZE(est3_modes))
2239 : break;
2240 0 : if (est[i] & (1 << j)) {
2241 0 : mode = drm_mode_find_dmt(connector->dev,
2242 0 : est3_modes[m].w,
2243 0 : est3_modes[m].h,
2244 0 : est3_modes[m].r,
2245 0 : est3_modes[m].rb);
2246 0 : if (mode) {
2247 0 : drm_mode_probed_add(connector, mode);
2248 0 : modes++;
2249 0 : }
2250 : }
2251 : }
2252 : }
2253 :
2254 0 : return modes;
2255 : }
2256 :
2257 : static void
2258 0 : do_established_modes(struct detailed_timing *timing, void *c)
2259 : {
2260 0 : struct detailed_mode_closure *closure = c;
2261 0 : struct detailed_non_pixel *data = &timing->data.other_data;
2262 :
2263 0 : if (data->type == EDID_DETAIL_EST_TIMINGS)
2264 0 : closure->modes += drm_est3_modes(closure->connector, timing);
2265 0 : }
2266 :
2267 : /**
2268 : * add_established_modes - get est. modes from EDID and add them
2269 : * @connector: connector to add mode(s) to
2270 : * @edid: EDID block to scan
2271 : *
2272 : * Each EDID block contains a bitmap of the supported "established modes" list
2273 : * (defined above). Tease them out and add them to the global modes list.
2274 : */
2275 : static int
2276 0 : add_established_modes(struct drm_connector *connector, struct edid *edid)
2277 : {
2278 0 : struct drm_device *dev = connector->dev;
2279 0 : unsigned long est_bits = edid->established_timings.t1 |
2280 0 : (edid->established_timings.t2 << 8) |
2281 0 : ((edid->established_timings.mfg_rsvd & 0x80) << 9);
2282 : int i, modes = 0;
2283 0 : struct detailed_mode_closure closure = {
2284 : .connector = connector,
2285 : .edid = edid,
2286 : };
2287 :
2288 0 : for (i = 0; i <= EDID_EST_TIMINGS; i++) {
2289 0 : if (est_bits & (1<<i)) {
2290 : struct drm_display_mode *newmode;
2291 0 : newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
2292 0 : if (newmode) {
2293 0 : drm_mode_probed_add(connector, newmode);
2294 0 : modes++;
2295 0 : }
2296 0 : }
2297 : }
2298 :
2299 0 : if (version_greater(edid, 1, 0))
2300 0 : drm_for_each_detailed_block((u8 *)edid,
2301 : do_established_modes, &closure);
2302 :
2303 0 : return modes + closure.modes;
2304 0 : }
2305 :
2306 : static void
2307 0 : do_standard_modes(struct detailed_timing *timing, void *c)
2308 : {
2309 0 : struct detailed_mode_closure *closure = c;
2310 0 : struct detailed_non_pixel *data = &timing->data.other_data;
2311 0 : struct drm_connector *connector = closure->connector;
2312 0 : struct edid *edid = closure->edid;
2313 :
2314 0 : if (data->type == EDID_DETAIL_STD_MODES) {
2315 : int i;
2316 0 : for (i = 0; i < 6; i++) {
2317 : struct std_timing *std;
2318 : struct drm_display_mode *newmode;
2319 :
2320 0 : std = &data->data.timings[i];
2321 0 : newmode = drm_mode_std(connector, edid, std);
2322 0 : if (newmode) {
2323 0 : drm_mode_probed_add(connector, newmode);
2324 0 : closure->modes++;
2325 0 : }
2326 : }
2327 0 : }
2328 0 : }
2329 :
2330 : /**
2331 : * add_standard_modes - get std. modes from EDID and add them
2332 : * @connector: connector to add mode(s) to
2333 : * @edid: EDID block to scan
2334 : *
2335 : * Standard modes can be calculated using the appropriate standard (DMT,
2336 : * GTF or CVT. Grab them from @edid and add them to the list.
2337 : */
2338 : static int
2339 0 : add_standard_modes(struct drm_connector *connector, struct edid *edid)
2340 : {
2341 : int i, modes = 0;
2342 0 : struct detailed_mode_closure closure = {
2343 : .connector = connector,
2344 : .edid = edid,
2345 : };
2346 :
2347 0 : for (i = 0; i < EDID_STD_TIMINGS; i++) {
2348 : struct drm_display_mode *newmode;
2349 :
2350 0 : newmode = drm_mode_std(connector, edid,
2351 0 : &edid->standard_timings[i]);
2352 0 : if (newmode) {
2353 0 : drm_mode_probed_add(connector, newmode);
2354 0 : modes++;
2355 0 : }
2356 : }
2357 :
2358 0 : if (version_greater(edid, 1, 0))
2359 0 : drm_for_each_detailed_block((u8 *)edid, do_standard_modes,
2360 : &closure);
2361 :
2362 : /* XXX should also look for standard codes in VTB blocks */
2363 :
2364 0 : return modes + closure.modes;
2365 0 : }
2366 :
2367 0 : static int drm_cvt_modes(struct drm_connector *connector,
2368 : struct detailed_timing *timing)
2369 : {
2370 : int i, j, modes = 0;
2371 : struct drm_display_mode *newmode;
2372 0 : struct drm_device *dev = connector->dev;
2373 : struct cvt_timing *cvt;
2374 : const int rates[] = { 60, 85, 75, 60, 50 };
2375 : const u8 empty[3] = { 0, 0, 0 };
2376 :
2377 0 : for (i = 0; i < 4; i++) {
2378 : int uninitialized_var(width), height;
2379 0 : cvt = &(timing->data.other_data.data.cvt[i]);
2380 :
2381 0 : if (!memcmp(cvt->code, empty, 3))
2382 0 : continue;
2383 :
2384 0 : height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2;
2385 0 : switch (cvt->code[1] & 0x0c) {
2386 : case 0x00:
2387 0 : width = height * 4 / 3;
2388 0 : break;
2389 : case 0x04:
2390 0 : width = height * 16 / 9;
2391 0 : break;
2392 : case 0x08:
2393 0 : width = height * 16 / 10;
2394 0 : break;
2395 : case 0x0c:
2396 0 : width = height * 15 / 9;
2397 0 : break;
2398 : }
2399 :
2400 0 : for (j = 1; j < 5; j++) {
2401 0 : if (cvt->code[2] & (1 << j)) {
2402 0 : newmode = drm_cvt_mode(dev, width, height,
2403 0 : rates[j], j == 0,
2404 : false, false);
2405 0 : if (newmode) {
2406 0 : drm_mode_probed_add(connector, newmode);
2407 0 : modes++;
2408 0 : }
2409 : }
2410 : }
2411 0 : }
2412 :
2413 0 : return modes;
2414 : }
2415 :
2416 : static void
2417 0 : do_cvt_mode(struct detailed_timing *timing, void *c)
2418 : {
2419 0 : struct detailed_mode_closure *closure = c;
2420 0 : struct detailed_non_pixel *data = &timing->data.other_data;
2421 :
2422 0 : if (data->type == EDID_DETAIL_CVT_3BYTE)
2423 0 : closure->modes += drm_cvt_modes(closure->connector, timing);
2424 0 : }
2425 :
2426 : static int
2427 0 : add_cvt_modes(struct drm_connector *connector, struct edid *edid)
2428 : {
2429 0 : struct detailed_mode_closure closure = {
2430 : .connector = connector,
2431 : .edid = edid,
2432 : };
2433 :
2434 0 : if (version_greater(edid, 1, 2))
2435 0 : drm_for_each_detailed_block((u8 *)edid, do_cvt_mode, &closure);
2436 :
2437 : /* XXX should also look for CVT codes in VTB blocks */
2438 :
2439 0 : return closure.modes;
2440 0 : }
2441 :
2442 : static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode);
2443 :
2444 : static void
2445 0 : do_detailed_mode(struct detailed_timing *timing, void *c)
2446 : {
2447 0 : struct detailed_mode_closure *closure = c;
2448 : struct drm_display_mode *newmode;
2449 :
2450 0 : if (timing->pixel_clock) {
2451 0 : newmode = drm_mode_detailed(closure->connector->dev,
2452 0 : closure->edid, timing,
2453 0 : closure->quirks);
2454 0 : if (!newmode)
2455 0 : return;
2456 :
2457 0 : if (closure->preferred)
2458 0 : newmode->type |= DRM_MODE_TYPE_PREFERRED;
2459 :
2460 : /*
2461 : * Detailed modes are limited to 10kHz pixel clock resolution,
2462 : * so fix up anything that looks like CEA/HDMI mode, but the clock
2463 : * is just slightly off.
2464 : */
2465 0 : fixup_detailed_cea_mode_clock(newmode);
2466 :
2467 0 : drm_mode_probed_add(closure->connector, newmode);
2468 0 : closure->modes++;
2469 0 : closure->preferred = 0;
2470 0 : }
2471 0 : }
2472 :
2473 : /*
2474 : * add_detailed_modes - Add modes from detailed timings
2475 : * @connector: attached connector
2476 : * @edid: EDID block to scan
2477 : * @quirks: quirks to apply
2478 : */
2479 : static int
2480 0 : add_detailed_modes(struct drm_connector *connector, struct edid *edid,
2481 : u32 quirks)
2482 : {
2483 0 : struct detailed_mode_closure closure = {
2484 : .connector = connector,
2485 : .edid = edid,
2486 : .preferred = 1,
2487 : .quirks = quirks,
2488 : };
2489 :
2490 0 : if (closure.preferred && !version_greater(edid, 1, 3))
2491 0 : closure.preferred =
2492 0 : (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
2493 :
2494 0 : drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure);
2495 :
2496 0 : return closure.modes;
2497 0 : }
2498 :
2499 : #define AUDIO_BLOCK 0x01
2500 : #define VIDEO_BLOCK 0x02
2501 : #define VENDOR_BLOCK 0x03
2502 : #define SPEAKER_BLOCK 0x04
2503 : #define VIDEO_CAPABILITY_BLOCK 0x07
2504 : #define EDID_BASIC_AUDIO (1 << 6)
2505 : #define EDID_CEA_YCRCB444 (1 << 5)
2506 : #define EDID_CEA_YCRCB422 (1 << 4)
2507 : #define EDID_CEA_VCDB_QS (1 << 6)
2508 :
2509 : /*
2510 : * Search EDID for CEA extension block.
2511 : */
2512 0 : static u8 *drm_find_edid_extension(struct edid *edid, int ext_id)
2513 : {
2514 : u8 *edid_ext = NULL;
2515 : int i;
2516 :
2517 : /* No EDID or EDID extensions */
2518 0 : if (edid == NULL || edid->extensions == 0)
2519 0 : return NULL;
2520 :
2521 : /* Find CEA extension */
2522 0 : for (i = 0; i < edid->extensions; i++) {
2523 0 : edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
2524 0 : if (edid_ext[0] == ext_id)
2525 : break;
2526 : }
2527 :
2528 0 : if (i == edid->extensions)
2529 0 : return NULL;
2530 :
2531 0 : return edid_ext;
2532 0 : }
2533 :
2534 0 : static u8 *drm_find_cea_extension(struct edid *edid)
2535 : {
2536 0 : return drm_find_edid_extension(edid, CEA_EXT);
2537 : }
2538 :
2539 0 : static u8 *drm_find_displayid_extension(struct edid *edid)
2540 : {
2541 0 : return drm_find_edid_extension(edid, DISPLAYID_EXT);
2542 : }
2543 :
2544 : /*
2545 : * Calculate the alternate clock for the CEA mode
2546 : * (60Hz vs. 59.94Hz etc.)
2547 : */
2548 : static unsigned int
2549 0 : cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
2550 : {
2551 0 : unsigned int clock = cea_mode->clock;
2552 :
2553 0 : if (cea_mode->vrefresh % 6 != 0)
2554 0 : return clock;
2555 :
2556 : /*
2557 : * edid_cea_modes contains the 59.94Hz
2558 : * variant for 240 and 480 line modes,
2559 : * and the 60Hz variant otherwise.
2560 : */
2561 0 : if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
2562 0 : clock = DIV_ROUND_CLOSEST(clock * 1001, 1000);
2563 : else
2564 0 : clock = DIV_ROUND_CLOSEST(clock * 1000, 1001);
2565 :
2566 0 : return clock;
2567 0 : }
2568 :
2569 : /**
2570 : * drm_match_cea_mode - look for a CEA mode matching given mode
2571 : * @to_match: display mode
2572 : *
2573 : * Return: The CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
2574 : * mode.
2575 : */
2576 0 : u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
2577 : {
2578 : u8 mode;
2579 :
2580 0 : if (!to_match->clock)
2581 0 : return 0;
2582 :
2583 0 : for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) {
2584 0 : const struct drm_display_mode *cea_mode = &edid_cea_modes[mode];
2585 : unsigned int clock1, clock2;
2586 :
2587 : /* Check both 60Hz and 59.94Hz */
2588 0 : clock1 = cea_mode->clock;
2589 0 : clock2 = cea_mode_alternate_clock(cea_mode);
2590 :
2591 0 : if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
2592 0 : KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
2593 0 : drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode))
2594 0 : return mode + 1;
2595 0 : }
2596 0 : return 0;
2597 0 : }
2598 : EXPORT_SYMBOL(drm_match_cea_mode);
2599 :
2600 : /**
2601 : * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to
2602 : * the input VIC from the CEA mode list
2603 : * @video_code: ID given to each of the CEA modes
2604 : *
2605 : * Returns picture aspect ratio
2606 : */
2607 0 : enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)
2608 : {
2609 : /* return picture aspect ratio for video_code - 1 to access the
2610 : * right array element
2611 : */
2612 0 : return edid_cea_modes[video_code-1].picture_aspect_ratio;
2613 : }
2614 : EXPORT_SYMBOL(drm_get_cea_aspect_ratio);
2615 :
2616 : /*
2617 : * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
2618 : * specific block).
2619 : *
2620 : * It's almost like cea_mode_alternate_clock(), we just need to add an
2621 : * exception for the VIC 4 mode (4096x2160@24Hz): no alternate clock for this
2622 : * one.
2623 : */
2624 : static unsigned int
2625 0 : hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
2626 : {
2627 0 : if (hdmi_mode->vdisplay == 4096 && hdmi_mode->hdisplay == 2160)
2628 0 : return hdmi_mode->clock;
2629 :
2630 0 : return cea_mode_alternate_clock(hdmi_mode);
2631 0 : }
2632 :
2633 : /*
2634 : * drm_match_hdmi_mode - look for a HDMI mode matching given mode
2635 : * @to_match: display mode
2636 : *
2637 : * An HDMI mode is one defined in the HDMI vendor specific block.
2638 : *
2639 : * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
2640 : */
2641 0 : static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
2642 : {
2643 : u8 mode;
2644 :
2645 0 : if (!to_match->clock)
2646 0 : return 0;
2647 :
2648 0 : for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) {
2649 0 : const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode];
2650 : unsigned int clock1, clock2;
2651 :
2652 : /* Make sure to also match alternate clocks */
2653 0 : clock1 = hdmi_mode->clock;
2654 0 : clock2 = hdmi_mode_alternate_clock(hdmi_mode);
2655 :
2656 0 : if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
2657 0 : KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
2658 0 : drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode))
2659 0 : return mode + 1;
2660 0 : }
2661 0 : return 0;
2662 0 : }
2663 :
2664 : static int
2665 0 : add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
2666 : {
2667 0 : struct drm_device *dev = connector->dev;
2668 : struct drm_display_mode *mode, *tmp;
2669 0 : DRM_LIST_HEAD(list);
2670 : int modes = 0;
2671 :
2672 : /* Don't add CEA modes if the CEA extension block is missing */
2673 0 : if (!drm_find_cea_extension(edid))
2674 0 : return 0;
2675 :
2676 : /*
2677 : * Go through all probed modes and create a new mode
2678 : * with the alternate clock for certain CEA modes.
2679 : */
2680 0 : list_for_each_entry(mode, &connector->probed_modes, head) {
2681 : const struct drm_display_mode *cea_mode = NULL;
2682 : struct drm_display_mode *newmode;
2683 0 : u8 mode_idx = drm_match_cea_mode(mode) - 1;
2684 : unsigned int clock1, clock2;
2685 :
2686 0 : if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
2687 0 : cea_mode = &edid_cea_modes[mode_idx];
2688 0 : clock2 = cea_mode_alternate_clock(cea_mode);
2689 0 : } else {
2690 0 : mode_idx = drm_match_hdmi_mode(mode) - 1;
2691 0 : if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
2692 0 : cea_mode = &edid_4k_modes[mode_idx];
2693 0 : clock2 = hdmi_mode_alternate_clock(cea_mode);
2694 0 : }
2695 : }
2696 :
2697 0 : if (!cea_mode)
2698 0 : continue;
2699 :
2700 0 : clock1 = cea_mode->clock;
2701 :
2702 0 : if (clock1 == clock2)
2703 0 : continue;
2704 :
2705 0 : if (mode->clock != clock1 && mode->clock != clock2)
2706 0 : continue;
2707 :
2708 0 : newmode = drm_mode_duplicate(dev, cea_mode);
2709 0 : if (!newmode)
2710 0 : continue;
2711 :
2712 : /* Carry over the stereo flags */
2713 0 : newmode->flags |= mode->flags & DRM_MODE_FLAG_3D_MASK;
2714 :
2715 : /*
2716 : * The current mode could be either variant. Make
2717 : * sure to pick the "other" clock for the new mode.
2718 : */
2719 0 : if (mode->clock != clock1)
2720 0 : newmode->clock = clock1;
2721 : else
2722 0 : newmode->clock = clock2;
2723 :
2724 0 : list_add_tail(&newmode->head, &list);
2725 0 : }
2726 :
2727 0 : list_for_each_entry_safe(mode, tmp, &list, head) {
2728 0 : list_del(&mode->head);
2729 0 : drm_mode_probed_add(connector, mode);
2730 0 : modes++;
2731 : }
2732 :
2733 0 : return modes;
2734 0 : }
2735 :
2736 : static struct drm_display_mode *
2737 0 : drm_display_mode_from_vic_index(struct drm_connector *connector,
2738 : const u8 *video_db, u8 video_len,
2739 : u8 video_index)
2740 : {
2741 0 : struct drm_device *dev = connector->dev;
2742 : struct drm_display_mode *newmode;
2743 : u8 cea_mode;
2744 :
2745 0 : if (video_db == NULL || video_index >= video_len)
2746 0 : return NULL;
2747 :
2748 : /* CEA modes are numbered 1..127 */
2749 0 : cea_mode = (video_db[video_index] & 127) - 1;
2750 0 : if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
2751 0 : return NULL;
2752 :
2753 0 : newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]);
2754 0 : if (!newmode)
2755 0 : return NULL;
2756 :
2757 0 : newmode->vrefresh = 0;
2758 :
2759 0 : return newmode;
2760 0 : }
2761 :
2762 : static int
2763 0 : do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
2764 : {
2765 : int i, modes = 0;
2766 :
2767 0 : for (i = 0; i < len; i++) {
2768 : struct drm_display_mode *mode;
2769 0 : mode = drm_display_mode_from_vic_index(connector, db, len, i);
2770 0 : if (mode) {
2771 0 : drm_mode_probed_add(connector, mode);
2772 0 : modes++;
2773 0 : }
2774 : }
2775 :
2776 0 : return modes;
2777 : }
2778 :
2779 : struct stereo_mandatory_mode {
2780 : int width, height, vrefresh;
2781 : unsigned int flags;
2782 : };
2783 :
2784 : static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
2785 : { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
2786 : { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING },
2787 : { 1920, 1080, 50,
2788 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
2789 : { 1920, 1080, 60,
2790 : DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
2791 : { 1280, 720, 50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
2792 : { 1280, 720, 50, DRM_MODE_FLAG_3D_FRAME_PACKING },
2793 : { 1280, 720, 60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
2794 : { 1280, 720, 60, DRM_MODE_FLAG_3D_FRAME_PACKING }
2795 : };
2796 :
2797 : static bool
2798 0 : stereo_match_mandatory(const struct drm_display_mode *mode,
2799 : const struct stereo_mandatory_mode *stereo_mode)
2800 : {
2801 0 : unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
2802 :
2803 0 : return mode->hdisplay == stereo_mode->width &&
2804 0 : mode->vdisplay == stereo_mode->height &&
2805 0 : interlaced == (stereo_mode->flags & DRM_MODE_FLAG_INTERLACE) &&
2806 0 : drm_mode_vrefresh(mode) == stereo_mode->vrefresh;
2807 : }
2808 :
2809 0 : static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
2810 : {
2811 0 : struct drm_device *dev = connector->dev;
2812 : const struct drm_display_mode *mode;
2813 0 : struct list_head stereo_modes;
2814 : int modes = 0, i;
2815 :
2816 0 : INIT_LIST_HEAD(&stereo_modes);
2817 :
2818 0 : list_for_each_entry(mode, &connector->probed_modes, head) {
2819 0 : for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) {
2820 : const struct stereo_mandatory_mode *mandatory;
2821 : struct drm_display_mode *new_mode;
2822 :
2823 0 : if (!stereo_match_mandatory(mode,
2824 0 : &stereo_mandatory_modes[i]))
2825 0 : continue;
2826 :
2827 : mandatory = &stereo_mandatory_modes[i];
2828 0 : new_mode = drm_mode_duplicate(dev, mode);
2829 0 : if (!new_mode)
2830 0 : continue;
2831 :
2832 0 : new_mode->flags |= mandatory->flags;
2833 0 : list_add_tail(&new_mode->head, &stereo_modes);
2834 0 : modes++;
2835 0 : }
2836 : }
2837 :
2838 0 : list_splice_tail(&stereo_modes, &connector->probed_modes);
2839 :
2840 0 : return modes;
2841 0 : }
2842 :
2843 0 : static int add_hdmi_mode(struct drm_connector *connector, u8 vic)
2844 : {
2845 0 : struct drm_device *dev = connector->dev;
2846 : struct drm_display_mode *newmode;
2847 :
2848 0 : vic--; /* VICs start at 1 */
2849 0 : if (vic >= ARRAY_SIZE(edid_4k_modes)) {
2850 0 : DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
2851 0 : return 0;
2852 : }
2853 :
2854 0 : newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
2855 0 : if (!newmode)
2856 0 : return 0;
2857 :
2858 0 : drm_mode_probed_add(connector, newmode);
2859 :
2860 0 : return 1;
2861 0 : }
2862 :
2863 0 : static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
2864 : const u8 *video_db, u8 video_len, u8 video_index)
2865 : {
2866 : struct drm_display_mode *newmode;
2867 : int modes = 0;
2868 :
2869 0 : if (structure & (1 << 0)) {
2870 0 : newmode = drm_display_mode_from_vic_index(connector, video_db,
2871 : video_len,
2872 : video_index);
2873 0 : if (newmode) {
2874 0 : newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
2875 0 : drm_mode_probed_add(connector, newmode);
2876 : modes++;
2877 0 : }
2878 : }
2879 0 : if (structure & (1 << 6)) {
2880 0 : newmode = drm_display_mode_from_vic_index(connector, video_db,
2881 : video_len,
2882 : video_index);
2883 0 : if (newmode) {
2884 0 : newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
2885 0 : drm_mode_probed_add(connector, newmode);
2886 0 : modes++;
2887 0 : }
2888 : }
2889 0 : if (structure & (1 << 8)) {
2890 0 : newmode = drm_display_mode_from_vic_index(connector, video_db,
2891 : video_len,
2892 : video_index);
2893 0 : if (newmode) {
2894 0 : newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
2895 0 : drm_mode_probed_add(connector, newmode);
2896 0 : modes++;
2897 0 : }
2898 : }
2899 :
2900 0 : return modes;
2901 : }
2902 :
2903 : /*
2904 : * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
2905 : * @connector: connector corresponding to the HDMI sink
2906 : * @db: start of the CEA vendor specific block
2907 : * @len: length of the CEA block payload, ie. one can access up to db[len]
2908 : *
2909 : * Parses the HDMI VSDB looking for modes to add to @connector. This function
2910 : * also adds the stereo 3d modes when applicable.
2911 : */
2912 : static int
2913 0 : do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
2914 : const u8 *video_db, u8 video_len)
2915 : {
2916 : int modes = 0, offset = 0, i, multi_present = 0, multi_len;
2917 : u8 vic_len, hdmi_3d_len = 0;
2918 : u16 mask;
2919 : u16 structure_all;
2920 :
2921 0 : if (len < 8)
2922 : goto out;
2923 :
2924 : /* no HDMI_Video_Present */
2925 0 : if (!(db[8] & (1 << 5)))
2926 : goto out;
2927 :
2928 : /* Latency_Fields_Present */
2929 0 : if (db[8] & (1 << 7))
2930 0 : offset += 2;
2931 :
2932 : /* I_Latency_Fields_Present */
2933 0 : if (db[8] & (1 << 6))
2934 0 : offset += 2;
2935 :
2936 : /* the declared length is not long enough for the 2 first bytes
2937 : * of additional video format capabilities */
2938 0 : if (len < (8 + offset + 2))
2939 : goto out;
2940 :
2941 : /* 3D_Present */
2942 0 : offset++;
2943 0 : if (db[8 + offset] & (1 << 7)) {
2944 0 : modes += add_hdmi_mandatory_stereo_modes(connector);
2945 :
2946 : /* 3D_Multi_present */
2947 0 : multi_present = (db[8 + offset] & 0x60) >> 5;
2948 0 : }
2949 :
2950 0 : offset++;
2951 0 : vic_len = db[8 + offset] >> 5;
2952 0 : hdmi_3d_len = db[8 + offset] & 0x1f;
2953 :
2954 0 : for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
2955 : u8 vic;
2956 :
2957 0 : vic = db[9 + offset + i];
2958 0 : modes += add_hdmi_mode(connector, vic);
2959 : }
2960 0 : offset += 1 + vic_len;
2961 :
2962 0 : if (multi_present == 1)
2963 0 : multi_len = 2;
2964 0 : else if (multi_present == 2)
2965 0 : multi_len = 4;
2966 : else
2967 : multi_len = 0;
2968 :
2969 0 : if (len < (8 + offset + hdmi_3d_len - 1))
2970 : goto out;
2971 :
2972 0 : if (hdmi_3d_len < multi_len)
2973 : goto out;
2974 :
2975 0 : if (multi_present == 1 || multi_present == 2) {
2976 : /* 3D_Structure_ALL */
2977 0 : structure_all = (db[8 + offset] << 8) | db[9 + offset];
2978 :
2979 : /* check if 3D_MASK is present */
2980 0 : if (multi_present == 2)
2981 0 : mask = (db[10 + offset] << 8) | db[11 + offset];
2982 : else
2983 : mask = 0xffff;
2984 :
2985 0 : for (i = 0; i < 16; i++) {
2986 0 : if (mask & (1 << i))
2987 0 : modes += add_3d_struct_modes(connector,
2988 : structure_all,
2989 : video_db,
2990 0 : video_len, i);
2991 : }
2992 : }
2993 :
2994 0 : offset += multi_len;
2995 :
2996 0 : for (i = 0; i < (hdmi_3d_len - multi_len); i++) {
2997 : int vic_index;
2998 : struct drm_display_mode *newmode = NULL;
2999 : unsigned int newflag = 0;
3000 : bool detail_present;
3001 :
3002 0 : detail_present = ((db[8 + offset + i] & 0x0f) > 7);
3003 :
3004 0 : if (detail_present && (i + 1 == hdmi_3d_len - multi_len))
3005 0 : break;
3006 :
3007 : /* 2D_VIC_order_X */
3008 0 : vic_index = db[8 + offset + i] >> 4;
3009 :
3010 : /* 3D_Structure_X */
3011 0 : switch (db[8 + offset + i] & 0x0f) {
3012 : case 0:
3013 : newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
3014 0 : break;
3015 : case 6:
3016 : newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
3017 0 : break;
3018 : case 8:
3019 : /* 3D_Detail_X */
3020 0 : if ((db[9 + offset + i] >> 4) == 1)
3021 0 : newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
3022 : break;
3023 : }
3024 :
3025 0 : if (newflag != 0) {
3026 0 : newmode = drm_display_mode_from_vic_index(connector,
3027 : video_db,
3028 : video_len,
3029 0 : vic_index);
3030 :
3031 0 : if (newmode) {
3032 0 : newmode->flags |= newflag;
3033 0 : drm_mode_probed_add(connector, newmode);
3034 0 : modes++;
3035 0 : }
3036 : }
3037 :
3038 0 : if (detail_present)
3039 0 : i++;
3040 0 : }
3041 :
3042 : out:
3043 0 : return modes;
3044 : }
3045 :
3046 : static int
3047 0 : cea_db_payload_len(const u8 *db)
3048 : {
3049 0 : return db[0] & 0x1f;
3050 : }
3051 :
3052 : static int
3053 0 : cea_db_tag(const u8 *db)
3054 : {
3055 0 : return db[0] >> 5;
3056 : }
3057 :
3058 : static int
3059 0 : cea_revision(const u8 *cea)
3060 : {
3061 0 : return cea[1];
3062 : }
3063 :
3064 : static int
3065 0 : cea_db_offsets(const u8 *cea, int *start, int *end)
3066 : {
3067 : /* Data block offset in CEA extension block */
3068 0 : *start = 4;
3069 0 : *end = cea[2];
3070 0 : if (*end == 0)
3071 0 : *end = 127;
3072 0 : if (*end < 4 || *end > 127)
3073 0 : return -ERANGE;
3074 0 : return 0;
3075 0 : }
3076 :
3077 0 : static bool cea_db_is_hdmi_vsdb(const u8 *db)
3078 : {
3079 : int hdmi_id;
3080 :
3081 0 : if (cea_db_tag(db) != VENDOR_BLOCK)
3082 0 : return false;
3083 :
3084 0 : if (cea_db_payload_len(db) < 5)
3085 0 : return false;
3086 :
3087 0 : hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
3088 :
3089 0 : return hdmi_id == HDMI_IEEE_OUI;
3090 0 : }
3091 :
3092 : #define for_each_cea_db(cea, i, start, end) \
3093 : for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
3094 :
3095 : static int
3096 0 : add_cea_modes(struct drm_connector *connector, struct edid *edid)
3097 : {
3098 0 : const u8 *cea = drm_find_cea_extension(edid);
3099 : const u8 *db, *hdmi = NULL, *video = NULL;
3100 : u8 dbl, hdmi_len, video_len = 0;
3101 : int modes = 0;
3102 :
3103 0 : if (cea && cea_revision(cea) >= 3) {
3104 0 : int i, start, end;
3105 :
3106 0 : if (cea_db_offsets(cea, &start, &end))
3107 0 : return 0;
3108 :
3109 0 : for_each_cea_db(cea, i, start, end) {
3110 : db = &cea[i];
3111 0 : dbl = cea_db_payload_len(db);
3112 :
3113 0 : if (cea_db_tag(db) == VIDEO_BLOCK) {
3114 0 : video = db + 1;
3115 : video_len = dbl;
3116 0 : modes += do_cea_modes(connector, video, dbl);
3117 0 : }
3118 0 : else if (cea_db_is_hdmi_vsdb(db)) {
3119 : hdmi = db;
3120 : hdmi_len = dbl;
3121 0 : }
3122 : }
3123 0 : }
3124 :
3125 : /*
3126 : * We parse the HDMI VSDB after having added the cea modes as we will
3127 : * be patching their flags when the sink supports stereo 3D.
3128 : */
3129 0 : if (hdmi)
3130 0 : modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
3131 : video_len);
3132 :
3133 0 : return modes;
3134 0 : }
3135 :
3136 0 : static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
3137 : {
3138 : const struct drm_display_mode *cea_mode;
3139 : int clock1, clock2, clock;
3140 : u8 mode_idx;
3141 : const char *type;
3142 :
3143 0 : mode_idx = drm_match_cea_mode(mode) - 1;
3144 0 : if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
3145 : type = "CEA";
3146 0 : cea_mode = &edid_cea_modes[mode_idx];
3147 0 : clock1 = cea_mode->clock;
3148 0 : clock2 = cea_mode_alternate_clock(cea_mode);
3149 0 : } else {
3150 0 : mode_idx = drm_match_hdmi_mode(mode) - 1;
3151 0 : if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
3152 : type = "HDMI";
3153 0 : cea_mode = &edid_4k_modes[mode_idx];
3154 0 : clock1 = cea_mode->clock;
3155 0 : clock2 = hdmi_mode_alternate_clock(cea_mode);
3156 : } else {
3157 0 : return;
3158 : }
3159 : }
3160 :
3161 : /* pick whichever is closest */
3162 0 : if (abs(mode->clock - clock1) < abs(mode->clock - clock2))
3163 0 : clock = clock1;
3164 : else
3165 : clock = clock2;
3166 :
3167 0 : if (mode->clock == clock)
3168 0 : return;
3169 :
3170 : DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n",
3171 : type, mode_idx + 1, mode->clock, clock);
3172 0 : mode->clock = clock;
3173 0 : }
3174 :
3175 : static void
3176 0 : parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
3177 : {
3178 0 : u8 len = cea_db_payload_len(db);
3179 :
3180 0 : if (len >= 6) {
3181 0 : connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */
3182 0 : connector->dvi_dual = db[6] & 1;
3183 0 : }
3184 0 : if (len >= 7)
3185 0 : connector->max_tmds_clock = db[7] * 5;
3186 0 : if (len >= 8) {
3187 0 : connector->latency_present[0] = db[8] >> 7;
3188 0 : connector->latency_present[1] = (db[8] >> 6) & 1;
3189 0 : }
3190 0 : if (len >= 9)
3191 0 : connector->video_latency[0] = db[9];
3192 0 : if (len >= 10)
3193 0 : connector->audio_latency[0] = db[10];
3194 0 : if (len >= 11)
3195 0 : connector->video_latency[1] = db[11];
3196 0 : if (len >= 12)
3197 0 : connector->audio_latency[1] = db[12];
3198 :
3199 : DRM_DEBUG_KMS("HDMI: DVI dual %d, "
3200 : "max TMDS clock %d, "
3201 : "latency present %d %d, "
3202 : "video latency %d %d, "
3203 : "audio latency %d %d\n",
3204 : connector->dvi_dual,
3205 : connector->max_tmds_clock,
3206 : (int) connector->latency_present[0],
3207 : (int) connector->latency_present[1],
3208 : connector->video_latency[0],
3209 : connector->video_latency[1],
3210 : connector->audio_latency[0],
3211 : connector->audio_latency[1]);
3212 0 : }
3213 :
3214 : static void
3215 0 : monitor_name(struct detailed_timing *t, void *data)
3216 : {
3217 0 : if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
3218 0 : *(u8 **)data = t->data.other_data.data.str.str;
3219 0 : }
3220 :
3221 : /**
3222 : * drm_edid_to_eld - build ELD from EDID
3223 : * @connector: connector corresponding to the HDMI/DP sink
3224 : * @edid: EDID to parse
3225 : *
3226 : * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
3227 : * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
3228 : */
3229 0 : void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
3230 : {
3231 0 : uint8_t *eld = connector->eld;
3232 : u8 *cea;
3233 0 : u8 *name;
3234 : u8 *db;
3235 : int sad_count = 0;
3236 : int mnl;
3237 : int dbl;
3238 :
3239 0 : memset(eld, 0, sizeof(connector->eld));
3240 :
3241 0 : cea = drm_find_cea_extension(edid);
3242 0 : if (!cea) {
3243 : DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
3244 0 : return;
3245 : }
3246 :
3247 0 : name = NULL;
3248 0 : drm_for_each_detailed_block((u8 *)edid, monitor_name, &name);
3249 0 : for (mnl = 0; name && mnl < 13; mnl++) {
3250 0 : if (name[mnl] == 0x0a)
3251 : break;
3252 0 : eld[20 + mnl] = name[mnl];
3253 : }
3254 0 : eld[4] = (cea[1] << 5) | mnl;
3255 : DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20);
3256 :
3257 0 : eld[0] = 2 << 3; /* ELD version: 2 */
3258 :
3259 0 : eld[16] = edid->mfg_id[0];
3260 0 : eld[17] = edid->mfg_id[1];
3261 0 : eld[18] = edid->prod_code[0];
3262 0 : eld[19] = edid->prod_code[1];
3263 :
3264 0 : if (cea_revision(cea) >= 3) {
3265 0 : int i, start, end;
3266 :
3267 0 : if (cea_db_offsets(cea, &start, &end)) {
3268 0 : start = 0;
3269 0 : end = 0;
3270 0 : }
3271 :
3272 0 : for_each_cea_db(cea, i, start, end) {
3273 : db = &cea[i];
3274 0 : dbl = cea_db_payload_len(db);
3275 :
3276 0 : switch (cea_db_tag(db)) {
3277 : case AUDIO_BLOCK:
3278 : /* Audio Data Block, contains SADs */
3279 0 : sad_count = dbl / 3;
3280 0 : if (dbl >= 1)
3281 0 : memcpy(eld + 20 + mnl, &db[1], dbl);
3282 : break;
3283 : case SPEAKER_BLOCK:
3284 : /* Speaker Allocation Data Block */
3285 0 : if (dbl >= 1)
3286 0 : eld[7] = db[1];
3287 : break;
3288 : case VENDOR_BLOCK:
3289 : /* HDMI Vendor-Specific Data Block */
3290 0 : if (cea_db_is_hdmi_vsdb(db))
3291 0 : parse_hdmi_vsdb(connector, db);
3292 : break;
3293 : default:
3294 : break;
3295 : }
3296 : }
3297 0 : }
3298 0 : eld[5] |= sad_count << 4;
3299 :
3300 0 : if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
3301 0 : connector->connector_type == DRM_MODE_CONNECTOR_eDP)
3302 0 : eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_DP;
3303 : else
3304 0 : eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_HDMI;
3305 :
3306 0 : eld[DRM_ELD_BASELINE_ELD_LEN] =
3307 0 : DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4);
3308 :
3309 : DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
3310 : drm_eld_size(eld), sad_count);
3311 0 : }
3312 : EXPORT_SYMBOL(drm_edid_to_eld);
3313 :
3314 : /**
3315 : * drm_edid_to_sad - extracts SADs from EDID
3316 : * @edid: EDID to parse
3317 : * @sads: pointer that will be set to the extracted SADs
3318 : *
3319 : * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it.
3320 : *
3321 : * Note: The returned pointer needs to be freed using kfree().
3322 : *
3323 : * Return: The number of found SADs or negative number on error.
3324 : */
3325 0 : int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
3326 : {
3327 : int count = 0;
3328 0 : int i, start, end, dbl;
3329 : u8 *cea;
3330 :
3331 0 : cea = drm_find_cea_extension(edid);
3332 0 : if (!cea) {
3333 : DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
3334 0 : return -ENOENT;
3335 : }
3336 :
3337 0 : if (cea_revision(cea) < 3) {
3338 : DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
3339 0 : return -ENOTSUPP;
3340 : }
3341 :
3342 0 : if (cea_db_offsets(cea, &start, &end)) {
3343 : DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
3344 0 : return -EPROTO;
3345 : }
3346 :
3347 0 : for_each_cea_db(cea, i, start, end) {
3348 : u8 *db = &cea[i];
3349 :
3350 0 : if (cea_db_tag(db) == AUDIO_BLOCK) {
3351 : int j;
3352 0 : dbl = cea_db_payload_len(db);
3353 :
3354 0 : count = dbl / 3; /* SAD is 3B */
3355 0 : *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
3356 0 : if (!*sads)
3357 0 : return -ENOMEM;
3358 0 : for (j = 0; j < count; j++) {
3359 0 : u8 *sad = &db[1 + j * 3];
3360 :
3361 0 : (*sads)[j].format = (sad[0] & 0x78) >> 3;
3362 0 : (*sads)[j].channels = sad[0] & 0x7;
3363 0 : (*sads)[j].freq = sad[1] & 0x7F;
3364 0 : (*sads)[j].byte2 = sad[2];
3365 : }
3366 0 : break;
3367 : }
3368 0 : }
3369 :
3370 0 : return count;
3371 0 : }
3372 : EXPORT_SYMBOL(drm_edid_to_sad);
3373 :
3374 : /**
3375 : * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID
3376 : * @edid: EDID to parse
3377 : * @sadb: pointer to the speaker block
3378 : *
3379 : * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it.
3380 : *
3381 : * Note: The returned pointer needs to be freed using kfree().
3382 : *
3383 : * Return: The number of found Speaker Allocation Blocks or negative number on
3384 : * error.
3385 : */
3386 0 : int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
3387 : {
3388 : int count = 0;
3389 0 : int i, start, end, dbl;
3390 : const u8 *cea;
3391 :
3392 0 : cea = drm_find_cea_extension(edid);
3393 0 : if (!cea) {
3394 : DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
3395 0 : return -ENOENT;
3396 : }
3397 :
3398 0 : if (cea_revision(cea) < 3) {
3399 : DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
3400 0 : return -ENOTSUPP;
3401 : }
3402 :
3403 0 : if (cea_db_offsets(cea, &start, &end)) {
3404 : DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
3405 0 : return -EPROTO;
3406 : }
3407 :
3408 0 : for_each_cea_db(cea, i, start, end) {
3409 : const u8 *db = &cea[i];
3410 :
3411 0 : if (cea_db_tag(db) == SPEAKER_BLOCK) {
3412 0 : dbl = cea_db_payload_len(db);
3413 :
3414 : /* Speaker Allocation Data Block */
3415 0 : if (dbl == 3) {
3416 0 : *sadb = kmemdup(&db[1], dbl, GFP_KERNEL);
3417 0 : if (!*sadb)
3418 0 : return -ENOMEM;
3419 : count = dbl;
3420 0 : break;
3421 : }
3422 : }
3423 0 : }
3424 :
3425 0 : return count;
3426 0 : }
3427 : EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
3428 :
3429 : /**
3430 : * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
3431 : * @connector: connector associated with the HDMI/DP sink
3432 : * @mode: the display mode
3433 : *
3434 : * Return: The HDMI/DP sink's audio-video sync delay in milliseconds or 0 if
3435 : * the sink doesn't support audio or video.
3436 : */
3437 0 : int drm_av_sync_delay(struct drm_connector *connector,
3438 : const struct drm_display_mode *mode)
3439 : {
3440 0 : int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
3441 : int a, v;
3442 :
3443 0 : if (!connector->latency_present[0])
3444 0 : return 0;
3445 0 : if (!connector->latency_present[1])
3446 0 : i = 0;
3447 :
3448 0 : a = connector->audio_latency[i];
3449 0 : v = connector->video_latency[i];
3450 :
3451 : /*
3452 : * HDMI/DP sink doesn't support audio or video?
3453 : */
3454 0 : if (a == 255 || v == 255)
3455 0 : return 0;
3456 :
3457 : /*
3458 : * Convert raw EDID values to millisecond.
3459 : * Treat unknown latency as 0ms.
3460 : */
3461 0 : if (a)
3462 0 : a = min(2 * (a - 1), 500);
3463 0 : if (v)
3464 0 : v = min(2 * (v - 1), 500);
3465 :
3466 0 : return max(v - a, 0);
3467 0 : }
3468 : EXPORT_SYMBOL(drm_av_sync_delay);
3469 :
3470 : /**
3471 : * drm_select_eld - select one ELD from multiple HDMI/DP sinks
3472 : * @encoder: the encoder just changed display mode
3473 : *
3474 : * It's possible for one encoder to be associated with multiple HDMI/DP sinks.
3475 : * The policy is now hard coded to simply use the first HDMI/DP sink's ELD.
3476 : *
3477 : * Return: The connector associated with the first HDMI/DP sink that has ELD
3478 : * attached to it.
3479 : */
3480 0 : struct drm_connector *drm_select_eld(struct drm_encoder *encoder)
3481 : {
3482 : struct drm_connector *connector;
3483 0 : struct drm_device *dev = encoder->dev;
3484 :
3485 0 : WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
3486 0 : WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
3487 :
3488 0 : drm_for_each_connector(connector, dev)
3489 0 : if (connector->encoder == encoder && connector->eld[0])
3490 0 : return connector;
3491 :
3492 0 : return NULL;
3493 0 : }
3494 : EXPORT_SYMBOL(drm_select_eld);
3495 :
3496 : /**
3497 : * drm_detect_hdmi_monitor - detect whether monitor is HDMI
3498 : * @edid: monitor EDID information
3499 : *
3500 : * Parse the CEA extension according to CEA-861-B.
3501 : *
3502 : * Return: True if the monitor is HDMI, false if not or unknown.
3503 : */
3504 0 : bool drm_detect_hdmi_monitor(struct edid *edid)
3505 : {
3506 : u8 *edid_ext;
3507 : int i;
3508 0 : int start_offset, end_offset;
3509 :
3510 0 : edid_ext = drm_find_cea_extension(edid);
3511 0 : if (!edid_ext)
3512 0 : return false;
3513 :
3514 0 : if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
3515 0 : return false;
3516 :
3517 : /*
3518 : * Because HDMI identifier is in Vendor Specific Block,
3519 : * search it from all data blocks of CEA extension.
3520 : */
3521 0 : for_each_cea_db(edid_ext, i, start_offset, end_offset) {
3522 0 : if (cea_db_is_hdmi_vsdb(&edid_ext[i]))
3523 0 : return true;
3524 : }
3525 :
3526 0 : return false;
3527 0 : }
3528 : EXPORT_SYMBOL(drm_detect_hdmi_monitor);
3529 :
3530 : /**
3531 : * drm_detect_monitor_audio - check monitor audio capability
3532 : * @edid: EDID block to scan
3533 : *
3534 : * Monitor should have CEA extension block.
3535 : * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
3536 : * audio' only. If there is any audio extension block and supported
3537 : * audio format, assume at least 'basic audio' support, even if 'basic
3538 : * audio' is not defined in EDID.
3539 : *
3540 : * Return: True if the monitor supports audio, false otherwise.
3541 : */
3542 0 : bool drm_detect_monitor_audio(struct edid *edid)
3543 : {
3544 : u8 *edid_ext;
3545 : int i, j;
3546 : bool has_audio = false;
3547 0 : int start_offset, end_offset;
3548 :
3549 0 : edid_ext = drm_find_cea_extension(edid);
3550 0 : if (!edid_ext)
3551 : goto end;
3552 :
3553 0 : has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
3554 :
3555 0 : if (has_audio) {
3556 : DRM_DEBUG_KMS("Monitor has basic audio support\n");
3557 : goto end;
3558 : }
3559 :
3560 0 : if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
3561 : goto end;
3562 :
3563 0 : for_each_cea_db(edid_ext, i, start_offset, end_offset) {
3564 0 : if (cea_db_tag(&edid_ext[i]) == AUDIO_BLOCK) {
3565 : has_audio = true;
3566 0 : for (j = 1; j < cea_db_payload_len(&edid_ext[i]) + 1; j += 3)
3567 : DRM_DEBUG_KMS("CEA audio format %d\n",
3568 : (edid_ext[i + j] >> 3) & 0xf);
3569 : goto end;
3570 : }
3571 : }
3572 : end:
3573 0 : return has_audio;
3574 0 : }
3575 : EXPORT_SYMBOL(drm_detect_monitor_audio);
3576 :
3577 : /**
3578 : * drm_rgb_quant_range_selectable - is RGB quantization range selectable?
3579 : * @edid: EDID block to scan
3580 : *
3581 : * Check whether the monitor reports the RGB quantization range selection
3582 : * as supported. The AVI infoframe can then be used to inform the monitor
3583 : * which quantization range (full or limited) is used.
3584 : *
3585 : * Return: True if the RGB quantization range is selectable, false otherwise.
3586 : */
3587 0 : bool drm_rgb_quant_range_selectable(struct edid *edid)
3588 : {
3589 : u8 *edid_ext;
3590 0 : int i, start, end;
3591 :
3592 0 : edid_ext = drm_find_cea_extension(edid);
3593 0 : if (!edid_ext)
3594 0 : return false;
3595 :
3596 0 : if (cea_db_offsets(edid_ext, &start, &end))
3597 0 : return false;
3598 :
3599 0 : for_each_cea_db(edid_ext, i, start, end) {
3600 0 : if (cea_db_tag(&edid_ext[i]) == VIDEO_CAPABILITY_BLOCK &&
3601 0 : cea_db_payload_len(&edid_ext[i]) == 2) {
3602 : DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
3603 0 : return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
3604 : }
3605 : }
3606 :
3607 0 : return false;
3608 0 : }
3609 : EXPORT_SYMBOL(drm_rgb_quant_range_selectable);
3610 :
3611 : /**
3612 : * drm_assign_hdmi_deep_color_info - detect whether monitor supports
3613 : * hdmi deep color modes and update drm_display_info if so.
3614 : * @edid: monitor EDID information
3615 : * @info: Updated with maximum supported deep color bpc and color format
3616 : * if deep color supported.
3617 : * @connector: DRM connector, used only for debug output
3618 : *
3619 : * Parse the CEA extension according to CEA-861-B.
3620 : * Return true if HDMI deep color supported, false if not or unknown.
3621 : */
3622 0 : static bool drm_assign_hdmi_deep_color_info(struct edid *edid,
3623 : struct drm_display_info *info,
3624 : struct drm_connector *connector)
3625 : {
3626 : u8 *edid_ext, *hdmi;
3627 : int i;
3628 0 : int start_offset, end_offset;
3629 : unsigned int dc_bpc = 0;
3630 :
3631 0 : edid_ext = drm_find_cea_extension(edid);
3632 0 : if (!edid_ext)
3633 0 : return false;
3634 :
3635 0 : if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
3636 0 : return false;
3637 :
3638 : /*
3639 : * Because HDMI identifier is in Vendor Specific Block,
3640 : * search it from all data blocks of CEA extension.
3641 : */
3642 0 : for_each_cea_db(edid_ext, i, start_offset, end_offset) {
3643 0 : if (cea_db_is_hdmi_vsdb(&edid_ext[i])) {
3644 : /* HDMI supports at least 8 bpc */
3645 0 : info->bpc = 8;
3646 :
3647 : hdmi = &edid_ext[i];
3648 0 : if (cea_db_payload_len(hdmi) < 6)
3649 0 : return false;
3650 :
3651 0 : if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
3652 : dc_bpc = 10;
3653 0 : info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
3654 : DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
3655 : connector->name);
3656 0 : }
3657 :
3658 0 : if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
3659 : dc_bpc = 12;
3660 0 : info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
3661 : DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
3662 : connector->name);
3663 0 : }
3664 :
3665 0 : if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
3666 : dc_bpc = 16;
3667 0 : info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
3668 : DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
3669 : connector->name);
3670 0 : }
3671 :
3672 0 : if (dc_bpc > 0) {
3673 : DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n",
3674 : connector->name, dc_bpc);
3675 0 : info->bpc = dc_bpc;
3676 :
3677 : /*
3678 : * Deep color support mandates RGB444 support for all video
3679 : * modes and forbids YCRCB422 support for all video modes per
3680 : * HDMI 1.3 spec.
3681 : */
3682 0 : info->color_formats = DRM_COLOR_FORMAT_RGB444;
3683 :
3684 : /* YCRCB444 is optional according to spec. */
3685 0 : if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) {
3686 0 : info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
3687 : DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n",
3688 : connector->name);
3689 0 : }
3690 :
3691 : /*
3692 : * Spec says that if any deep color mode is supported at all,
3693 : * then deep color 36 bit must be supported.
3694 : */
3695 0 : if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) {
3696 : DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n",
3697 : connector->name);
3698 : }
3699 :
3700 0 : return true;
3701 : }
3702 : else {
3703 : DRM_DEBUG("%s: No deep color support on this HDMI sink.\n",
3704 : connector->name);
3705 : }
3706 : }
3707 : }
3708 :
3709 0 : return false;
3710 0 : }
3711 :
3712 : /**
3713 : * drm_add_display_info - pull display info out if present
3714 : * @edid: EDID data
3715 : * @info: display info (attached to connector)
3716 : * @connector: connector whose edid is used to build display info
3717 : *
3718 : * Grab any available display info and stuff it into the drm_display_info
3719 : * structure that's part of the connector. Useful for tracking bpp and
3720 : * color spaces.
3721 : */
3722 0 : static void drm_add_display_info(struct edid *edid,
3723 : struct drm_display_info *info,
3724 : struct drm_connector *connector)
3725 : {
3726 : u8 *edid_ext;
3727 :
3728 0 : info->width_mm = edid->width_cm * 10;
3729 0 : info->height_mm = edid->height_cm * 10;
3730 :
3731 : /* driver figures it out in this case */
3732 0 : info->bpc = 0;
3733 0 : info->color_formats = 0;
3734 :
3735 0 : if (edid->revision < 3)
3736 0 : return;
3737 :
3738 0 : if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
3739 0 : return;
3740 :
3741 : /* Get data from CEA blocks if present */
3742 0 : edid_ext = drm_find_cea_extension(edid);
3743 0 : if (edid_ext) {
3744 0 : info->cea_rev = edid_ext[1];
3745 :
3746 : /* The existence of a CEA block should imply RGB support */
3747 0 : info->color_formats = DRM_COLOR_FORMAT_RGB444;
3748 0 : if (edid_ext[3] & EDID_CEA_YCRCB444)
3749 0 : info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
3750 0 : if (edid_ext[3] & EDID_CEA_YCRCB422)
3751 0 : info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
3752 : }
3753 :
3754 : /* HDMI deep color modes supported? Assign to info, if so */
3755 0 : drm_assign_hdmi_deep_color_info(edid, info, connector);
3756 :
3757 : /* Only defined for 1.4 with digital displays */
3758 0 : if (edid->revision < 4)
3759 0 : return;
3760 :
3761 0 : switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
3762 : case DRM_EDID_DIGITAL_DEPTH_6:
3763 0 : info->bpc = 6;
3764 0 : break;
3765 : case DRM_EDID_DIGITAL_DEPTH_8:
3766 0 : info->bpc = 8;
3767 0 : break;
3768 : case DRM_EDID_DIGITAL_DEPTH_10:
3769 0 : info->bpc = 10;
3770 0 : break;
3771 : case DRM_EDID_DIGITAL_DEPTH_12:
3772 0 : info->bpc = 12;
3773 0 : break;
3774 : case DRM_EDID_DIGITAL_DEPTH_14:
3775 0 : info->bpc = 14;
3776 0 : break;
3777 : case DRM_EDID_DIGITAL_DEPTH_16:
3778 0 : info->bpc = 16;
3779 0 : break;
3780 : case DRM_EDID_DIGITAL_DEPTH_UNDEF:
3781 : default:
3782 0 : info->bpc = 0;
3783 0 : break;
3784 : }
3785 :
3786 : DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n",
3787 : connector->name, info->bpc);
3788 :
3789 0 : info->color_formats |= DRM_COLOR_FORMAT_RGB444;
3790 0 : if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
3791 0 : info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
3792 0 : if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
3793 0 : info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
3794 0 : }
3795 :
3796 : /**
3797 : * drm_add_edid_modes - add modes from EDID data, if available
3798 : * @connector: connector we're probing
3799 : * @edid: EDID data
3800 : *
3801 : * Add the specified modes to the connector's mode list.
3802 : *
3803 : * Return: The number of modes added or 0 if we couldn't find any.
3804 : */
3805 0 : int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
3806 : {
3807 : int num_modes = 0;
3808 : u32 quirks;
3809 :
3810 0 : if (edid == NULL) {
3811 0 : return 0;
3812 : }
3813 0 : if (!drm_edid_is_valid(edid)) {
3814 0 : dev_warn(connector->dev->dev, "%s: EDID invalid.\n",
3815 : connector->name);
3816 0 : return 0;
3817 : }
3818 :
3819 0 : quirks = edid_get_quirks(edid);
3820 :
3821 : /*
3822 : * EDID spec says modes should be preferred in this order:
3823 : * - preferred detailed mode
3824 : * - other detailed modes from base block
3825 : * - detailed modes from extension blocks
3826 : * - CVT 3-byte code modes
3827 : * - standard timing codes
3828 : * - established timing codes
3829 : * - modes inferred from GTF or CVT range information
3830 : *
3831 : * We get this pretty much right.
3832 : *
3833 : * XXX order for additional mode types in extension blocks?
3834 : */
3835 0 : num_modes += add_detailed_modes(connector, edid, quirks);
3836 0 : num_modes += add_cvt_modes(connector, edid);
3837 0 : num_modes += add_standard_modes(connector, edid);
3838 0 : num_modes += add_established_modes(connector, edid);
3839 0 : num_modes += add_cea_modes(connector, edid);
3840 0 : num_modes += add_alternate_cea_modes(connector, edid);
3841 0 : if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
3842 0 : num_modes += add_inferred_modes(connector, edid);
3843 :
3844 0 : if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
3845 0 : edid_fixup_preferred(connector, quirks);
3846 :
3847 0 : drm_add_display_info(edid, &connector->display_info, connector);
3848 :
3849 0 : if (quirks & EDID_QUIRK_FORCE_6BPC)
3850 0 : connector->display_info.bpc = 6;
3851 :
3852 0 : if (quirks & EDID_QUIRK_FORCE_8BPC)
3853 0 : connector->display_info.bpc = 8;
3854 :
3855 0 : if (quirks & EDID_QUIRK_FORCE_10BPC)
3856 0 : connector->display_info.bpc = 10;
3857 :
3858 0 : if (quirks & EDID_QUIRK_FORCE_12BPC)
3859 0 : connector->display_info.bpc = 12;
3860 :
3861 0 : return num_modes;
3862 0 : }
3863 : EXPORT_SYMBOL(drm_add_edid_modes);
3864 :
3865 : /**
3866 : * drm_add_modes_noedid - add modes for the connectors without EDID
3867 : * @connector: connector we're probing
3868 : * @hdisplay: the horizontal display limit
3869 : * @vdisplay: the vertical display limit
3870 : *
3871 : * Add the specified modes to the connector's mode list. Only when the
3872 : * hdisplay/vdisplay is not beyond the given limit, it will be added.
3873 : *
3874 : * Return: The number of modes added or 0 if we couldn't find any.
3875 : */
3876 0 : int drm_add_modes_noedid(struct drm_connector *connector,
3877 : int hdisplay, int vdisplay)
3878 : {
3879 : int i, count, num_modes = 0;
3880 : struct drm_display_mode *mode;
3881 0 : struct drm_device *dev = connector->dev;
3882 :
3883 : count = ARRAY_SIZE(drm_dmt_modes);
3884 0 : if (hdisplay < 0)
3885 0 : hdisplay = 0;
3886 0 : if (vdisplay < 0)
3887 0 : vdisplay = 0;
3888 :
3889 0 : for (i = 0; i < count; i++) {
3890 0 : const struct drm_display_mode *ptr = &drm_dmt_modes[i];
3891 0 : if (hdisplay && vdisplay) {
3892 : /*
3893 : * Only when two are valid, they will be used to check
3894 : * whether the mode should be added to the mode list of
3895 : * the connector.
3896 : */
3897 0 : if (ptr->hdisplay > hdisplay ||
3898 0 : ptr->vdisplay > vdisplay)
3899 0 : continue;
3900 : }
3901 0 : if (drm_mode_vrefresh(ptr) > 61)
3902 0 : continue;
3903 0 : mode = drm_mode_duplicate(dev, ptr);
3904 0 : if (mode) {
3905 0 : drm_mode_probed_add(connector, mode);
3906 0 : num_modes++;
3907 0 : }
3908 0 : }
3909 0 : return num_modes;
3910 : }
3911 : EXPORT_SYMBOL(drm_add_modes_noedid);
3912 :
3913 : /**
3914 : * drm_set_preferred_mode - Sets the preferred mode of a connector
3915 : * @connector: connector whose mode list should be processed
3916 : * @hpref: horizontal resolution of preferred mode
3917 : * @vpref: vertical resolution of preferred mode
3918 : *
3919 : * Marks a mode as preferred if it matches the resolution specified by @hpref
3920 : * and @vpref.
3921 : */
3922 0 : void drm_set_preferred_mode(struct drm_connector *connector,
3923 : int hpref, int vpref)
3924 : {
3925 : struct drm_display_mode *mode;
3926 :
3927 0 : list_for_each_entry(mode, &connector->probed_modes, head) {
3928 0 : if (mode->hdisplay == hpref &&
3929 0 : mode->vdisplay == vpref)
3930 0 : mode->type |= DRM_MODE_TYPE_PREFERRED;
3931 : }
3932 0 : }
3933 : EXPORT_SYMBOL(drm_set_preferred_mode);
3934 :
3935 : /**
3936 : * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
3937 : * data from a DRM display mode
3938 : * @frame: HDMI AVI infoframe
3939 : * @mode: DRM display mode
3940 : *
3941 : * Return: 0 on success or a negative error code on failure.
3942 : */
3943 : int
3944 0 : drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
3945 : const struct drm_display_mode *mode)
3946 : {
3947 : int err;
3948 :
3949 0 : if (!frame || !mode)
3950 0 : return -EINVAL;
3951 :
3952 0 : err = hdmi_avi_infoframe_init(frame);
3953 0 : if (err < 0)
3954 0 : return err;
3955 :
3956 0 : if (mode->flags & DRM_MODE_FLAG_DBLCLK)
3957 0 : frame->pixel_repeat = 1;
3958 :
3959 0 : frame->video_code = drm_match_cea_mode(mode);
3960 :
3961 0 : frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
3962 :
3963 : /*
3964 : * Populate picture aspect ratio from either
3965 : * user input (if specified) or from the CEA mode list.
3966 : */
3967 0 : if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 ||
3968 0 : mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9)
3969 0 : frame->picture_aspect = mode->picture_aspect_ratio;
3970 0 : else if (frame->video_code > 0)
3971 0 : frame->picture_aspect = drm_get_cea_aspect_ratio(
3972 : frame->video_code);
3973 :
3974 0 : frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
3975 0 : frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
3976 :
3977 0 : return 0;
3978 0 : }
3979 : EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
3980 :
3981 : static enum hdmi_3d_structure
3982 0 : s3d_structure_from_display_mode(const struct drm_display_mode *mode)
3983 : {
3984 0 : u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK;
3985 :
3986 0 : switch (layout) {
3987 : case DRM_MODE_FLAG_3D_FRAME_PACKING:
3988 0 : return HDMI_3D_STRUCTURE_FRAME_PACKING;
3989 : case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
3990 0 : return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE;
3991 : case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
3992 0 : return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE;
3993 : case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
3994 0 : return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL;
3995 : case DRM_MODE_FLAG_3D_L_DEPTH:
3996 0 : return HDMI_3D_STRUCTURE_L_DEPTH;
3997 : case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
3998 0 : return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH;
3999 : case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
4000 0 : return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM;
4001 : case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
4002 0 : return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF;
4003 : default:
4004 0 : return HDMI_3D_STRUCTURE_INVALID;
4005 : }
4006 0 : }
4007 :
4008 : /**
4009 : * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with
4010 : * data from a DRM display mode
4011 : * @frame: HDMI vendor infoframe
4012 : * @mode: DRM display mode
4013 : *
4014 : * Note that there's is a need to send HDMI vendor infoframes only when using a
4015 : * 4k or stereoscopic 3D mode. So when giving any other mode as input this
4016 : * function will return -EINVAL, error that can be safely ignored.
4017 : *
4018 : * Return: 0 on success or a negative error code on failure.
4019 : */
4020 : int
4021 0 : drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
4022 : const struct drm_display_mode *mode)
4023 : {
4024 : int err;
4025 : u32 s3d_flags;
4026 : u8 vic;
4027 :
4028 0 : if (!frame || !mode)
4029 0 : return -EINVAL;
4030 :
4031 0 : vic = drm_match_hdmi_mode(mode);
4032 0 : s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK;
4033 :
4034 0 : if (!vic && !s3d_flags)
4035 0 : return -EINVAL;
4036 :
4037 0 : if (vic && s3d_flags)
4038 0 : return -EINVAL;
4039 :
4040 0 : err = hdmi_vendor_infoframe_init(frame);
4041 0 : if (err < 0)
4042 0 : return err;
4043 :
4044 0 : if (vic)
4045 0 : frame->vic = vic;
4046 : else
4047 0 : frame->s3d_struct = s3d_structure_from_display_mode(mode);
4048 :
4049 0 : return 0;
4050 0 : }
4051 : EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
4052 :
4053 0 : static int drm_parse_display_id(struct drm_connector *connector,
4054 : u8 *displayid, int length,
4055 : bool is_edid_extension)
4056 : {
4057 : /* if this is an EDID extension the first byte will be 0x70 */
4058 : int idx = 0;
4059 : struct displayid_hdr *base;
4060 : struct displayid_block *block;
4061 : u8 csum = 0;
4062 : int i;
4063 :
4064 0 : if (is_edid_extension)
4065 0 : idx = 1;
4066 :
4067 0 : base = (struct displayid_hdr *)&displayid[idx];
4068 :
4069 : DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
4070 : base->rev, base->bytes, base->prod_id, base->ext_count);
4071 :
4072 0 : if (base->bytes + 5 > length - idx)
4073 0 : return -EINVAL;
4074 :
4075 0 : for (i = idx; i <= base->bytes + 5; i++) {
4076 0 : csum += displayid[i];
4077 : }
4078 0 : if (csum) {
4079 0 : DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum);
4080 0 : return -EINVAL;
4081 : }
4082 :
4083 0 : block = (struct displayid_block *)&displayid[idx + 4];
4084 : DRM_DEBUG_KMS("block id %d, rev %d, len %d\n",
4085 : block->tag, block->rev, block->num_bytes);
4086 :
4087 0 : switch (block->tag) {
4088 : case DATA_BLOCK_TILED_DISPLAY: {
4089 0 : struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
4090 :
4091 : u16 w, h;
4092 : u8 tile_v_loc, tile_h_loc;
4093 : u8 num_v_tile, num_h_tile;
4094 : struct drm_tile_group *tg;
4095 :
4096 0 : w = tile->tile_size[0] | tile->tile_size[1] << 8;
4097 0 : h = tile->tile_size[2] | tile->tile_size[3] << 8;
4098 :
4099 0 : num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
4100 0 : num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
4101 0 : tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
4102 0 : tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
4103 :
4104 0 : connector->has_tile = true;
4105 0 : if (tile->tile_cap & 0x80)
4106 0 : connector->tile_is_single_monitor = true;
4107 :
4108 0 : connector->num_h_tile = num_h_tile + 1;
4109 0 : connector->num_v_tile = num_v_tile + 1;
4110 0 : connector->tile_h_loc = tile_h_loc;
4111 0 : connector->tile_v_loc = tile_v_loc;
4112 0 : connector->tile_h_size = w + 1;
4113 0 : connector->tile_v_size = h + 1;
4114 :
4115 : DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
4116 : DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
4117 : DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
4118 : num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
4119 : DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
4120 :
4121 0 : tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
4122 0 : if (!tg) {
4123 0 : tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
4124 0 : }
4125 0 : if (!tg)
4126 0 : return -ENOMEM;
4127 :
4128 0 : if (connector->tile_group != tg) {
4129 : /* if we haven't got a pointer,
4130 : take the reference, drop ref to old tile group */
4131 0 : if (connector->tile_group) {
4132 0 : drm_mode_put_tile_group(connector->dev, connector->tile_group);
4133 0 : }
4134 0 : connector->tile_group = tg;
4135 0 : } else
4136 : /* if same tile group, then release the ref we just took. */
4137 0 : drm_mode_put_tile_group(connector->dev, tg);
4138 0 : }
4139 : break;
4140 : default:
4141 0 : printk("unknown displayid tag %d\n", block->tag);
4142 0 : break;
4143 : }
4144 0 : return 0;
4145 0 : }
4146 :
4147 0 : static void drm_get_displayid(struct drm_connector *connector,
4148 : struct edid *edid)
4149 : {
4150 : void *displayid = NULL;
4151 : int ret;
4152 0 : connector->has_tile = false;
4153 0 : displayid = drm_find_displayid_extension(edid);
4154 0 : if (!displayid) {
4155 : /* drop reference to any tile group we had */
4156 : goto out_drop_ref;
4157 : }
4158 :
4159 0 : ret = drm_parse_display_id(connector, displayid, EDID_LENGTH, true);
4160 0 : if (ret < 0)
4161 : goto out_drop_ref;
4162 0 : if (!connector->has_tile)
4163 : goto out_drop_ref;
4164 0 : return;
4165 : out_drop_ref:
4166 0 : if (connector->tile_group) {
4167 0 : drm_mode_put_tile_group(connector->dev, connector->tile_group);
4168 0 : connector->tile_group = NULL;
4169 0 : }
4170 0 : return;
4171 0 : }
|