xref: /gfx-drm/usr/src/uts/common/io/drm/drm_edid.c (revision 34389f68)
1 /*
2  * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 /*
6  * Copyright (c) 2006 Luc Verhaegen (quirks list)
7  * Copyright (c) 2007-2008, 2013, Intel Corporation
8  *   Jesse Barnes <jesse.barnes@intel.com>
9  *
10  * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
11  * FB layer.
12  *   Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a
15  * copy of this software and associated documentation files (the "Software"),
16  * to deal in the Software without restriction, including without limitation
17  * the rights to use, copy, modify, merge, publish, distribute, sub license,
18  * and/or sell copies of the Software, and to permit persons to whom the
19  * Software is furnished to do so, subject to the following conditions:
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
28  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31  * DEALINGS IN THE SOFTWARE.
32  */
33 #include "drm.h"
34 #include "drmP.h"
35 #include "drm_edid.h"
36 #include "drm_sun_i2c.h"
37 #include "drm_crtc.h"
38 
39 #define version_greater(edid, maj, min) \
40 	(((edid)->version > (maj)) || \
41 	 ((edid)->version == (maj) && (edid)->revision > (min)))
42 
43 #define EDID_EST_TIMINGS 16
44 #define EDID_STD_TIMINGS 8
45 #define EDID_DETAILED_TIMINGS 4
46 
47 /*
48  * EDID blocks out in the wild have a variety of bugs, try to collect
49  * them here (note that userspace may work around broken monitors first,
50  * but fixes should make their way here so that the kernel "just works"
51  * on as many displays as possible).
52  */
53 
54 /* First detailed mode wrong, use largest 60Hz mode */
55 #define EDID_QUIRK_PREFER_LARGE_60		(1 << 0)
56 /* Reported 135MHz pixel clock is too high, needs adjustment */
57 #define EDID_QUIRK_135_CLOCK_TOO_HIGH		(1 << 1)
58 /* Prefer the largest mode at 75 Hz */
59 #define EDID_QUIRK_PREFER_LARGE_75		(1 << 2)
60 /* Detail timing is in cm not mm */
61 #define EDID_QUIRK_DETAILED_IN_CM		(1 << 3)
62 /* Detailed timing descriptors have bogus size values, so just take the
63  * maximum size and use that.
64  */
65 #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE	(1 << 4)
66 /* Monitor forgot to set the first detailed is preferred bit. */
67 #define EDID_QUIRK_FIRST_DETAILED_PREFERRED	(1 << 5)
68 /* use +hsync +vsync for detailed mode */
69 #define EDID_QUIRK_DETAILED_SYNC_PP		(1 << 6)
70 /* Force reduced-blanking timings for detailed modes */
71 #define EDID_QUIRK_FORCE_REDUCED_BLANKING	(1 << 7)
72 
73 struct detailed_mode_closure {
74 	struct drm_connector *connector;
75 	struct edid *edid;
76 	bool preferred;
77 	u32 quirks;
78 	int modes;
79 };
80 
81 #define LEVEL_DMT	0
82 #define LEVEL_GTF	1
83 #define LEVEL_GTF2	2
84 #define LEVEL_CVT	3
85 
86 static struct edid_quirk {
87 	char vendor[4];
88 	int product_id;
89 	u32 quirks;
90 } edid_quirk_list[] = {
91 	/* Acer AL1706 */
92 	{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
93 	/* Acer F51 */
94 	{ "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
95 	/* Unknown Acer */
96 	{ "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
97 
98 	/* Belinea 10 15 55 */
99 	{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
100 	{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
101 
102 	/* Envision Peripherals, Inc. EN-7100e */
103 	{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
104 	/* Envision EN2028 */
105 	{ "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
106 
107 	/* Funai Electronics PM36B */
108 	{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
109 	  EDID_QUIRK_DETAILED_IN_CM },
110 
111 	/* LG Philips LCD LP154W01-A5 */
112 	{ "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
113 	{ "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
114 
115 	/* Philips 107p5 CRT */
116 	{ "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
117 
118 	/* Proview AY765C */
119 	{ "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
120 
121 	/* Samsung SyncMaster 205BW.  Note: irony */
122 	{ "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
123 	/* Samsung SyncMaster 22[5-6]BW */
124 	{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
125 	{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
126 
127 	/* ViewSonic VA2026w */
128 	{ "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
129 };
130 
131 /*
132  * Autogenerated from the DMT spec.
133  * This table is copied from xfree86/modes/xf86EdidModes.c.
134  */
135 static const struct drm_display_mode drm_dmt_modes[] = {
136 	/* 640x350@85Hz */
137 	{ DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
138 		   736, 832, 0, 350, 382, 385, 445, 0,
139 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
140 	/* 640x400@85Hz */
141 	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
142 		   736, 832, 0, 400, 401, 404, 445, 0,
143 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
144 	/* 720x400@85Hz */
145 	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
146 		   828, 936, 0, 400, 401, 404, 446, 0,
147 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
148 	/* 640x480@60Hz */
149 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
150 		   752, 800, 0, 480, 489, 492, 525, 0,
151 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
152 	/* 640x480@72Hz */
153 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
154 		   704, 832, 0, 480, 489, 492, 520, 0,
155 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
156 	/* 640x480@75Hz */
157 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
158 		   720, 840, 0, 480, 481, 484, 500, 0,
159 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
160 	/* 640x480@85Hz */
161 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
162 		   752, 832, 0, 480, 481, 484, 509, 0,
163 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
164 	/* 800x600@56Hz */
165 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
166 		   896, 1024, 0, 600, 601, 603, 625, 0,
167 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
168 	/* 800x600@60Hz */
169 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
170 		   968, 1056, 0, 600, 601, 605, 628, 0,
171 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
172 	/* 800x600@72Hz */
173 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
174 		   976, 1040, 0, 600, 637, 643, 666, 0,
175 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
176 	/* 800x600@75Hz */
177 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
178 		   896, 1056, 0, 600, 601, 604, 625, 0,
179 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
180 	/* 800x600@85Hz */
181 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
182 		   896, 1048, 0, 600, 601, 604, 631, 0,
183 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
184 	/* 800x600@120Hz RB */
185 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
186 		   880, 960, 0, 600, 603, 607, 636, 0,
187 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
188 	/* 848x480@60Hz */
189 	{ DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
190 		   976, 1088, 0, 480, 486, 494, 517, 0,
191 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
192 	/* 1024x768@43Hz, interlace */
193 	{ DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
194 		   1208, 1264, 0, 768, 768, 772, 817, 0,
195 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
196 			DRM_MODE_FLAG_INTERLACE) },
197 	/* 1024x768@60Hz */
198 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
199 		   1184, 1344, 0, 768, 771, 777, 806, 0,
200 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
201 	/* 1024x768@70Hz */
202 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
203 		   1184, 1328, 0, 768, 771, 777, 806, 0,
204 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
205 	/* 1024x768@75Hz */
206 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
207 		   1136, 1312, 0, 768, 769, 772, 800, 0,
208 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
209 	/* 1024x768@85Hz */
210 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
211 		   1168, 1376, 0, 768, 769, 772, 808, 0,
212 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
213 	/* 1024x768@120Hz RB */
214 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
215 		   1104, 1184, 0, 768, 771, 775, 813, 0,
216 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
217 	/* 1152x864@75Hz */
218 	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
219 		   1344, 1600, 0, 864, 865, 868, 900, 0,
220 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
221 	/* 1280x768@60Hz RB */
222 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
223 		   1360, 1440, 0, 768, 771, 778, 790, 0,
224 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
225 	/* 1280x768@60Hz */
226 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
227 		   1472, 1664, 0, 768, 771, 778, 798, 0,
228 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
229 	/* 1280x768@75Hz */
230 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
231 		   1488, 1696, 0, 768, 771, 778, 805, 0,
232 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
233 	/* 1280x768@85Hz */
234 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
235 		   1496, 1712, 0, 768, 771, 778, 809, 0,
236 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
237 	/* 1280x768@120Hz RB */
238 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
239 		   1360, 1440, 0, 768, 771, 778, 813, 0,
240 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
241 	/* 1280x800@60Hz RB */
242 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
243 		   1360, 1440, 0, 800, 803, 809, 823, 0,
244 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
245 	/* 1280x800@60Hz */
246 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
247 		   1480, 1680, 0, 800, 803, 809, 831, 0,
248 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
249 	/* 1280x800@75Hz */
250 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
251 		   1488, 1696, 0, 800, 803, 809, 838, 0,
252 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
253 	/* 1280x800@85Hz */
254 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
255 		   1496, 1712, 0, 800, 803, 809, 843, 0,
256 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
257 	/* 1280x800@120Hz RB */
258 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
259 		   1360, 1440, 0, 800, 803, 809, 847, 0,
260 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
261 	/* 1280x960@60Hz */
262 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
263 		   1488, 1800, 0, 960, 961, 964, 1000, 0,
264 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
265 	/* 1280x960@85Hz */
266 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
267 		   1504, 1728, 0, 960, 961, 964, 1011, 0,
268 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
269 	/* 1280x960@120Hz RB */
270 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
271 		   1360, 1440, 0, 960, 963, 967, 1017, 0,
272 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
273 	/* 1280x1024@60Hz */
274 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
275 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
276 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
277 	/* 1280x1024@75Hz */
278 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
279 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
280 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
281 	/* 1280x1024@85Hz */
282 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
283 		   1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
284 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
285 	/* 1280x1024@120Hz RB */
286 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
287 		   1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
288 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
289 	/* 1360x768@60Hz */
290 	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
291 		   1536, 1792, 0, 768, 771, 777, 795, 0,
292 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
293 	/* 1360x768@120Hz RB */
294 	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
295 		   1440, 1520, 0, 768, 771, 776, 813, 0,
296 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
297 	/* 1400x1050@60Hz RB */
298 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
299 		   1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
300 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
301 	/* 1400x1050@60Hz */
302 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
303 		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
304 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
305 	/* 1400x1050@75Hz */
306 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
307 		   1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
308 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
309 	/* 1400x1050@85Hz */
310 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
311 		   1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
312 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
313 	/* 1400x1050@120Hz RB */
314 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
315 		   1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
316 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
317 	/* 1440x900@60Hz RB */
318 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
319 		   1520, 1600, 0, 900, 903, 909, 926, 0,
320 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
321 	/* 1440x900@60Hz */
322 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
323 		   1672, 1904, 0, 900, 903, 909, 934, 0,
324 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
325 	/* 1440x900@75Hz */
326 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
327 		   1688, 1936, 0, 900, 903, 909, 942, 0,
328 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
329 	/* 1440x900@85Hz */
330 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
331 		   1696, 1952, 0, 900, 903, 909, 948, 0,
332 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
333 	/* 1440x900@120Hz RB */
334 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
335 		   1520, 1600, 0, 900, 903, 909, 953, 0,
336 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
337 	/* 1600x1200@60Hz */
338 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
339 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
340 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
341 	/* 1600x1200@65Hz */
342 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
343 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
344 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
345 	/* 1600x1200@70Hz */
346 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
347 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
348 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
349 	/* 1600x1200@75Hz */
350 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
351 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
352 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
353 	/* 1600x1200@85Hz */
354 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
355 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
356 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
357 	/* 1600x1200@120Hz RB */
358 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
359 		   1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
360 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
361 	/* 1680x1050@60Hz RB */
362 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
363 		   1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
364 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
365 	/* 1680x1050@60Hz */
366 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
367 		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
368 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
369 	/* 1680x1050@75Hz */
370 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
371 		   1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
372 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
373 	/* 1680x1050@85Hz */
374 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
375 		   1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
376 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
377 	/* 1680x1050@120Hz RB */
378 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
379 		   1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
380 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
381 	/* 1792x1344@60Hz */
382 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
383 		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
384 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
385 	/* 1792x1344@75Hz */
386 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
387 		   2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
388 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
389 	/* 1792x1344@120Hz RB */
390 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
391 		   1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
392 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
393 	/* 1856x1392@60Hz */
394 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
395 		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
396 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
397 	/* 1856x1392@75Hz */
398 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
399 		   2208, 2560, 0, 1392, 1395, 1399, 1500, 0,
400 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
401 	/* 1856x1392@120Hz RB */
402 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
403 		   1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
404 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
405 	/* 1920x1200@60Hz RB */
406 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
407 		   2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
408 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
409 	/* 1920x1200@60Hz */
410 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
411 		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
412 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
413 	/* 1920x1200@75Hz */
414 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
415 		   2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
416 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
417 	/* 1920x1200@85Hz */
418 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
419 		   2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
420 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
421 	/* 1920x1200@120Hz RB */
422 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
423 		   2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
424 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
425 	/* 1920x1440@60Hz */
426 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
427 		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
428 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
429 	/* 1920x1440@75Hz */
430 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
431 		   2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
432 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
433 	/* 1920x1440@120Hz RB */
434 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
435 		   2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
436 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
437 	/* 2560x1600@60Hz RB */
438 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
439 		   2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
440 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
441 	/* 2560x1600@60Hz */
442 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
443 		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
444 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
445 	/* 2560x1600@75HZ */
446 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
447 		   3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
448 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
449 	/* 2560x1600@85HZ */
450 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
451 		   3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
452 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
453 	/* 2560x1600@120Hz RB */
454 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
455 		   2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
456 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
457 };
458 
459 static const struct drm_display_mode edid_est_modes[] = {
460 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
461 		   968, 1056, 0, 600, 601, 605, 628, 0,
462 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
463 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
464 		   896, 1024, 0, 600, 601, 603,  625, 0,
465 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
466 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
467 		   720, 840, 0, 480, 481, 484, 500, 0,
468 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
469 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
470 		   704,  832, 0, 480, 489, 491, 520, 0,
471 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
472 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
473 		   768,  864, 0, 480, 483, 486, 525, 0,
474 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
475 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
476 		   752, 800, 0, 480, 490, 492, 525, 0,
477 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
478 	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
479 		   846, 900, 0, 400, 421, 423,  449, 0,
480 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
481 	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
482 		   846,  900, 0, 400, 412, 414, 449, 0,
483 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
484 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
485 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
486 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
487 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
488 		   1136, 1312, 0,  768, 769, 772, 800, 0,
489 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
490 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
491 		   1184, 1328, 0,  768, 771, 777, 806, 0,
492 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
493 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
494 		   1184, 1344, 0,  768, 771, 777, 806, 0,
495 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
496 	{ DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
497 		   1208, 1264, 0, 768, 768, 776, 817, 0,
498 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
499 	{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
500 		   928, 1152, 0, 624, 625, 628, 667, 0,
501 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
502 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
503 		   896, 1056, 0, 600, 601, 604,  625, 0,
504 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
505 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
506 		   976, 1040, 0, 600, 637, 643, 666, 0,
507 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
508 	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
509 		   1344, 1600, 0,  864, 865, 868, 900, 0,
510 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
511 };
512 
513 struct minimode {
514 	short w;
515 	short h;
516 	short r;
517 	short rb;
518 };
519 
520 static const struct minimode est3_modes[] = {
521 	/* byte 6 */
522 	{ 640, 350, 85, 0 },
523 	{ 640, 400, 85, 0 },
524 	{ 720, 400, 85, 0 },
525 	{ 640, 480, 85, 0 },
526 	{ 848, 480, 60, 0 },
527 	{ 800, 600, 85, 0 },
528 	{ 1024, 768, 85, 0 },
529 	{ 1152, 864, 75, 0 },
530 	/* byte 7 */
531 	{ 1280, 768, 60, 1 },
532 	{ 1280, 768, 60, 0 },
533 	{ 1280, 768, 75, 0 },
534 	{ 1280, 768, 85, 0 },
535 	{ 1280, 960, 60, 0 },
536 	{ 1280, 960, 85, 0 },
537 	{ 1280, 1024, 60, 0 },
538 	{ 1280, 1024, 85, 0 },
539 	/* byte 8 */
540 	{ 1360, 768, 60, 0 },
541 	{ 1440, 900, 60, 1 },
542 	{ 1440, 900, 60, 0 },
543 	{ 1440, 900, 75, 0 },
544 	{ 1440, 900, 85, 0 },
545 	{ 1400, 1050, 60, 1 },
546 	{ 1400, 1050, 60, 0 },
547 	{ 1400, 1050, 75, 0 },
548 	/* byte 9 */
549 	{ 1400, 1050, 85, 0 },
550 	{ 1680, 1050, 60, 1 },
551 	{ 1680, 1050, 60, 0 },
552 	{ 1680, 1050, 75, 0 },
553 	{ 1680, 1050, 85, 0 },
554 	{ 1600, 1200, 60, 0 },
555 	{ 1600, 1200, 65, 0 },
556 	{ 1600, 1200, 70, 0 },
557 	/* byte 10 */
558 	{ 1600, 1200, 75, 0 },
559 	{ 1600, 1200, 85, 0 },
560 	{ 1792, 1344, 60, 0 },
561 	{ 1792, 1344, 85, 0 },
562 	{ 1856, 1392, 60, 0 },
563 	{ 1856, 1392, 75, 0 },
564 	{ 1920, 1200, 60, 1 },
565 	{ 1920, 1200, 60, 0 },
566 	/* byte 11 */
567 	{ 1920, 1200, 75, 0 },
568 	{ 1920, 1200, 85, 0 },
569 	{ 1920, 1440, 60, 0 },
570 	{ 1920, 1440, 75, 0 },
571 };
572 
573 static const struct minimode extra_modes[] = {
574 	{ 1024, 576,  60, 0 },
575 	{ 1366, 768,  60, 0 },
576 	{ 1600, 900,  60, 0 },
577 	{ 1680, 945,  60, 0 },
578 	{ 1920, 1080, 60, 0 },
579 	{ 2048, 1152, 60, 0 },
580 	{ 2048, 1536, 60, 0 },
581 };
582 
583 /*
584  * Probably taken from CEA-861 spec.
585  * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.
586  */
587 static const struct drm_display_mode edid_cea_modes[] = {
588 	/* 1 - 640x480@60Hz */
589 	{ .vrefresh = 60, DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
590 		   752, 800, 0, 480, 490, 492, 525, 0,
591 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
592 	/* 2 - 720x480@60Hz */
593 	{ .vrefresh = 60, DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
594 		   798, 858, 0, 480, 489, 495, 525, 0,
595 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
596 	/* 3 - 720x480@60Hz */
597 	{ .vrefresh = 60, DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
598 		   798, 858, 0, 480, 489, 495, 525, 0,
599 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
600 	/* 4 - 1280x720@60Hz */
601 	{ .vrefresh = 60, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
602 		   1430, 1650, 0, 720, 725, 730, 750, 0,
603 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
604 	/* 5 - 1920x1080i@60Hz */
605 	{ .vrefresh = 60, DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
606 		   2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
607 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
608 			DRM_MODE_FLAG_INTERLACE)},
609 	/* 6 - 1440x480i@60Hz */
610 	{ .vrefresh = 60, DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
611 		   1602, 1716, 0, 480, 488, 494, 525, 0,
612 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
613 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
614 	/* 7 - 1440x480i@60Hz */
615 	{ .vrefresh = 60, DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
616 		   1602, 1716, 0, 480, 488, 494, 525, 0,
617 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
618 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
619 	/* 8 - 1440x240@60Hz */
620 	{ .vrefresh = 60, DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
621 		   1602, 1716, 0, 240, 244, 247, 262, 0,
622 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
623 			DRM_MODE_FLAG_DBLCLK)},
624 	/* 9 - 1440x240@60Hz */
625 	{ .vrefresh = 60, DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
626 		   1602, 1716, 0, 240, 244, 247, 262, 0,
627 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
628 			DRM_MODE_FLAG_DBLCLK)},
629 	/* 10 - 2880x480i@60Hz */
630 	{ .vrefresh = 60, DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
631 		   3204, 3432, 0, 480, 488, 494, 525, 0,
632 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
633 			DRM_MODE_FLAG_INTERLACE)},
634 	/* 11 - 2880x480i@60Hz */
635 	{ .vrefresh = 60, DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
636 		   3204, 3432, 0, 480, 488, 494, 525, 0,
637 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
638 			DRM_MODE_FLAG_INTERLACE)},
639 	/* 12 - 2880x240@60Hz */
640 	{ .vrefresh = 60, DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
641 		   3204, 3432, 0, 240, 244, 247, 262, 0,
642 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
643 	/* 13 - 2880x240@60Hz */
644 	{ .vrefresh = 60, DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
645 		   3204, 3432, 0, 240, 244, 247, 262, 0,
646 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
647 	/* 14 - 1440x480@60Hz */
648 	{ .vrefresh = 60, DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
649 		   1596, 1716, 0, 480, 489, 495, 525, 0,
650 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
651 	/* 15 - 1440x480@60Hz */
652 	{ .vrefresh = 60, DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
653 		   1596, 1716, 0, 480, 489, 495, 525, 0,
654 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
655 	/* 16 - 1920x1080@60Hz */
656 	{ .vrefresh = 60, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
657 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
658 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
659 	/* 17 - 720x576@50Hz */
660 	{ .vrefresh = 50, DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
661 		   796, 864, 0, 576, 581, 586, 625, 0,
662 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
663 	/* 18 - 720x576@50Hz */
664 	{ .vrefresh = 50, DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
665 		   796, 864, 0, 576, 581, 586, 625, 0,
666 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
667 	/* 19 - 1280x720@50Hz */
668 	{ .vrefresh = 50, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
669 		   1760, 1980, 0, 720, 725, 730, 750, 0,
670 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
671 	/* 20 - 1920x1080i@50Hz */
672 	{ .vrefresh = 50, DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
673 		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
674 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
675 			DRM_MODE_FLAG_INTERLACE)},
676 	/* 21 - 1440x576i@50Hz */
677 	{ .vrefresh = 50, DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
678 		   1590, 1728, 0, 576, 580, 586, 625, 0,
679 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
680 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
681 	/* 22 - 1440x576i@50Hz */
682 	{ .vrefresh = 50, DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
683 		   1590, 1728, 0, 576, 580, 586, 625, 0,
684 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
685 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
686 	/* 23 - 1440x288@50Hz */
687 	{ .vrefresh = 50, DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
688 		   1590, 1728, 0, 288, 290, 293, 312, 0,
689 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
690 			DRM_MODE_FLAG_DBLCLK)},
691 	/* 24 - 1440x288@50Hz */
692 	{ .vrefresh = 50, DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
693 		   1590, 1728, 0, 288, 290, 293, 312, 0,
694 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
695 			DRM_MODE_FLAG_DBLCLK)},
696 	/* 25 - 2880x576i@50Hz */
697 	{ .vrefresh = 50, DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
698 		   3180, 3456, 0, 576, 580, 586, 625, 0,
699 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
700 			DRM_MODE_FLAG_INTERLACE)},
701 	/* 26 - 2880x576i@50Hz */
702 	{ .vrefresh = 50, DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
703 		   3180, 3456, 0, 576, 580, 586, 625, 0,
704 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
705 			DRM_MODE_FLAG_INTERLACE)},
706 	/* 27 - 2880x288@50Hz */
707 	{ .vrefresh = 50, DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
708 		   3180, 3456, 0, 288, 290, 293, 312, 0,
709 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
710 	/* 28 - 2880x288@50Hz */
711 	{ .vrefresh = 50, DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
712 		   3180, 3456, 0, 288, 290, 293, 312, 0,
713 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
714 	/* 29 - 1440x576@50Hz */
715 	{ .vrefresh = 50, DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
716 		   1592, 1728, 0, 576, 581, 586, 625, 0,
717 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
718 	/* 30 - 1440x576@50Hz */
719 	{ .vrefresh = 50, DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
720 		   1592, 1728, 0, 576, 581, 586, 625, 0,
721 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
722 	/* 31 - 1920x1080@50Hz */
723 	{ .vrefresh = 50, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
724 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
725 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
726 	/* 32 - 1920x1080@24Hz */
727 	{ .vrefresh = 50, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
728 		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
729 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
730 	/* 33 - 1920x1080@25Hz */
731 	{ .vrefresh = 25, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
732 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
733 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
734 	/* 34 - 1920x1080@30Hz */
735 	{ .vrefresh = 30, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
736 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
737 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
738 	/* 35 - 2880x480@60Hz */
739 	{ .vrefresh = 60, DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
740 		   3192, 3432, 0, 480, 489, 495, 525, 0,
741 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
742 	/* 36 - 2880x480@60Hz */
743 	{ .vrefresh = 60, DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
744 		   3192, 3432, 0, 480, 489, 495, 525, 0,
745 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
746 	/* 37 - 2880x576@50Hz */
747 	{ .vrefresh = 50, DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
748 		   3184, 3456, 0, 576, 581, 586, 625, 0,
749 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
750 	/* 38 - 2880x576@50Hz */
751 	{ .vrefresh = 50, DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
752 		   3184, 3456, 0, 576, 581, 586, 625, 0,
753 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
754 	/* 39 - 1920x1080i@50Hz */
755 	{ .vrefresh = 50, DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
756 		   2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
757 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
758 			DRM_MODE_FLAG_INTERLACE)},
759 	/* 40 - 1920x1080i@100Hz */
760 	{ .vrefresh = 100, DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
761 		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
762 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
763 			DRM_MODE_FLAG_INTERLACE)},
764 	/* 41 - 1280x720@100Hz */
765 	{ .vrefresh = 100, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
766 		   1760, 1980, 0, 720, 725, 730, 750, 0,
767 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
768 	/* 42 - 720x576@100Hz */
769 	{ .vrefresh = 100, DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
770 		   796, 864, 0, 576, 581, 586, 625, 0,
771 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
772 	/* 43 - 720x576@100Hz */
773 	{ .vrefresh = 100, DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
774 		   796, 864, 0, 576, 581, 586, 625, 0,
775 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
776 	/* 44 - 1440x576i@100Hz */
777 	{ .vrefresh = 100, DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
778 		   1590, 1728, 0, 576, 580, 586, 625, 0,
779 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
780 			DRM_MODE_FLAG_DBLCLK)},
781 	/* 45 - 1440x576i@100Hz */
782 	{ .vrefresh = 100, DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
783 		   1590, 1728, 0, 576, 580, 586, 625, 0,
784 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
785 			DRM_MODE_FLAG_DBLCLK)},
786 	/* 46 - 1920x1080i@120Hz */
787 	{ .vrefresh = 120, DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
788 		   2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
789 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
790 			DRM_MODE_FLAG_INTERLACE)},
791 	/* 47 - 1280x720@120Hz */
792 	{ .vrefresh = 120, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
793 		   1430, 1650, 0, 720, 725, 730, 750, 0,
794 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
795 	/* 48 - 720x480@120Hz */
796 	{ .vrefresh = 120, DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
797 		   798, 858, 0, 480, 489, 495, 525, 0,
798 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
799 	/* 49 - 720x480@120Hz */
800 	{ .vrefresh = 120, DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
801 		   798, 858, 0, 480, 489, 495, 525, 0,
802 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
803 	/* 50 - 1440x480i@120Hz */
804 	{ .vrefresh = 120, DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
805 		   1602, 1716, 0, 480, 488, 494, 525, 0,
806 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
807 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
808 	/* 51 - 1440x480i@120Hz */
809 	{ .vrefresh = 120, DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
810 		   1602, 1716, 0, 480, 488, 494, 525, 0,
811 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
812 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
813 	/* 52 - 720x576@200Hz */
814 	{ .vrefresh = 200, DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
815 		   796, 864, 0, 576, 581, 586, 625, 0,
816 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
817 	/* 53 - 720x576@200Hz */
818 	{ .vrefresh = 200, DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
819 		   796, 864, 0, 576, 581, 586, 625, 0,
820 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
821 	/* 54 - 1440x576i@200Hz */
822 	{ .vrefresh = 200, DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
823 		   1590, 1728, 0, 576, 580, 586, 625, 0,
824 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
825 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
826 	/* 55 - 1440x576i@200Hz */
827 	{ .vrefresh = 200, DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
828 		   1590, 1728, 0, 576, 580, 586, 625, 0,
829 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
830 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
831 	/* 56 - 720x480@240Hz */
832 	{ .vrefresh = 240, DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
833 		   798, 858, 0, 480, 489, 495, 525, 0,
834 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
835 	/* 57 - 720x480@240Hz */
836 	{ .vrefresh = 240, DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
837 		   798, 858, 0, 480, 489, 495, 525, 0,
838 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
839 	/* 58 - 1440x480i@240 */
840 	{ .vrefresh = 240, DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
841 		   1602, 1716, 0, 480, 488, 494, 525, 0,
842 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
843 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
844 	/* 59 - 1440x480i@240 */
845 	{ .vrefresh = 240, DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
846 		   1602, 1716, 0, 480, 488, 494, 525, 0,
847 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
848 			DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK)},
849 	/* 60 - 1280x720@24Hz */
850 	{ .vrefresh = 24, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
851 		   3080, 3300, 0, 720, 725, 730, 750, 0,
852 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
853 	/* 61 - 1280x720@25Hz */
854 	{ .vrefresh = 25, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
855 		   3740, 3960, 0, 720, 725, 730, 750, 0,
856 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
857 	/* 62 - 1280x720@30Hz */
858 	{ .vrefresh = 30, DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
859 		   3080, 3300, 0, 720, 725, 730, 750, 0,
860 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
861 	/* 63 - 1920x1080@120Hz */
862 	{ .vrefresh = 120, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
863 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
864 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
865 	/* 64 - 1920x1080@100Hz */
866 	{ .vrefresh = 100, DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
867 		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
868 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
869 };
870 
871 /*** DDC fetch and block validation ***/
872 
873 static const u8 edid_header[] = {
874 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
875 };
876 
877  /*
878  * Sanity check the header of the base EDID block.  Return 8 if the header
879  * is perfect, down to 0 if it's totally wrong.
880  */
drm_edid_header_is_valid(const u8 * raw_edid)881 int drm_edid_header_is_valid(const u8 *raw_edid)
882 {
883 	int i, score = 0;
884 
885 	for (i = 0; i < sizeof(edid_header); i++)
886 		if (raw_edid[i] == edid_header[i])
887 			score++;
888 
889 	return score;
890 }
891 
892 static int edid_fixup = 6;
893 /*
894  * Sanity check the EDID block (base or extension).  Return 0 if the block
895  * doesn't check out, or 1 if it's valid.
896  */
drm_edid_block_valid(u8 * raw_edid,int block,bool print_bad_edid)897 bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
898 {
899 	int i;
900 	u8 csum = 0;
901 	struct edid *edid = (struct edid *)raw_edid;
902 
903 	if (!raw_edid) {
904 		WARN_ON(1);
905 		return false;
906 	}
907 	if (edid_fixup > 8 || edid_fixup < 0)
908 		edid_fixup = 6;
909 
910 	if (block == 0) {
911 		int score = drm_edid_header_is_valid(raw_edid);
912 		if (score == 8)
913 			DRM_DEBUG("edid header is perfect");
914 		else if (score >= edid_fixup) {
915 			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
916 			(void) memcpy(raw_edid, edid_header, sizeof(edid_header));
917 		} else {
918 			goto bad;
919 		}
920 	}
921 
922 	for (i = 0; i < EDID_LENGTH; i++)
923 		csum += raw_edid[i];
924 	if (csum) {
925 		if (print_bad_edid) {
926 			DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
927 		}
928 
929 		/* allow CEA to slide through, switches mangle this */
930 		if (raw_edid[0] != 0x02)
931 			goto bad;
932 	}
933 
934 	/* per-block-type checks */
935 	switch (raw_edid[0]) {
936 	case 0: /* base */
937 		if (edid->version != 1) {
938 			DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
939 			goto bad;
940 		}
941 
942 		if (edid->revision > 4)
943 			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
944 		break;
945 
946 	default:
947 		break;
948 	}
949 
950 	return true;
951 
952 bad:
953 	if (print_bad_edid) {
954 		DRM_DEBUG_KMS("Raw EDID:\n");
955 //		print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
956 	}
957 	return false;
958 }
959 
960 /**
961  * drm_edid_is_valid - sanity check EDID data
962  * @edid: EDID data
963  *
964  * Sanity-check an entire EDID record (including extensions)
965  */
drm_edid_is_valid(struct edid * edid)966 bool drm_edid_is_valid(struct edid *edid)
967 {
968 	int i;
969 	u8 *raw = (u8 *)edid;
970 
971 	if (!edid)
972 		return false;
973 
974 	for (i = 0; i <= edid->extensions; i++)
975 		if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true))
976 			return false;
977 
978 	return true;
979 }
980 
981 #define DDC_SEGMENT_ADDR 0x30
982 /**
983  * Get EDID information via I2C.
984  *
985  * \param adapter : i2c device adaptor
986  * \param buf     : EDID data buffer to be filled
987  * \param len     : EDID data buffer length
988  * \return 0 on success or -1 on failure.
989  *
990  * Try to fetch EDID information by calling i2c driver function.
991  */
992 static int
drm_do_probe_ddc_edid(struct i2c_adapter * adapter,unsigned char * buf,int block,int len)993 drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
994 		      int block, int len)
995 {
996 	unsigned char start = block * EDID_LENGTH;
997 	unsigned char segment = block >> 1;
998 	unsigned char xfers = segment ? 3 : 2;
999 	int ret, retries = 5;
1000 
1001 	/* The core i2c driver will automatically retry the transfer if the
1002 	 * adapter reports EAGAIN. However, we find that bit-banging transfers
1003 	 * are susceptible to errors under a heavily loaded machine and
1004 	 * generate spurious NAKs and timeouts. Retrying the transfer
1005 	 * of the individual block a few times seems to overcome this.
1006 	 */
1007 	do {
1008 		struct i2c_msg msgs[] = {
1009 			{
1010 				.addr	= DDC_SEGMENT_ADDR,
1011 				.flags	= 0,
1012 				.len	= 1,
1013 				.buf	= &segment,
1014 			}, {
1015 				.addr	= DDC_ADDR,
1016 				.flags	= 0,
1017 				.len	= 1,
1018 				.buf	= &start,
1019 			}, {
1020 				.addr	= DDC_ADDR,
1021 				.flags	= I2C_M_RD,
1022 				.len	= (u16)len,
1023 				.buf	= buf,
1024 			}
1025 		};
1026 
1027 	/*
1028 	 * Avoid sending the segment addr to not upset non-compliant ddc
1029 	 * monitors.
1030 	 */
1031 		ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
1032 
1033 		if (ret == -ENXIO) {
1034 			DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
1035 					adapter->name);
1036 			break;
1037 		}
1038 	} while (ret != xfers && --retries);
1039 
1040 	return ret == xfers ? 0 : -1;
1041 }
1042 
drm_edid_is_zero(u8 * in_edid,int length)1043 static bool drm_edid_is_zero(u8 *in_edid, int length)
1044 {
1045 	int i;
1046 	u32 *raw_edid = (u32 *)(uintptr_t)(caddr_t)in_edid;
1047 
1048 	for (i = 0; i < length / 4; i++)
1049 		if (*(raw_edid + i) != 0)
1050 			return false;
1051 	return true;
1052 }
1053 
1054 static struct edid *
drm_do_get_edid(struct drm_connector * connector,struct i2c_adapter * adapter)1055 drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
1056 {
1057 	int i, j = 0;
1058 	u8 *block, valid_extensions = 0;
1059 	bool print_bad_edid = !connector->bad_edid_counter;
1060 
1061 	/* try to allock max memory at first time */
1062 	if ((block = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1), GFP_KERNEL)) == NULL)
1063 		return NULL;
1064 
1065 	/* base block fetch */
1066 	for (i = 0; i < 4; i++) {
1067 		if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
1068 			goto out;
1069 		if (drm_edid_block_valid(block, 0, print_bad_edid))
1070 			break;
1071 		if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
1072 			connector->null_edid_counter++;
1073 			goto carp;
1074 		}
1075 	}
1076 	if (i == 4)
1077 		goto carp;
1078 
1079 	/* if there's no extensions, we're done */
1080 	if (block[0x7e] == 0)
1081 		return (struct edid *) block;
1082 
1083 	for (j = 1; j <= block[0x7e]; j++) {
1084 		for (i = 0; i < 4; i++) {
1085 			if (drm_do_probe_ddc_edid(adapter,
1086 				  block + (valid_extensions + 1) * EDID_LENGTH,
1087 				  j, EDID_LENGTH))
1088 				goto out;
1089 			if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j, print_bad_edid)) {
1090 				valid_extensions++;
1091 				break;
1092 			}
1093 		}
1094 		if (i == 4)
1095 			 DRM_ERROR("%s: Ignoring invalid EDID block %d.\n",
1096 			 drm_get_connector_name(connector), j);
1097 	}
1098 
1099 	if (valid_extensions != block[0x7e]) {
1100 		block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
1101 		block[0x7e] = valid_extensions;
1102 	}
1103 
1104 	return (struct edid *) block;
1105 
1106 carp:
1107 	if (print_bad_edid) {
1108 		DRM_DEBUG_KMS("%s: EDID block %d invalid.\n",
1109 		 drm_get_connector_name(connector), j);
1110 	}
1111 	connector->bad_edid_counter++;
1112 
1113 out:
1114 	kfree(block, EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1));
1115 	return NULL;
1116 }
1117 
1118 /**
1119  * Probe DDC presence.
1120  *
1121  * \param adapter : i2c device adaptor
1122  * \return 1 on success
1123  */
1124 bool
drm_probe_ddc(struct i2c_adapter * adapter)1125 drm_probe_ddc(struct i2c_adapter *adapter)
1126 {
1127 	unsigned char out;
1128 
1129 	return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
1130 }
1131 
1132 /**
1133  * drm_get_edid - get EDID data, if available
1134  * @connector: connector we're probing
1135  * @adapter: i2c adapter to use for DDC
1136  *
1137  * Poke the given i2c channel to grab EDID data if possible.  If found,
1138  * attach it to the connector.
1139  *
1140  * Return edid data or NULL if we couldn't find any.
1141  */
drm_get_edid(struct drm_connector * connector,struct i2c_adapter * adapter)1142 struct edid *drm_get_edid(struct drm_connector *connector,
1143 			  struct i2c_adapter *adapter)
1144 {
1145 	struct edid *edid = NULL;
1146 
1147 	if (drm_probe_ddc(adapter))
1148 		edid = drm_do_get_edid(connector, adapter);
1149 
1150 	return edid;
1151 }
1152 
1153 /*** EDID parsing ***/
1154 
1155 /**
1156  * edid_vendor - match a string against EDID's obfuscated vendor field
1157  * @edid: EDID to match
1158  * @vendor: vendor string
1159  *
1160  * Returns true if @vendor is in @edid, false otherwise
1161  */
edid_vendor(struct edid * edid,char * vendor)1162 static bool edid_vendor(struct edid *edid, char *vendor)
1163 {
1164 	char edid_vendor[3];
1165 
1166 	edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
1167 	edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
1168 			  ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
1169 	edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
1170 
1171 	return !strncmp(edid_vendor, vendor, 3);
1172 }
1173 
1174 /**
1175  * edid_get_quirks - return quirk flags for a given EDID
1176  * @edid: EDID to process
1177  *
1178  * This tells subsequent routines what fixes they need to apply.
1179  */
edid_get_quirks(struct edid * edid)1180 static u32 edid_get_quirks(struct edid *edid)
1181 {
1182 	struct edid_quirk *quirk;
1183 	int i;
1184 
1185 	for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
1186 		quirk = &edid_quirk_list[i];
1187 
1188 		if (edid_vendor(edid, quirk->vendor) &&
1189 		    (EDID_PRODUCT_ID(edid) == quirk->product_id))
1190 			return quirk->quirks;
1191 	}
1192 
1193 	return 0;
1194 }
1195 
1196 #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
1197 #define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh))
1198 
1199 /**
1200  * edid_fixup_preferred - set preferred modes based on quirk list
1201  * @connector: has mode list to fix up
1202  * @quirks: quirks list
1203  *
1204  * Walk the mode list for @connector, clearing the preferred status
1205  * on existing modes and setting it anew for the right mode ala @quirks.
1206  */
edid_fixup_preferred(struct drm_connector * connector,u32 quirks)1207 static void edid_fixup_preferred(struct drm_connector *connector,
1208 				 u32 quirks)
1209 {
1210 	struct drm_display_mode *t, *cur_mode, *preferred_mode;
1211 	int target_refresh = 0;
1212 
1213 	if (list_empty(&connector->probed_modes))
1214 		return;
1215 
1216 	if (quirks & EDID_QUIRK_PREFER_LARGE_60)
1217 		target_refresh = 60;
1218 	if (quirks & EDID_QUIRK_PREFER_LARGE_75)
1219 		target_refresh = 75;
1220 
1221 	preferred_mode = list_first_entry(&connector->probed_modes,
1222 					  struct drm_display_mode, head);
1223 
1224 	list_for_each_entry_safe(cur_mode, t, struct drm_display_mode, &connector->probed_modes, head) {
1225 		cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
1226 
1227 		if (cur_mode == preferred_mode)
1228 			continue;
1229 
1230 		/* Largest mode is preferred */
1231 		if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
1232 			preferred_mode = cur_mode;
1233 
1234 		/* At a given size, try to get closest to target refresh */
1235 		if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
1236 			MODE_REFRESH_DIFF(cur_mode, target_refresh) <
1237 		    MODE_REFRESH_DIFF(preferred_mode, target_refresh)) {
1238 			preferred_mode = cur_mode;
1239 		}
1240 	}
1241 
1242 	preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
1243 }
1244 
1245 static bool
mode_is_rb(const struct drm_display_mode * mode)1246 mode_is_rb(const struct drm_display_mode *mode)
1247 {
1248 	return (mode->htotal - mode->hdisplay == 160) &&
1249 	       (mode->hsync_end - mode->hdisplay == 80) &&
1250 	       (mode->hsync_end - mode->hsync_start == 32) &&
1251 	       (mode->vsync_start - mode->vdisplay == 3);
1252 }
1253 
1254 /*
1255  * drm_mode_find_dmt - Create a copy of a mode if present in DMT
1256  * @dev: Device to duplicate against
1257  * @hsize: Mode width
1258  * @vsize: Mode height
1259  * @fresh: Mode refresh rate
1260  * @rb: Mode reduced-blanking-ness
1261  *
1262  * Walk the DMT mode list looking for a match for the given parameters.
1263  * Return a newly allocated copy of the mode, or NULL if not found.
1264  */
drm_mode_find_dmt(struct drm_device * dev,int hsize,int vsize,int fresh,bool rb)1265 struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
1266 					   int hsize, int vsize, int fresh,
1267 					   bool rb)
1268 {
1269 	int i;
1270 
1271 	for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
1272 		const struct drm_display_mode *ptr = &drm_dmt_modes[i];
1273 		if (hsize != ptr->hdisplay)
1274 			continue;
1275 		if (vsize != ptr->vdisplay)
1276 			continue;
1277 		if (fresh != drm_mode_vrefresh(ptr))
1278 			continue;
1279 		if (rb != mode_is_rb(ptr))
1280 			continue;
1281 
1282 		return drm_mode_duplicate(dev, ptr);
1283 	}
1284 
1285 	return NULL;
1286 }
1287 
1288 typedef void detailed_cb(struct detailed_timing *timing, void *closure);
1289 
1290 static void
cea_for_each_detailed_block(u8 * ext,detailed_cb * cb,void * closure)1291 cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
1292 {
1293 	int i, n = 0;
1294 	u8 d = ext[0x02];
1295 	u8 *det_base = ext + d;
1296 
1297 	n = (127 - d) / 18;
1298 	for (i = 0; i < n; i++)
1299 		cb((struct detailed_timing *)(det_base + 18 * i), closure);
1300 }
1301 
1302 static void
vtb_for_each_detailed_block(u8 * ext,detailed_cb * cb,void * closure)1303 vtb_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
1304 {
1305 	unsigned int i, n = min((int)ext[0x02], 6);
1306 	u8 *det_base = ext + 5;
1307 
1308 	if (ext[0x01] != 1)
1309 		return; /* unknown version */
1310 
1311 	for (i = 0; i < n; i++)
1312 		cb((struct detailed_timing *)(det_base + 18 * i), closure);
1313 }
1314 
1315 static void
drm_for_each_detailed_block(u8 * raw_edid,detailed_cb * cb,void * closure)1316 drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure)
1317 {
1318 	int i;
1319 	struct edid *edid = (struct edid *)raw_edid;
1320 
1321 	if (edid == NULL)
1322 		return;
1323 
1324 	for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
1325 		cb(&(edid->detailed_timings[i]), closure);
1326 
1327 	for (i = 1; i <= raw_edid[0x7e]; i++) {
1328 		u8 *ext = raw_edid + (i * EDID_LENGTH);
1329 		switch (*ext) {
1330 		case CEA_EXT:
1331 			cea_for_each_detailed_block(ext, cb, closure);
1332 			break;
1333 		case VTB_EXT:
1334 			vtb_for_each_detailed_block(ext, cb, closure);
1335 			break;
1336 		default:
1337 			break;
1338 		}
1339 	}
1340 }
1341 
1342 static void
is_rb(struct detailed_timing * t,void * data)1343 is_rb(struct detailed_timing *t, void *data)
1344 {
1345 	u8 *r = (u8 *)t;
1346 	if (r[3] == EDID_DETAIL_MONITOR_RANGE)
1347 		if (r[15] & 0x10)
1348 			*(bool *)data = true;
1349 }
1350 
1351 /* EDID 1.4 defines this explicitly.  For EDID 1.3, we guess, badly. */
1352 static bool
drm_monitor_supports_rb(struct edid * edid)1353 drm_monitor_supports_rb(struct edid *edid)
1354 {
1355 	if (edid->revision >= 4) {
1356 		bool ret = false;
1357 		drm_for_each_detailed_block((u8 *)edid, is_rb, &ret);
1358 		return ret;
1359 	}
1360 
1361 	return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0);
1362 }
1363 
1364 static void
find_gtf2(struct detailed_timing * t,void * data)1365 find_gtf2(struct detailed_timing *t, void *data)
1366 {
1367 	u8 *r = (u8 *)t;
1368 	if (r[3] == EDID_DETAIL_MONITOR_RANGE && r[10] == 0x02)
1369 		*(u8 **)data = r;
1370 }
1371 
1372 /* Secondary GTF curve kicks in above some break frequency */
1373 static int
drm_gtf2_hbreak(struct edid * edid)1374 drm_gtf2_hbreak(struct edid *edid)
1375 {
1376 	u8 *r = NULL;
1377 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1378 	return r ? (r[12] * 2) : 0;
1379 }
1380 
1381 static int
drm_gtf2_2c(struct edid * edid)1382 drm_gtf2_2c(struct edid *edid)
1383 {
1384 	u8 *r = NULL;
1385 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1386 	return r ? r[13] : 0;
1387 }
1388 
1389 static int
drm_gtf2_m(struct edid * edid)1390 drm_gtf2_m(struct edid *edid)
1391 {
1392 	u8 *r = NULL;
1393 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1394 	return r ? (r[15] << 8) + r[14] : 0;
1395 }
1396 
1397 static int
drm_gtf2_k(struct edid * edid)1398 drm_gtf2_k(struct edid *edid)
1399 {
1400 	u8 *r = NULL;
1401 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1402 	return r ? r[16] : 0;
1403 }
1404 
1405 static int
drm_gtf2_2j(struct edid * edid)1406 drm_gtf2_2j(struct edid *edid)
1407 {
1408 	u8 *r = NULL;
1409 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
1410 	return r ? r[17] : 0;
1411 }
1412 
1413 /**
1414  * standard_timing_level - get std. timing level(CVT/GTF/DMT)
1415  * @edid: EDID block to scan
1416  */
standard_timing_level(struct edid * edid)1417 static int standard_timing_level(struct edid *edid)
1418 {
1419 	if (edid->revision >= 2) {
1420 		if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
1421 			return LEVEL_CVT;
1422 		if (drm_gtf2_hbreak(edid))
1423 			return LEVEL_GTF2;
1424 		return LEVEL_GTF;
1425 	}
1426 	return LEVEL_DMT;
1427 }
1428 
1429 /*
1430  * 0 is reserved.  The spec says 0x01 fill for unused timings.  Some old
1431  * monitors fill with ascii space (0x20) instead.
1432  */
1433 static int
bad_std_timing(u8 a,u8 b)1434 bad_std_timing(u8 a, u8 b)
1435 {
1436 	return (a == 0x00 && b == 0x00) ||
1437 	       (a == 0x01 && b == 0x01) ||
1438 	       (a == 0x20 && b == 0x20);
1439 }
1440 
1441 /**
1442  * drm_mode_std - convert standard mode info (width, height, refresh) into mode
1443  * @t: standard timing params
1444  * @timing_level: standard timing level
1445  *
1446  * Take the standard timing params (in this case width, aspect, and refresh)
1447  * and convert them into a real mode using CVT/GTF/DMT.
1448  */
1449 static struct drm_display_mode *
drm_mode_std(struct drm_connector * connector,struct edid * edid,struct std_timing * t,int revision)1450 drm_mode_std(struct drm_connector *connector, struct edid *edid,
1451 	     struct std_timing *t, int revision)
1452 {
1453 	struct drm_device *dev = connector->dev;
1454 	struct drm_display_mode *m, *mode = NULL;
1455 	int hsize, vsize;
1456 	int vrefresh_rate;
1457 	unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
1458 		>> EDID_TIMING_ASPECT_SHIFT;
1459 	unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
1460 		>> EDID_TIMING_VFREQ_SHIFT;
1461 	int timing_level = standard_timing_level(edid);
1462 
1463 	if (bad_std_timing(t->hsize, t->vfreq_aspect))
1464 		return NULL;
1465 
1466 	/* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
1467 	hsize = t->hsize * 8 + 248;
1468 	/* vrefresh_rate = vfreq + 60 */
1469 	vrefresh_rate = vfreq + 60;
1470 	/* the vdisplay is calculated based on the aspect ratio */
1471 	if (aspect_ratio == 0) {
1472 		if (revision < 3)
1473 			vsize = hsize;
1474 		else
1475 			vsize = (hsize * 10) / 16;
1476 	} else if (aspect_ratio == 1)
1477 		vsize = (hsize * 3) / 4;
1478 	else if (aspect_ratio == 2)
1479 		vsize = (hsize * 4) / 5;
1480 	else
1481 		vsize = (hsize * 9) / 16;
1482 
1483 	/* HDTV hack, part 1 */
1484 	if (vrefresh_rate == 60 &&
1485 	    ((hsize == 1360 && vsize == 765) ||
1486 	     (hsize == 1368 && vsize == 769))) {
1487 		hsize = 1366;
1488 		vsize = 768;
1489 	}
1490 
1491 	/*
1492 	 * If this connector already has a mode for this size and refresh
1493 	 * rate (because it came from detailed or CVT info), use that
1494 	 * instead.  This way we don't have to guess at interlace or
1495 	 * reduced blanking.
1496 	 */
1497 	list_for_each_entry(m, struct drm_display_mode, &connector->probed_modes, head)
1498 		if (m->hdisplay == hsize && m->vdisplay == vsize &&
1499 		    drm_mode_vrefresh(m) == vrefresh_rate)
1500 			return NULL;
1501 
1502 	/* HDTV hack, part 2 */
1503 	if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) {
1504 		mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
1505 				    false);
1506 		if (mode != NULL) {
1507 			mode->hdisplay = 1366;
1508 			mode->hsync_start = mode->hsync_start - 1;
1509 			mode->hsync_end = mode->hsync_end - 1;
1510 		}
1511 		return mode;
1512 	}
1513 
1514 	/* check whether it can be found in default mode table */
1515 	if (drm_monitor_supports_rb(edid)) {
1516 		mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate,
1517 					 true);
1518 		if (mode)
1519 			return mode;
1520 	}
1521 	mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false);
1522 	if (mode)
1523 		return mode;
1524 
1525 	/* okay, generate it */
1526 	switch (timing_level) {
1527 	case LEVEL_DMT:
1528 		break;
1529 	case LEVEL_GTF:
1530 		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
1531 		break;
1532 	case LEVEL_GTF2:
1533 		/*
1534 		 * This is potentially wrong if there's ever a monitor with
1535 		 * more than one ranges section, each claiming a different
1536 		 * secondary GTF curve.  Please don't do that.
1537 		 */
1538 		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
1539 		if (!mode)
1540 			return NULL;
1541 		if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
1542 			drm_mode_destroy(dev, mode);
1543 			mode = drm_gtf_mode_complex(dev, hsize, vsize,
1544 						    vrefresh_rate, 0, 0,
1545 						    drm_gtf2_m(edid),
1546 						    drm_gtf2_2c(edid),
1547 						    drm_gtf2_k(edid),
1548 						    drm_gtf2_2j(edid));
1549 		}
1550 		break;
1551 	case LEVEL_CVT:
1552 		mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
1553 				    false);
1554 		break;
1555 	}
1556 	return mode;
1557 }
1558 
1559 /*
1560  * EDID is delightfully ambiguous about how interlaced modes are to be
1561  * encoded.  Our internal representation is of frame height, but some
1562  * HDTV detailed timings are encoded as field height.
1563  *
1564  * The format list here is from CEA, in frame size.  Technically we
1565  * should be checking refresh rate too.  Whatever.
1566  */
1567 static void
drm_mode_do_interlace_quirk(struct drm_display_mode * mode,struct detailed_pixel_timing * pt)1568 drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
1569 			    struct detailed_pixel_timing *pt)
1570 {
1571 	int i;
1572 	static const struct {
1573 		int w, h;
1574 	} cea_interlaced[] = {
1575 		{ 1920, 1080 },
1576 		{  720,  480 },
1577 		{ 1440,  480 },
1578 		{ 2880,  480 },
1579 		{  720,  576 },
1580 		{ 1440,  576 },
1581 		{ 2880,  576 },
1582 	};
1583 
1584 	if (!(pt->misc & DRM_EDID_PT_INTERLACED))
1585 		return;
1586 
1587 	for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) {
1588 		if ((mode->hdisplay == cea_interlaced[i].w) &&
1589 		    (mode->vdisplay == cea_interlaced[i].h / 2)) {
1590 			mode->vdisplay *= 2;
1591 			mode->vsync_start *= 2;
1592 			mode->vsync_end *= 2;
1593 			mode->vtotal *= 2;
1594 			mode->vtotal |= 1;
1595 		}
1596 	}
1597 
1598 	mode->flags |= DRM_MODE_FLAG_INTERLACE;
1599 }
1600 
1601 /**
1602  * drm_mode_detailed - create a new mode from an EDID detailed timing section
1603  * @dev: DRM device (needed to create new mode)
1604  * @edid: EDID block
1605  * @timing: EDID detailed timing info
1606  * @quirks: quirks to apply
1607  *
1608  * An EDID detailed timing block contains enough info for us to create and
1609  * return a new struct drm_display_mode.
1610  */
drm_mode_detailed(struct drm_device * dev,struct edid * edid,struct detailed_timing * timing,u32 quirks)1611 static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
1612 						  struct edid *edid,
1613 						  struct detailed_timing *timing,
1614 						  u32 quirks)
1615 {
1616 	struct drm_display_mode *mode;
1617 	struct detailed_pixel_timing *pt = &timing->data.pixel_data;
1618 	unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
1619 	unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
1620 	unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
1621 	unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
1622 	unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
1623 	unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
1624 	unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4;
1625 	unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
1626 
1627 	/* ignore tiny modes */
1628 	if (hactive < 64 || vactive < 64)
1629 		return NULL;
1630 
1631 	if (pt->misc & DRM_EDID_PT_STEREO) {
1632 		DRM_ERROR("stereo mode not supported\n");
1633 		return NULL;
1634 	}
1635 	if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
1636 		DRM_ERROR("integrated sync not supported\n");
1637 	}
1638 
1639 	/* it is incorrect if hsync/vsync width is zero */
1640 	if (!hsync_pulse_width || !vsync_pulse_width) {
1641 		DRM_DEBUG_KMS("Incorrect Detailed timing. "
1642 				"Wrong Hsync/Vsync pulse width\n");
1643 		return NULL;
1644 	}
1645 
1646 	if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
1647 		mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
1648 		if (!mode)
1649 			return NULL;
1650 
1651 		goto set_size;
1652 	}
1653 
1654 	mode = drm_mode_create(dev);
1655 	if (!mode)
1656 		return NULL;
1657 
1658 	if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
1659 		timing->pixel_clock = cpu_to_le16(1088);
1660 
1661 	mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
1662 
1663 	mode->hdisplay = hactive;
1664 	mode->hsync_start = mode->hdisplay + hsync_offset;
1665 	mode->hsync_end = mode->hsync_start + hsync_pulse_width;
1666 	mode->htotal = mode->hdisplay + hblank;
1667 
1668 	mode->vdisplay = vactive;
1669 	mode->vsync_start = mode->vdisplay + vsync_offset;
1670 	mode->vsync_end = mode->vsync_start + vsync_pulse_width;
1671 	mode->vtotal = mode->vdisplay + vblank;
1672 
1673 	/* Some EDIDs have bogus h/vtotal values */
1674 	if (mode->hsync_end > mode->htotal)
1675 		mode->htotal = mode->hsync_end + 1;
1676 	if (mode->vsync_end > mode->vtotal)
1677 		mode->vtotal = mode->vsync_end + 1;
1678 
1679 	drm_mode_do_interlace_quirk(mode, pt);
1680 
1681 	if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
1682 		pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
1683 	}
1684 
1685 	mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
1686 		DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
1687 	mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
1688 		DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
1689 
1690 set_size:
1691 	mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
1692 	mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
1693 
1694 	if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
1695 		mode->width_mm *= 10;
1696 		mode->height_mm *= 10;
1697 	}
1698 
1699 	if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
1700 		mode->width_mm = edid->width_cm * 10;
1701 		mode->height_mm = edid->height_cm * 10;
1702 	}
1703 
1704 	mode->type = DRM_MODE_TYPE_DRIVER;
1705 	drm_mode_set_name(mode);
1706 
1707 	return mode;
1708 }
1709 
1710 static bool
mode_in_hsync_range(const struct drm_display_mode * mode,struct edid * edid,u8 * t)1711 mode_in_hsync_range(const struct drm_display_mode *mode,
1712 		    struct edid *edid, u8 *t)
1713 {
1714 	int hsync, hmin, hmax;
1715 
1716 	hmin = t[7];
1717 	if (edid->revision >= 4)
1718 	    hmin += ((t[4] & 0x04) ? 255 : 0);
1719 	hmax = t[8];
1720 	if (edid->revision >= 4)
1721 	    hmax += ((t[4] & 0x08) ? 255 : 0);
1722 	hsync = drm_mode_hsync(mode);
1723 
1724 	return (hsync <= hmax && hsync >= hmin);
1725 }
1726 
1727 static bool
mode_in_vsync_range(const struct drm_display_mode * mode,struct edid * edid,u8 * t)1728 mode_in_vsync_range(const struct drm_display_mode *mode,
1729 		    struct edid *edid, u8 *t)
1730 {
1731 	int vsync, vmin, vmax;
1732 
1733 	vmin = t[5];
1734 	if (edid->revision >= 4)
1735 	    vmin += ((t[4] & 0x01) ? 255 : 0);
1736 	vmax = t[6];
1737 	if (edid->revision >= 4)
1738 	    vmax += ((t[4] & 0x02) ? 255 : 0);
1739 	vsync = drm_mode_vrefresh(mode);
1740 
1741 	return (vsync <= vmax && vsync >= vmin);
1742 }
1743 
1744 static u32
range_pixel_clock(struct edid * edid,u8 * t)1745 range_pixel_clock(struct edid *edid, u8 *t)
1746 {
1747 	/* unspecified */
1748 	if (t[9] == 0 || t[9] == 255)
1749 		return 0;
1750 
1751 	/* 1.4 with CVT support gives us real precision, yay */
1752 	if (edid->revision >= 4 && t[10] == 0x04)
1753 		return (t[9] * 10000) - ((t[12] >> 2) * 250);
1754 
1755 	/* 1.3 is pathetic, so fuzz up a bit */
1756 	return t[9] * 10000 + 5001;
1757 }
1758 
1759 static bool
mode_in_range(const struct drm_display_mode * mode,struct edid * edid,struct detailed_timing * timing)1760 mode_in_range(const struct drm_display_mode *mode, struct edid *edid,
1761 	      struct detailed_timing *timing)
1762 {
1763 	u32 max_clock;
1764 	u8 *t = (u8 *)timing;
1765 
1766 	if (!mode_in_hsync_range(mode, edid, t))
1767 		return false;
1768 
1769 	if (!mode_in_vsync_range(mode, edid, t))
1770 		return false;
1771 
1772 	if ((max_clock = range_pixel_clock(edid, t)))
1773 		if (mode->clock > max_clock)
1774 			return false;
1775 
1776 	/* 1.4 max horizontal check */
1777 	if (edid->revision >= 4 && t[10] == 0x04)
1778 		if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3))))
1779 			return false;
1780 
1781 	if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid))
1782 		return false;
1783 
1784 	return true;
1785 }
1786 
valid_inferred_mode(const struct drm_connector * connector,const struct drm_display_mode * mode)1787 static bool valid_inferred_mode(const struct drm_connector *connector,
1788 				const struct drm_display_mode *mode)
1789 {
1790 	struct drm_display_mode *m;
1791 	bool ok = false;
1792 
1793 	list_for_each_entry(m, struct drm_display_mode, &connector->probed_modes, head) {
1794 		if (mode->hdisplay == m->hdisplay &&
1795 		    mode->vdisplay == m->vdisplay &&
1796 		    drm_mode_vrefresh(mode) == drm_mode_vrefresh(m))
1797 			return false; /* duplicated */
1798 		if (mode->hdisplay <= m->hdisplay &&
1799 		    mode->vdisplay <= m->vdisplay)
1800 			ok = true;
1801 	}
1802 	return ok;
1803 }
1804 
1805 static int
drm_dmt_modes_for_range(struct drm_connector * connector,struct edid * edid,struct detailed_timing * timing)1806 drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
1807 			struct detailed_timing *timing)
1808 {
1809 	int i, modes = 0;
1810 	struct drm_display_mode *newmode;
1811 	struct drm_device *dev = connector->dev;
1812 
1813 	for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
1814 		if (mode_in_range(drm_dmt_modes + i, edid, timing) &&
1815 		    valid_inferred_mode(connector, drm_dmt_modes + i)) {
1816 			newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
1817 			if (newmode) {
1818 				drm_mode_probed_add(connector, newmode);
1819 				modes++;
1820 			}
1821 		}
1822 	}
1823 
1824 	return modes;
1825 }
1826 
1827 /* fix up 1366x768 mode from 1368x768;
1828  * GFT/CVT can't express 1366 width which isn't dividable by 8
1829  */
fixup_mode_1366x768(struct drm_display_mode * mode)1830 static void fixup_mode_1366x768(struct drm_display_mode *mode)
1831 {
1832 	if (mode->hdisplay == 1368 && mode->vdisplay == 768) {
1833 		mode->hdisplay = 1366;
1834 		mode->hsync_start--;
1835 		mode->hsync_end--;
1836 		drm_mode_set_name(mode);
1837 	}
1838 }
1839 
1840 static int
drm_gtf_modes_for_range(struct drm_connector * connector,struct edid * edid,struct detailed_timing * timing)1841 drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
1842 			struct detailed_timing *timing)
1843 {
1844 	int i, modes = 0;
1845 	struct drm_display_mode *newmode;
1846 	struct drm_device *dev = connector->dev;
1847 
1848 	for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
1849 		const struct minimode *m = &extra_modes[i];
1850 		newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
1851 		if (!newmode)
1852 			return modes;
1853 
1854 		fixup_mode_1366x768(newmode);
1855 		if (!mode_in_range(newmode, edid, timing) ||
1856 		    !valid_inferred_mode(connector, newmode)) {
1857 			drm_mode_destroy(dev, newmode);
1858 			continue;
1859 		}
1860 
1861 		drm_mode_probed_add(connector, newmode);
1862 		modes++;
1863 	}
1864 
1865 	return modes;
1866 }
1867 
1868 static int
drm_cvt_modes_for_range(struct drm_connector * connector,struct edid * edid,struct detailed_timing * timing)1869 drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
1870 			struct detailed_timing *timing)
1871 {
1872 	int i, modes = 0;
1873 	struct drm_display_mode *newmode;
1874 	struct drm_device *dev = connector->dev;
1875 	bool rb = drm_monitor_supports_rb(edid);
1876 
1877 	for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
1878 		const struct minimode *m = &extra_modes[i];
1879 		newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
1880 		if (!newmode)
1881 			return modes;
1882 
1883 		fixup_mode_1366x768(newmode);
1884 		if (!mode_in_range(newmode, edid, timing) ||
1885 		    !valid_inferred_mode(connector, newmode)) {
1886 			drm_mode_destroy(dev, newmode);
1887 			continue;
1888 		}
1889 
1890 		drm_mode_probed_add(connector, newmode);
1891 		modes++;
1892 	}
1893 
1894 	return modes;
1895 }
1896 
1897 static void
do_inferred_modes(struct detailed_timing * timing,void * c)1898 do_inferred_modes(struct detailed_timing *timing, void *c)
1899 {
1900 	struct detailed_mode_closure *closure = c;
1901 	struct detailed_non_pixel *data = &timing->data.other_data;
1902 	struct detailed_data_monitor_range *range = &data->data.range;
1903 
1904 	if (data->type != EDID_DETAIL_MONITOR_RANGE)
1905 		return;
1906 
1907 	closure->modes += drm_dmt_modes_for_range(closure->connector,
1908 						  closure->edid,
1909 						  timing);
1910 
1911 	if (!version_greater(closure->edid, 1, 1))
1912 		return; /* GTF not defined yet */
1913 
1914 	switch (range->flags) {
1915 	case 0x02: /* secondary gtf, XXX could do more */
1916 	case 0x00: /* default gtf */
1917 		closure->modes += drm_gtf_modes_for_range(closure->connector,
1918 							  closure->edid,
1919 							  timing);
1920 		break;
1921 	case 0x04: /* cvt, only in 1.4+ */
1922 		if (!version_greater(closure->edid, 1, 3))
1923 			break;
1924 
1925 		closure->modes += drm_cvt_modes_for_range(closure->connector,
1926 							  closure->edid,
1927 							  timing);
1928 		break;
1929 	case 0x01: /* just the ranges, no formula */
1930 	default:
1931 		break;
1932 	}
1933 }
1934 
1935 static int
add_inferred_modes(struct drm_connector * connector,struct edid * edid)1936 add_inferred_modes(struct drm_connector *connector, struct edid *edid)
1937 {
1938 	struct detailed_mode_closure closure = {
1939 		connector, edid, 0, 0, 0
1940 	};
1941 
1942 	if (version_greater(edid, 1, 0))
1943 		drm_for_each_detailed_block((u8 *)edid, do_inferred_modes,
1944 					    &closure);
1945 
1946 	return closure.modes;
1947 }
1948 
1949 static int
drm_est3_modes(struct drm_connector * connector,struct detailed_timing * timing)1950 drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
1951 {
1952 	int i, j, m, modes = 0;
1953 	struct drm_display_mode *mode;
1954 	u8 *est = ((u8 *)timing) + 5;
1955 
1956 	for (i = 0; i < 6; i++) {
1957 		for (j = 7; j > 0; j--) {
1958 			m = (i * 8) + (7 - j);
1959 			if (m >= ARRAY_SIZE(est3_modes))
1960 				break;
1961 			if (est[i] & (1 << j)) {
1962 				mode = drm_mode_find_dmt(connector->dev,
1963 							 est3_modes[m].w,
1964 							 est3_modes[m].h,
1965 							 est3_modes[m].r,
1966 							 est3_modes[m].rb);
1967 				if (mode) {
1968 					drm_mode_probed_add(connector, mode);
1969 					modes++;
1970 				}
1971 			}
1972 		}
1973 	}
1974 
1975 	return modes;
1976 }
1977 
1978 static void
do_established_modes(struct detailed_timing * timing,void * c)1979 do_established_modes(struct detailed_timing *timing, void *c)
1980 {
1981 	struct detailed_mode_closure *closure = c;
1982 	struct detailed_non_pixel *data = &timing->data.other_data;
1983 
1984 	if (data->type == EDID_DETAIL_EST_TIMINGS)
1985 		closure->modes += drm_est3_modes(closure->connector, timing);
1986 }
1987 
1988 /**
1989  * add_established_modes - get est. modes from EDID and add them
1990  * @edid: EDID block to scan
1991  *
1992  * Each EDID block contains a bitmap of the supported "established modes" list
1993  * (defined above).  Tease them out and add them to the global modes list.
1994  */
1995 static int
add_established_modes(struct drm_connector * connector,struct edid * edid)1996 add_established_modes(struct drm_connector *connector, struct edid *edid)
1997 {
1998 	struct drm_device *dev = connector->dev;
1999 	unsigned long est_bits = edid->established_timings.t1 |
2000 		(edid->established_timings.t2 << 8) |
2001 		((edid->established_timings.mfg_rsvd & 0x80) << 9);
2002 	int i, modes = 0;
2003 	struct detailed_mode_closure closure = {
2004 		connector, edid, 0, 0, 0
2005 	};
2006 
2007 	for (i = 0; i <= EDID_EST_TIMINGS; i++) {
2008 		if (est_bits & (1<<i)) {
2009 			struct drm_display_mode *newmode;
2010 			newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
2011 			if (newmode) {
2012 				drm_mode_probed_add(connector, newmode);
2013 				modes++;
2014 			}
2015 		}
2016 	}
2017 
2018 	if (version_greater(edid, 1, 0))
2019 		    drm_for_each_detailed_block((u8 *)edid,
2020 						do_established_modes, &closure);
2021 
2022 	return modes + closure.modes;
2023 }
2024 
2025 static void
do_standard_modes(struct detailed_timing * timing,void * c)2026 do_standard_modes(struct detailed_timing *timing, void *c)
2027 {
2028 	struct detailed_mode_closure *closure = c;
2029 	struct detailed_non_pixel *data = &timing->data.other_data;
2030 	struct drm_connector *connector = closure->connector;
2031 	struct edid *edid = closure->edid;
2032 
2033 	if (data->type == EDID_DETAIL_STD_MODES) {
2034 		int i;
2035 		for (i = 0; i < 6; i++) {
2036 			struct std_timing *std;
2037 			struct drm_display_mode *newmode;
2038 
2039 			std = &data->data.timings[i];
2040 			newmode = drm_mode_std(connector, edid, std,
2041 					       edid->revision);
2042 			if (newmode) {
2043 				drm_mode_probed_add(connector, newmode);
2044 				closure->modes++;
2045 			}
2046 		}
2047 	}
2048 }
2049 
2050 /**
2051  * add_standard_modes - get std. modes from EDID and add them
2052  * @edid: EDID block to scan
2053  *
2054  * Standard modes can be calculated using the appropriate standard (DMT,
2055  * GTF or CVT. Grab them from @edid and add them to the list.
2056  */
2057 static int
add_standard_modes(struct drm_connector * connector,struct edid * edid)2058 add_standard_modes(struct drm_connector *connector, struct edid *edid)
2059 {
2060 	int i, modes = 0;
2061 	struct detailed_mode_closure closure = {
2062 		connector, edid, 0, 0, 0
2063 	};
2064 
2065 	for (i = 0; i < EDID_STD_TIMINGS; i++) {
2066 		struct drm_display_mode *newmode;
2067 
2068 		newmode = drm_mode_std(connector, edid,
2069 				       &edid->standard_timings[i],
2070 				       edid->revision);
2071 		if (newmode) {
2072 			drm_mode_probed_add(connector, newmode);
2073 			modes++;
2074 		}
2075 	}
2076 
2077 	if (version_greater(edid, 1, 0))
2078 		drm_for_each_detailed_block((u8 *)edid, do_standard_modes,
2079 					    &closure);
2080 
2081 	/* XXX should also look for standard codes in VTB blocks */
2082 
2083 	return modes + closure.modes;
2084 }
2085 
drm_cvt_modes(struct drm_connector * connector,struct detailed_timing * timing)2086 static int drm_cvt_modes(struct drm_connector *connector,
2087 			 struct detailed_timing *timing)
2088 {
2089 	int i, j, modes = 0;
2090 	struct drm_display_mode *newmode;
2091 	struct drm_device *dev = connector->dev;
2092 	struct cvt_timing *cvt;
2093 	const int rates[] = { 60, 85, 75, 60, 50 };
2094 	const u8 empty[3] = { 0, 0, 0 };
2095 
2096 	for (i = 0; i < 4; i++) {
2097 		int width, height;
2098 		cvt = &(timing->data.other_data.data.cvt[i]);
2099 
2100 		if (!memcmp(cvt->code, empty, 3))
2101 			continue;
2102 
2103 		height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2;
2104 		switch (cvt->code[1] & 0x0c) {
2105 		default: /* else gcc says: width may be used uninitialized... */
2106 		case 0x00:
2107 			width = height * 4 / 3;
2108 			break;
2109 		case 0x04:
2110 			width = height * 16 / 9;
2111 			break;
2112 		case 0x08:
2113 			width = height * 16 / 10;
2114 			break;
2115 		case 0x0c:
2116 			width = height * 15 / 9;
2117 			break;
2118 		}
2119 
2120 		for (j = 1; j < 5; j++) {
2121 			if (cvt->code[2] & (1 << j)) {
2122 				newmode = drm_cvt_mode(dev, width, height,
2123 						       rates[j], j == 0,
2124 						       false, false);
2125 				if (newmode) {
2126 					drm_mode_probed_add(connector, newmode);
2127 					modes++;
2128 				}
2129 			}
2130 		}
2131 	}
2132 
2133 	return modes;
2134 }
2135 
2136 static void
do_cvt_mode(struct detailed_timing * timing,void * c)2137 do_cvt_mode(struct detailed_timing *timing, void *c)
2138 {
2139 	struct detailed_mode_closure *closure = c;
2140 	struct detailed_non_pixel *data = &timing->data.other_data;
2141 
2142 	if (data->type == EDID_DETAIL_CVT_3BYTE)
2143 		closure->modes += drm_cvt_modes(closure->connector, timing);
2144 }
2145 
2146 static int
add_cvt_modes(struct drm_connector * connector,struct edid * edid)2147 add_cvt_modes(struct drm_connector *connector, struct edid *edid)
2148 {
2149 	struct detailed_mode_closure closure = {
2150 		connector, edid, 0, 0, 0
2151 	};
2152 
2153 	if (version_greater(edid, 1, 2))
2154 		drm_for_each_detailed_block((u8 *)edid, do_cvt_mode, &closure);
2155 
2156 	/* XXX should also look for CVT codes in VTB blocks */
2157 
2158 	return closure.modes;
2159 }
2160 
2161 static void
do_detailed_mode(struct detailed_timing * timing,void * c)2162 do_detailed_mode(struct detailed_timing *timing, void *c)
2163 {
2164 	struct detailed_mode_closure *closure = c;
2165 	struct drm_display_mode *newmode;
2166 
2167 	if (timing->pixel_clock) {
2168 		newmode = drm_mode_detailed(closure->connector->dev,
2169 					    closure->edid, timing,
2170 					    closure->quirks);
2171 		if (!newmode)
2172 			return;
2173 
2174 		if (closure->preferred)
2175 			newmode->type |= DRM_MODE_TYPE_PREFERRED;
2176 
2177 		drm_mode_probed_add(closure->connector, newmode);
2178 		closure->modes++;
2179 		closure->preferred = 0;
2180 	}
2181 }
2182 
2183 /*
2184  * add_detailed_modes - Add modes from detailed timings
2185  * @connector: attached connector
2186  * @edid: EDID block to scan
2187  * @quirks: quirks to apply
2188  */
2189 static int
add_detailed_modes(struct drm_connector * connector,struct edid * edid,u32 quirks)2190 add_detailed_modes(struct drm_connector *connector, struct edid *edid,
2191 		   u32 quirks)
2192 {
2193 	struct detailed_mode_closure closure = {
2194 		connector,
2195 		edid,
2196 		1,
2197 		quirks,
2198 		0
2199 	};
2200 
2201 	if (closure.preferred && !version_greater(edid, 1, 3))
2202 		closure.preferred =
2203 		    (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
2204 
2205 	drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure);
2206 
2207 	return closure.modes;
2208 }
2209 
2210 #define HDMI_IDENTIFIER 0x000C03
2211 #define AUDIO_BLOCK	0x01
2212 #define VIDEO_BLOCK     0x02
2213 #define VENDOR_BLOCK    0x03
2214 #define SPEAKER_BLOCK	0x04
2215 #define VIDEO_CAPABILITY_BLOCK	0x07
2216 #define EDID_BASIC_AUDIO	(1 << 6)
2217 #define EDID_CEA_YCRCB444	(1 << 5)
2218 #define EDID_CEA_YCRCB422	(1 << 4)
2219 #define EDID_CEA_VCDB_QS	(1 << 6)
2220 
2221 /**
2222  * Search EDID for CEA extension block.
2223  */
drm_find_cea_extension(struct edid * edid)2224 u8 *drm_find_cea_extension(struct edid *edid)
2225 {
2226 	u8 *edid_ext = NULL;
2227 	int i;
2228 
2229 	/* No EDID or EDID extensions */
2230 	if (edid == NULL || edid->extensions == 0)
2231 		return NULL;
2232 
2233 	/* Find CEA extension */
2234 	for (i = 0; i < edid->extensions; i++) {
2235 		edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
2236 		if (edid_ext[0] == CEA_EXT)
2237 			break;
2238 	}
2239 
2240 	if (i == edid->extensions)
2241 		return NULL;
2242 
2243 	return edid_ext;
2244 }
2245 
2246 /*
2247  * Calculate the alternate clock for the CEA mode
2248  * (60Hz vs. 59.94Hz etc.)
2249  */
2250 static unsigned int
cea_mode_alternate_clock(const struct drm_display_mode * cea_mode)2251 cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
2252 {
2253 	unsigned int clock = cea_mode->clock;
2254 
2255 	if (cea_mode->vrefresh % 6 != 0)
2256 		return clock;
2257 
2258 	/*
2259 	 * edid_cea_modes contains the 59.94Hz
2260 	 * variant for 240 and 480 line modes,
2261 	 * and the 60Hz variant otherwise.
2262 	 */
2263 	if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
2264 		clock = clock * 1001 / 1000;
2265 	else
2266 		clock = DIV_ROUND_UP(clock * 1000, 1001);
2267 
2268 	return clock;
2269 }
2270 
2271 /**
2272  * drm_match_cea_mode - look for a CEA mode matching given mode
2273  * @to_match: display mode
2274  *
2275  * Returns the CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
2276  * mode.
2277  */
drm_match_cea_mode(const struct drm_display_mode * to_match)2278 u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
2279 {
2280 	u8 mode;
2281 
2282 	if (!to_match->clock)
2283 		return 0;
2284 
2285 	for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) {
2286 		const struct drm_display_mode *cea_mode = (struct drm_display_mode *)&edid_cea_modes[mode];
2287 		unsigned int clock1, clock2;
2288 
2289 		/* Check both 60Hz and 59.94Hz */
2290 		clock1 = cea_mode->clock;
2291 		clock2 = cea_mode_alternate_clock(cea_mode);
2292 
2293 		if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
2294 		     KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
2295 		    drm_mode_equal_no_clocks(to_match, cea_mode))
2296 			return mode + 1;
2297 	}
2298 	return 0;
2299 }
2300 
2301 static int
add_alternate_cea_modes(struct drm_connector * connector,struct edid * edid)2302 add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
2303 {
2304 	struct drm_device *dev = connector->dev;
2305 	struct drm_display_mode *mode, *tmp;
2306 	struct list_head list;
2307 
2308 	INIT_LIST_HEAD(&list);
2309 
2310 	int modes = 0;
2311 
2312 	/* Don't add CEA modes if the CEA extension block is missing */
2313 	if (!drm_find_cea_extension(edid))
2314 		return 0;
2315 
2316 	/*
2317 	 * Go through all probed modes and create a new mode
2318 	 * with the alternate clock for certain CEA modes.
2319 	 */
2320 	list_for_each_entry(mode, struct drm_display_mode, &connector->probed_modes, head) {
2321 		const struct drm_display_mode *cea_mode;
2322 		struct drm_display_mode *newmode;
2323 		u8 cea_mode_idx = drm_match_cea_mode(mode) - 1;
2324 		unsigned int clock1, clock2;
2325 
2326 		if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes))
2327 			continue;
2328 
2329 		cea_mode = &edid_cea_modes[cea_mode_idx];
2330 
2331 		clock1 = cea_mode->clock;
2332 		clock2 = cea_mode_alternate_clock(cea_mode);
2333 
2334 		if (clock1 == clock2)
2335 			continue;
2336 
2337 		if (mode->clock != clock1 && mode->clock != clock2)
2338 			continue;
2339 
2340 		newmode = drm_mode_duplicate(dev, cea_mode);
2341 		if (!newmode)
2342 			continue;
2343 
2344 		/*
2345 		 * The current mode could be either variant. Make
2346 		 * sure to pick the "other" clock for the new mode.
2347 		 */
2348 		if (mode->clock != clock1)
2349 			newmode->clock = clock1;
2350 		else
2351 			newmode->clock = clock2;
2352 
2353 		list_add_tail(&newmode->head, &list, (caddr_t)newmode);
2354 	}
2355 
2356 	list_for_each_entry_safe(mode, tmp, struct drm_display_mode, &list, head) {
2357 		list_del(&mode->head);
2358 		drm_mode_probed_add(connector, mode);
2359 		modes++;
2360 	}
2361 
2362 	return modes;
2363 }
2364 
2365 static int
do_cea_modes(struct drm_connector * connector,u8 * db,u8 len)2366 do_cea_modes (struct drm_connector *connector, u8 *db, u8 len)
2367 {
2368 	struct drm_device *dev = connector->dev;
2369 	u8 * mode, cea_mode;
2370 	int modes = 0;
2371 
2372 	for (mode = db; mode < db + len; mode++) {
2373 		cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */
2374 		if (cea_mode < ARRAY_SIZE(edid_cea_modes)) {
2375 			struct drm_display_mode *newmode;
2376 			newmode = drm_mode_duplicate(dev,
2377 						     &edid_cea_modes[cea_mode]);
2378 			if (newmode) {
2379 				newmode->vrefresh = 0;
2380 				drm_mode_probed_add(connector, newmode);
2381 				modes++;
2382 			}
2383 		}
2384 	}
2385 
2386 	return modes;
2387 }
2388 
2389 static int
cea_db_payload_len(const u8 * db)2390 cea_db_payload_len(const u8 *db)
2391 {
2392 	return db[0] & 0x1f;
2393 }
2394 
2395 static int
cea_db_tag(const u8 * db)2396 cea_db_tag(const u8 *db)
2397 {
2398 	return db[0] >> 5;
2399 }
2400 
2401 static int
cea_revision(const u8 * cea)2402 cea_revision(const u8 *cea)
2403 {
2404 	return cea[1];
2405 }
2406 
2407 static int
cea_db_offsets(const u8 * cea,int * start,int * end)2408 cea_db_offsets(const u8 *cea, int *start, int *end)
2409 {
2410 	/* Data block offset in CEA extension block */
2411 	*start = 4;
2412 	*end = cea[2];
2413 	if (*end == 0)
2414 		*end = 127;
2415 	if (*end < 4 || *end > 127)
2416 		return -ERANGE;
2417 	return 0;
2418 }
2419 
2420 #define for_each_cea_db(cea, i, start, end) \
2421 	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
2422 
2423 static int
add_cea_modes(struct drm_connector * connector,struct edid * edid)2424 add_cea_modes(struct drm_connector *connector, struct edid *edid)
2425 {
2426 	u8 * cea = drm_find_cea_extension(edid);
2427 	u8 * db, dbl;
2428 	int modes = 0;
2429 
2430 	if (cea && cea_revision(cea) >= 3) {
2431 		int i, start, end;
2432 
2433 		if (cea_db_offsets(cea, &start, &end))
2434 			return 0;
2435 
2436 		for_each_cea_db(cea, i, start, end) {
2437 			db = &cea[i];
2438 			dbl = cea_db_payload_len(db);
2439 
2440 			if (cea_db_tag(db) == VIDEO_BLOCK)
2441 				modes += do_cea_modes (connector, db+1, dbl);
2442 		}
2443 	}
2444 
2445 	return modes;
2446 }
2447 
2448 static void
parse_hdmi_vsdb(struct drm_connector * connector,const u8 * db)2449 parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
2450 {
2451 	u8 len = cea_db_payload_len(db);
2452 
2453 	if (len >= 6) {
2454 		connector->eld[5] |= (db[6] >> 7) << 1;  /* Supports_AI */
2455 		connector->dvi_dual = db[6] & 1;
2456 	}
2457 	if (len >= 7)
2458 		connector->max_tmds_clock = db[7] * 5;
2459 	if (len >= 8) {
2460 		connector->latency_present[0] = db[8] >> 7;
2461 		connector->latency_present[1] = (db[8] >> 6) & 1;
2462 	}
2463 	if (len >= 9)
2464 		connector->video_latency[0] = db[9];
2465 	if (len >= 10)
2466 		connector->audio_latency[0] = db[10];
2467 	if (len >= 11)
2468 		connector->video_latency[1] = db[11];
2469 	if (len >= 12)
2470 		connector->audio_latency[1] = db[12];
2471 
2472 	DRM_LOG_KMS("HDMI: DVI dual %d, "
2473 		    "max TMDS clock %d, "
2474 		    "latency present %d %d, "
2475 		    "video latency %d %d, "
2476 		    "audio latency %d %d\n",
2477 		    connector->dvi_dual,
2478 		    connector->max_tmds_clock,
2479 	      (int) connector->latency_present[0],
2480 	      (int) connector->latency_present[1],
2481 		    connector->video_latency[0],
2482 		    connector->video_latency[1],
2483 		    connector->audio_latency[0],
2484 		    connector->audio_latency[1]);
2485 }
2486 
2487 static void
monitor_name(struct detailed_timing * t,void * data)2488 monitor_name(struct detailed_timing *t, void *data)
2489 {
2490 	if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
2491 		*(u8 **)data = t->data.other_data.data.str.str;
2492 }
2493 
cea_db_is_hdmi_vsdb(const u8 * db)2494 static bool cea_db_is_hdmi_vsdb(const u8 *db)
2495 {
2496 	int hdmi_id;
2497 
2498 	if (cea_db_tag(db) != VENDOR_BLOCK)
2499 		return false;
2500 
2501 	if (cea_db_payload_len(db) < 5)
2502 		return false;
2503 
2504 	hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
2505 
2506 	return hdmi_id == HDMI_IDENTIFIER;
2507 }
2508 
2509 /**
2510  * drm_edid_to_eld - build ELD from EDID
2511  * @connector: connector corresponding to the HDMI/DP sink
2512  * @edid: EDID to parse
2513  *
2514  * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver.
2515  * Some ELD fields are left to the graphics driver caller:
2516  * - Conn_Type
2517  * - HDCP
2518  * - Port_ID
2519  */
drm_edid_to_eld(struct drm_connector * connector,struct edid * edid)2520 void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
2521 {
2522 	uint8_t *eld = connector->eld;
2523 	u8 *cea;
2524 	u8 *name;
2525 	u8 *db;
2526 	int sad_count = 0;
2527 	int mnl;
2528 	int dbl;
2529 
2530 	(void) memset(eld, 0, sizeof(connector->eld));
2531 
2532 	cea = drm_find_cea_extension(edid);
2533 	if (!cea) {
2534 		DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
2535 		return;
2536 	}
2537 
2538 	name = NULL;
2539 	drm_for_each_detailed_block((u8 *)edid, monitor_name, &name);
2540 	for (mnl = 0; name && mnl < 13; mnl++) {
2541 		if (name[mnl] == 0x0a)
2542 			break;
2543 		eld[20 + mnl] = name[mnl];
2544 	}
2545 	eld[4] = (cea[1] << 5) | mnl;
2546 	DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20);
2547 
2548 	eld[0] = 2 << 3;		/* ELD version: 2 */
2549 
2550 	eld[16] = edid->mfg_id[0];
2551 	eld[17] = edid->mfg_id[1];
2552 	eld[18] = edid->prod_code[0];
2553 	eld[19] = edid->prod_code[1];
2554 
2555 	if (cea_revision(cea) >= 3) {
2556 		int i, start, end;
2557 
2558 		if (cea_db_offsets(cea, &start, &end)) {
2559 			start = 0;
2560 			end = 0;
2561 		}
2562 
2563 		for_each_cea_db(cea, i, start, end) {
2564 			db = &cea[i];
2565 			dbl = cea_db_payload_len(db);
2566 
2567 			switch (cea_db_tag(db)) {
2568 			case AUDIO_BLOCK:
2569 				/* Audio Data Block, contains SADs */
2570 				sad_count = dbl / 3;
2571 				if (dbl >= 1)
2572 					(void) memcpy(eld + 20 + mnl, &db[1], dbl);
2573 				break;
2574 			case SPEAKER_BLOCK:
2575 				/* Speaker Allocation Data Block */
2576 				if (dbl >= 1)
2577 					eld[7] = db[1];
2578 				break;
2579 			case VENDOR_BLOCK:
2580 				/* HDMI Vendor-Specific Data Block */
2581 				if (cea_db_is_hdmi_vsdb(db))
2582 					parse_hdmi_vsdb(connector, db);
2583 				break;
2584 			default:
2585 				break;
2586 			}
2587 		}
2588 	}
2589 	eld[5] |= sad_count << 4;
2590 	eld[2] = (20 + mnl + sad_count * 3 + 3) / 4;
2591 
2592 	DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count);
2593 }
2594 
2595 /**
2596  * drm_edid_to_sad - extracts SADs from EDID
2597  * @edid: EDID to parse
2598  * @sads: pointer that will be set to the extracted SADs
2599  *
2600  * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it.
2601  * Note: returned pointer needs to be kfreed
2602  *
2603  * Return number of found SADs or negative number on error.
2604  */
drm_edid_to_sad(struct edid * edid,struct cea_sad ** sads)2605 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
2606 {
2607 	int count = 0;
2608 	int i, start, end, dbl;
2609 	u8 *cea;
2610 
2611 	cea = drm_find_cea_extension(edid);
2612 	if (!cea) {
2613 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
2614 		return -ENOENT;
2615 	}
2616 
2617 	if (cea_revision(cea) < 3) {
2618 		DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
2619 		return -ENOTSUP;
2620 	}
2621 
2622 	if (cea_db_offsets(cea, &start, &end)) {
2623 		DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
2624 		return -EPROTO;
2625 	}
2626 
2627 	for_each_cea_db(cea, i, start, end) {
2628 		u8 *db = &cea[i];
2629 
2630 		if (cea_db_tag(db) == AUDIO_BLOCK) {
2631 			int j;
2632 			dbl = cea_db_payload_len(db);
2633 
2634 			count = dbl / 3; /* SAD is 3B */
2635 			*sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
2636 			if (!*sads)
2637 				return -ENOMEM;
2638 			for (j = 0; j < count; j++) {
2639 				u8 *sad = &db[1 + j * 3];
2640 
2641 				(*sads)[j].format = (sad[0] & 0x78) >> 3;
2642 				(*sads)[j].channels = sad[0] & 0x7;
2643 				(*sads)[j].freq = sad[1] & 0x7F;
2644 				(*sads)[j].byte2 = sad[2];
2645 			}
2646 			break;
2647 		}
2648 	}
2649 
2650 	return count;
2651 }
2652 
2653 /**
2654  * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond
2655  * @connector: connector associated with the HDMI/DP sink
2656  * @mode: the display mode
2657  */
drm_av_sync_delay(struct drm_connector * connector,struct drm_display_mode * mode)2658 int drm_av_sync_delay(struct drm_connector *connector,
2659 		      struct drm_display_mode *mode)
2660 {
2661 	int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
2662 	int a, v;
2663 
2664 	if (!connector->latency_present[0])
2665 		return 0;
2666 	if (!connector->latency_present[1])
2667 		i = 0;
2668 
2669 	a = connector->audio_latency[i];
2670 	v = connector->video_latency[i];
2671 
2672 	/*
2673 	 * HDMI/DP sink doesn't support audio or video?
2674 	 */
2675 	if (a == 255 || v == 255)
2676 		return 0;
2677 
2678 	/*
2679 	 * Convert raw EDID values to millisecond.
2680 	 * Treat unknown latency as 0ms.
2681 	 */
2682 	if (a)
2683 		a = min(2 * (a - 1), 500);
2684 	if (v)
2685 		v = min(2 * (v - 1), 500);
2686 
2687 	return max(v - a, 0);
2688 }
2689 
2690 /**
2691  * drm_select_eld - select one ELD from multiple HDMI/DP sinks
2692  * @encoder: the encoder just changed display mode
2693  * @mode: the adjusted display mode
2694  *
2695  * It's possible for one encoder to be associated with multiple HDMI/DP sinks.
2696  * The policy is now hard coded to simply use the first HDMI/DP sink's ELD.
2697  */
drm_select_eld(struct drm_encoder * encoder,struct drm_display_mode * mode)2698 struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
2699 				/* LINTED E_FUNC_ARG_UNUSED */
2700 				     struct drm_display_mode *mode)
2701 {
2702 	struct drm_connector *connector;
2703 	struct drm_device *dev = encoder->dev;
2704 
2705 	list_for_each_entry(connector, struct drm_connector, &dev->mode_config.connector_list, head)
2706 		if (connector->encoder == encoder && connector->eld[0])
2707 			return connector;
2708 
2709 	return NULL;
2710 }
2711 
2712 /**
2713  * drm_detect_hdmi_monitor - detect whether monitor is hdmi.
2714  * @edid: monitor EDID information
2715  *
2716  * Parse the CEA extension according to CEA-861-B.
2717  * Return true if HDMI, false if not or unknown.
2718  */
drm_detect_hdmi_monitor(struct edid * edid)2719 bool drm_detect_hdmi_monitor(struct edid *edid)
2720 {
2721 	u8 *edid_ext;
2722 	int i;
2723 	int start_offset, end_offset;
2724 
2725 	edid_ext = drm_find_cea_extension(edid);
2726 	if (!edid_ext)
2727 		return false;
2728 
2729 	if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
2730 		return false;
2731 
2732 	/*
2733 	 * Because HDMI identifier is in Vendor Specific Block,
2734 	 * search it from all data blocks of CEA extension.
2735 	 */
2736 	for_each_cea_db(edid_ext, i, start_offset, end_offset) {
2737 		if (cea_db_is_hdmi_vsdb(&edid_ext[i]))
2738 			return true;
2739 	}
2740 
2741 	return false;
2742 }
2743 
2744 /**
2745  * drm_detect_monitor_audio - check monitor audio capability
2746  *
2747  * Monitor should have CEA extension block.
2748  * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
2749  * audio' only. If there is any audio extension block and supported
2750  * audio format, assume at least 'basic audio' support, even if 'basic
2751  * audio' is not defined in EDID.
2752  *
2753  */
drm_detect_monitor_audio(struct edid * edid)2754 bool drm_detect_monitor_audio(struct edid *edid)
2755 {
2756 	u8 *edid_ext;
2757 	int i, j;
2758 	bool has_audio = false;
2759 	int start_offset, end_offset;
2760 
2761 	edid_ext = drm_find_cea_extension(edid);
2762 	if (!edid_ext)
2763 		goto end;
2764 
2765 	has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
2766 
2767 	if (has_audio) {
2768 		DRM_DEBUG_KMS("Monitor has basic audio support\n");
2769 		goto end;
2770 	}
2771 
2772 	if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
2773 		goto end;
2774 
2775 	for_each_cea_db(edid_ext, i, start_offset, end_offset) {
2776 		if (cea_db_tag(&edid_ext[i]) == AUDIO_BLOCK) {
2777 			has_audio = true;
2778 			for (j = 1; j < cea_db_payload_len(&edid_ext[i]) + 1; j += 3)
2779 				DRM_DEBUG_KMS("CEA audio format %d\n",
2780 					      (edid_ext[i + j] >> 3) & 0xf);
2781 			goto end;
2782 		}
2783 	}
2784 end:
2785 	return has_audio;
2786 }
2787 
2788 /**
2789  * drm_rgb_quant_range_selectable - is RGB quantization range selectable?
2790  *
2791  * Check whether the monitor reports the RGB quantization range selection
2792  * as supported. The AVI infoframe can then be used to inform the monitor
2793  * which quantization range (full or limited) is used.
2794  */
drm_rgb_quant_range_selectable(struct edid * edid)2795 bool drm_rgb_quant_range_selectable(struct edid *edid)
2796 {
2797 	u8 *edid_ext;
2798 	int i, start, end;
2799 
2800 	edid_ext = drm_find_cea_extension(edid);
2801 	if (!edid_ext)
2802 		return false;
2803 
2804 	if (cea_db_offsets(edid_ext, &start, &end))
2805 		return false;
2806 
2807 	for_each_cea_db(edid_ext, i, start, end) {
2808 		if (cea_db_tag(&edid_ext[i]) == VIDEO_CAPABILITY_BLOCK &&
2809 		    cea_db_payload_len(&edid_ext[i]) == 2) {
2810 			DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
2811 			return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
2812 		}
2813 	}
2814 
2815 	return false;
2816 }
2817 
2818 /**
2819  * drm_add_display_info - pull display info out if present
2820  * @edid: EDID data
2821  * @info: display info (attached to connector)
2822  *
2823  * Grab any available display info and stuff it into the drm_display_info
2824  * structure that's part of the connector.  Useful for tracking bpp and
2825  * color spaces.
2826  */
drm_add_display_info(struct edid * edid,struct drm_display_info * info)2827 static void drm_add_display_info(struct edid *edid,
2828 				 struct drm_display_info *info)
2829 {
2830 	u8 *edid_ext;
2831 
2832 	info->width_mm = edid->width_cm * 10;
2833 	info->height_mm = edid->height_cm * 10;
2834 
2835 	/* driver figures it out in this case */
2836 	info->bpc = 0;
2837 	info->color_formats = 0;
2838 
2839 	if (edid->revision < 3)
2840 		return;
2841 
2842 	if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
2843 		return;
2844 
2845 	/* Get data from CEA blocks if present */
2846 	edid_ext = drm_find_cea_extension(edid);
2847 	if (edid_ext) {
2848 		info->cea_rev = edid_ext[1];
2849 
2850 		/* The existence of a CEA block should imply RGB support */
2851 		info->color_formats = DRM_COLOR_FORMAT_RGB444;
2852 		if (edid_ext[3] & EDID_CEA_YCRCB444)
2853 			info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
2854 		if (edid_ext[3] & EDID_CEA_YCRCB422)
2855 			info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
2856 	}
2857 
2858 	/* Only defined for 1.4 with digital displays */
2859 	if (edid->revision < 4)
2860 		return;
2861 
2862 	switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
2863 	case DRM_EDID_DIGITAL_DEPTH_6:
2864 		info->bpc = 6;
2865 		break;
2866 	case DRM_EDID_DIGITAL_DEPTH_8:
2867 		info->bpc = 8;
2868 		break;
2869 	case DRM_EDID_DIGITAL_DEPTH_10:
2870 		info->bpc = 10;
2871 		break;
2872 	case DRM_EDID_DIGITAL_DEPTH_12:
2873 		info->bpc = 12;
2874 		break;
2875 	case DRM_EDID_DIGITAL_DEPTH_14:
2876 		info->bpc = 14;
2877 		break;
2878 	case DRM_EDID_DIGITAL_DEPTH_16:
2879 		info->bpc = 16;
2880 		break;
2881 	case DRM_EDID_DIGITAL_DEPTH_UNDEF:
2882 	default:
2883 		info->bpc = 0;
2884 		break;
2885 	}
2886 
2887 	info->color_formats |= DRM_COLOR_FORMAT_RGB444;
2888 	if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
2889 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
2890 	if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
2891 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
2892 }
2893 
2894 /**
2895  * drm_add_edid_modes - add modes from EDID data, if available
2896  * @connector: connector we're probing
2897  * @edid: edid data
2898  *
2899  * Add the specified modes to the connector's mode list.
2900  *
2901  * Return number of modes added or 0 if we couldn't find any.
2902  */
drm_add_edid_modes(struct drm_connector * connector,struct edid * edid)2903 int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
2904 {
2905 	int num_modes = 0;
2906 	u32 quirks;
2907 
2908 	if (edid == NULL) {
2909 		return 0;
2910 	}
2911 	if (!drm_edid_is_valid(edid)) {
2912 		DRM_ERROR("%s: EDID invalid.\n",
2913 			 drm_get_connector_name(connector));
2914 		return 0;
2915 	}
2916 
2917 	quirks = edid_get_quirks(edid);
2918 
2919 	/*
2920 	 * EDID spec says modes should be preferred in this order:
2921 	 * - preferred detailed mode
2922 	 * - other detailed modes from base block
2923 	 * - detailed modes from extension blocks
2924 	 * - CVT 3-byte code modes
2925 	 * - standard timing codes
2926 	 * - established timing codes
2927 	 * - modes inferred from GTF or CVT range information
2928 	 *
2929 	 * We get this pretty much right.
2930 	 *
2931 	 * XXX order for additional mode types in extension blocks?
2932 	 */
2933 	num_modes += add_detailed_modes(connector, edid, quirks);
2934 	num_modes += add_cvt_modes(connector, edid);
2935 	num_modes += add_standard_modes(connector, edid);
2936 	num_modes += add_established_modes(connector, edid);
2937 	if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
2938 		num_modes += add_inferred_modes(connector, edid);
2939 	num_modes += add_cea_modes(connector, edid);
2940 	num_modes += add_alternate_cea_modes(connector, edid);
2941 
2942 	if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
2943 		edid_fixup_preferred(connector, quirks);
2944 
2945 	drm_add_display_info(edid, &connector->display_info);
2946 
2947 	return num_modes;
2948 }
2949 
2950 /**
2951  * drm_add_modes_noedid - add modes for the connectors without EDID
2952  * @connector: connector we're probing
2953  * @hdisplay: the horizontal display limit
2954  * @vdisplay: the vertical display limit
2955  *
2956  * Add the specified modes to the connector's mode list. Only when the
2957  * hdisplay/vdisplay is not beyond the given limit, it will be added.
2958  *
2959  * Return number of modes added or 0 if we couldn't find any.
2960  */
drm_add_modes_noedid(struct drm_connector * connector,int hdisplay,int vdisplay)2961 int drm_add_modes_noedid(struct drm_connector *connector,
2962 			int hdisplay, int vdisplay)
2963 {
2964 	int i, count, num_modes = 0;
2965 	struct drm_display_mode *mode;
2966 	struct drm_device *dev = connector->dev;
2967 
2968 	count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
2969 	if (hdisplay < 0)
2970 		hdisplay = 0;
2971 	if (vdisplay < 0)
2972 		vdisplay = 0;
2973 
2974 	for (i = 0; i < count; i++) {
2975 		const struct drm_display_mode *ptr = &drm_dmt_modes[i];
2976 		if (hdisplay && vdisplay) {
2977 			/*
2978 			 * Only when two are valid, they will be used to check
2979 			 * whether the mode should be added to the mode list of
2980 			 * the connector.
2981 			 */
2982 			if (ptr->hdisplay > hdisplay ||
2983 					ptr->vdisplay > vdisplay)
2984 				continue;
2985 		}
2986 		if (drm_mode_vrefresh(ptr) > 61)
2987 			continue;
2988 		mode = drm_mode_duplicate(dev, ptr);
2989 		if (mode) {
2990 			drm_mode_probed_add(connector, mode);
2991 			num_modes++;
2992 		}
2993 	}
2994 	return num_modes;
2995 }
2996 
2997