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