aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-02-23 21:39:42 -0500
committerDave Airlie <airlied@redhat.com>2013-02-23 21:39:42 -0500
commit28ee46184fc64591e286fa0355845e09c39e2a84 (patch)
tree97f6cb0411cf45f173586275b53c1cfe457a587b
parenta497bfe9dbbc0fbacd61295986372a626e73f452 (diff)
parente3b2e0347e3b3b81cc322b413abf98a349d275df (diff)
Merge branch 'drm/hdmi-for-3.9' of git://anongit.freedesktop.org/tegra/linux into drm-next
Thierry writes: "Remove a duplicate implementation of the CEA VIC lookup and move the CEA and other mode tables to drm_edid.c to make it more difficult to create duplicates of the tables. Add some helpers to pack CEA-861/HDMI AVI, audio and SPD infoframes into binary buffers that can easily be written into hardware registers. A new helper function makes it easy construct an AVI infoframe from a DRM display mode. Convert the Tegra and Radeon drivers to use the new HDMI helpers." * 'drm/hdmi-for-3.9' of git://anongit.freedesktop.org/tegra/linux: drm/radeon: Use generic HDMI infoframe helpers drm/tegra: Use generic HDMI infoframe helpers drm: Add EDID helper documentation drm: Add HDMI infoframe helpers video: Add generic HDMI infoframe helpers drm: Add some missing forward declarations drm: Move mode tables to drm_edid.c drm: Remove duplicate drm_mode_cea_vic()
-rw-r--r--Documentation/DocBook/drm.tmpl4
-rw-r--r--drivers/gpu/drm/Kconfig1
-rw-r--r--drivers/gpu/drm/drm_edid.c798
-rw-r--r--drivers/gpu/drm/drm_edid_modes.h774
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c4
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c2
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c85
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c134
-rw-r--r--drivers/gpu/drm/tegra/Kconfig1
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c226
-rw-r--r--drivers/gpu/drm/tegra/hdmi.h189
-rw-r--r--drivers/video/Kconfig3
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/hdmi.c308
-rw-r--r--include/drm/drm_crtc.h6
-rw-r--r--include/drm/drm_edid.h6
-rw-r--r--include/linux/hdmi.h231
18 files changed, 1506 insertions, 1269 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index a6428ddfcfc2..f9df3b872c16 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2157,6 +2157,10 @@ void intel_crt_init(struct drm_device *dev)
2157!Iinclude/drm/drm_dp_helper.h 2157!Iinclude/drm/drm_dp_helper.h
2158!Edrivers/gpu/drm/drm_dp_helper.c 2158!Edrivers/gpu/drm/drm_dp_helper.c
2159 </sect2> 2159 </sect2>
2160 <sect2>
2161 <title>EDID Helper Functions Reference</title>
2162!Edrivers/gpu/drm/drm_edid.c
2163 </sect2>
2160 </sect1> 2164 </sect1>
2161 2165
2162 <!-- Internals: vertical blanking --> 2166 <!-- Internals: vertical blanking -->
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f8dae851130c..1e82882da9de 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
7menuconfig DRM 7menuconfig DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" 8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU 9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
10 select HDMI
10 select I2C 11 select I2C
11 select I2C_ALGOBIT 12 select I2C_ALGOBIT
12 select DMA_SHARED_BUFFER 13 select DMA_SHARED_BUFFER
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 67aa0dd68250..c194f4e680ad 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -29,11 +29,11 @@
29 */ 29 */
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/hdmi.h>
32#include <linux/i2c.h> 33#include <linux/i2c.h>
33#include <linux/module.h> 34#include <linux/module.h>
34#include <drm/drmP.h> 35#include <drm/drmP.h>
35#include <drm/drm_edid.h> 36#include <drm/drm_edid.h>
36#include "drm_edid_modes.h"
37 37
38#define version_greater(edid, maj, min) \ 38#define version_greater(edid, maj, min) \
39 (((edid)->version > (maj)) || \ 39 (((edid)->version > (maj)) || \
@@ -127,6 +127,746 @@ static struct edid_quirk {
127 { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, 127 { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
128}; 128};
129 129
130/*
131 * Autogenerated from the DMT spec.
132 * This table is copied from xfree86/modes/xf86EdidModes.c.
133 */
134static const struct drm_display_mode drm_dmt_modes[] = {
135 /* 640x350@85Hz */
136 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
137 736, 832, 0, 350, 382, 385, 445, 0,
138 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
139 /* 640x400@85Hz */
140 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
141 736, 832, 0, 400, 401, 404, 445, 0,
142 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
143 /* 720x400@85Hz */
144 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
145 828, 936, 0, 400, 401, 404, 446, 0,
146 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
147 /* 640x480@60Hz */
148 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
149 752, 800, 0, 480, 489, 492, 525, 0,
150 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
151 /* 640x480@72Hz */
152 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
153 704, 832, 0, 480, 489, 492, 520, 0,
154 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
155 /* 640x480@75Hz */
156 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
157 720, 840, 0, 480, 481, 484, 500, 0,
158 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
159 /* 640x480@85Hz */
160 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
161 752, 832, 0, 480, 481, 484, 509, 0,
162 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
163 /* 800x600@56Hz */
164 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
165 896, 1024, 0, 600, 601, 603, 625, 0,
166 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
167 /* 800x600@60Hz */
168 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
169 968, 1056, 0, 600, 601, 605, 628, 0,
170 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
171 /* 800x600@72Hz */
172 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
173 976, 1040, 0, 600, 637, 643, 666, 0,
174 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
175 /* 800x600@75Hz */
176 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
177 896, 1056, 0, 600, 601, 604, 625, 0,
178 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
179 /* 800x600@85Hz */
180 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
181 896, 1048, 0, 600, 601, 604, 631, 0,
182 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
183 /* 800x600@120Hz RB */
184 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
185 880, 960, 0, 600, 603, 607, 636, 0,
186 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
187 /* 848x480@60Hz */
188 { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
189 976, 1088, 0, 480, 486, 494, 517, 0,
190 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
191 /* 1024x768@43Hz, interlace */
192 { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
193 1208, 1264, 0, 768, 768, 772, 817, 0,
194 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
195 DRM_MODE_FLAG_INTERLACE) },
196 /* 1024x768@60Hz */
197 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
198 1184, 1344, 0, 768, 771, 777, 806, 0,
199 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
200 /* 1024x768@70Hz */
201 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
202 1184, 1328, 0, 768, 771, 777, 806, 0,
203 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
204 /* 1024x768@75Hz */
205 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
206 1136, 1312, 0, 768, 769, 772, 800, 0,
207 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
208 /* 1024x768@85Hz */
209 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
210 1168, 1376, 0, 768, 769, 772, 808, 0,
211 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
212 /* 1024x768@120Hz RB */
213 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
214 1104, 1184, 0, 768, 771, 775, 813, 0,
215 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
216 /* 1152x864@75Hz */
217 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
218 1344, 1600, 0, 864, 865, 868, 900, 0,
219 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
220 /* 1280x768@60Hz RB */
221 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
222 1360, 1440, 0, 768, 771, 778, 790, 0,
223 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
224 /* 1280x768@60Hz */
225 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
226 1472, 1664, 0, 768, 771, 778, 798, 0,
227 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
228 /* 1280x768@75Hz */
229 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
230 1488, 1696, 0, 768, 771, 778, 805, 0,
231 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
232 /* 1280x768@85Hz */
233 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
234 1496, 1712, 0, 768, 771, 778, 809, 0,
235 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
236 /* 1280x768@120Hz RB */
237 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
238 1360, 1440, 0, 768, 771, 778, 813, 0,
239 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
240 /* 1280x800@60Hz RB */
241 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
242 1360, 1440, 0, 800, 803, 809, 823, 0,
243 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
244 /* 1280x800@60Hz */
245 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
246 1480, 1680, 0, 800, 803, 809, 831, 0,
247 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
248 /* 1280x800@75Hz */
249 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
250 1488, 1696, 0, 800, 803, 809, 838, 0,
251 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
252 /* 1280x800@85Hz */
253 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
254 1496, 1712, 0, 800, 803, 809, 843, 0,
255 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
256 /* 1280x800@120Hz RB */
257 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
258 1360, 1440, 0, 800, 803, 809, 847, 0,
259 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
260 /* 1280x960@60Hz */
261 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
262 1488, 1800, 0, 960, 961, 964, 1000, 0,
263 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
264 /* 1280x960@85Hz */
265 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
266 1504, 1728, 0, 960, 961, 964, 1011, 0,
267 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
268 /* 1280x960@120Hz RB */
269 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
270 1360, 1440, 0, 960, 963, 967, 1017, 0,
271 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
272 /* 1280x1024@60Hz */
273 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
274 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
275 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
276 /* 1280x1024@75Hz */
277 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
278 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
279 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
280 /* 1280x1024@85Hz */
281 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
282 1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
283 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
284 /* 1280x1024@120Hz RB */
285 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
286 1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
287 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
288 /* 1360x768@60Hz */
289 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
290 1536, 1792, 0, 768, 771, 777, 795, 0,
291 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
292 /* 1360x768@120Hz RB */
293 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
294 1440, 1520, 0, 768, 771, 776, 813, 0,
295 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
296 /* 1400x1050@60Hz RB */
297 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
298 1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
299 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
300 /* 1400x1050@60Hz */
301 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
302 1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
303 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
304 /* 1400x1050@75Hz */
305 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
306 1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
307 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
308 /* 1400x1050@85Hz */
309 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
310 1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
311 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
312 /* 1400x1050@120Hz RB */
313 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
314 1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
315 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
316 /* 1440x900@60Hz RB */
317 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
318 1520, 1600, 0, 900, 903, 909, 926, 0,
319 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
320 /* 1440x900@60Hz */
321 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
322 1672, 1904, 0, 900, 903, 909, 934, 0,
323 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
324 /* 1440x900@75Hz */
325 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
326 1688, 1936, 0, 900, 903, 909, 942, 0,
327 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
328 /* 1440x900@85Hz */
329 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
330 1696, 1952, 0, 900, 903, 909, 948, 0,
331 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
332 /* 1440x900@120Hz RB */
333 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
334 1520, 1600, 0, 900, 903, 909, 953, 0,
335 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
336 /* 1600x1200@60Hz */
337 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
338 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
339 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
340 /* 1600x1200@65Hz */
341 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
342 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
343 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
344 /* 1600x1200@70Hz */
345 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
346 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
347 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
348 /* 1600x1200@75Hz */
349 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
350 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
351 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
352 /* 1600x1200@85Hz */
353 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
354 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
355 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
356 /* 1600x1200@120Hz RB */
357 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
358 1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
359 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
360 /* 1680x1050@60Hz RB */
361 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
362 1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
363 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
364 /* 1680x1050@60Hz */
365 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
366 1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
367 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
368 /* 1680x1050@75Hz */
369 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
370 1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
371 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
372 /* 1680x1050@85Hz */
373 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
374 1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
375 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
376 /* 1680x1050@120Hz RB */
377 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
378 1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
379 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
380 /* 1792x1344@60Hz */
381 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
382 2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
383 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
384 /* 1792x1344@75Hz */
385 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
386 2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
387 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
388 /* 1792x1344@120Hz RB */
389 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
390 1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
391 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
392 /* 1856x1392@60Hz */
393 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
394 2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
395 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
396 /* 1856x1392@75Hz */
397 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
398 2208, 2560, 0, 1392, 1395, 1399, 1500, 0,
399 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
400 /* 1856x1392@120Hz RB */
401 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
402 1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
403 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
404 /* 1920x1200@60Hz RB */
405 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
406 2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
407 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
408 /* 1920x1200@60Hz */
409 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
410 2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
411 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
412 /* 1920x1200@75Hz */
413 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
414 2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
415 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
416 /* 1920x1200@85Hz */
417 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
418 2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
419 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
420 /* 1920x1200@120Hz RB */
421 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
422 2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
423 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
424 /* 1920x1440@60Hz */
425 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
426 2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
427 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
428 /* 1920x1440@75Hz */
429 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
430 2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
431 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
432 /* 1920x1440@120Hz RB */
433 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
434 2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
435 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
436 /* 2560x1600@60Hz RB */
437 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
438 2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
439 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
440 /* 2560x1600@60Hz */
441 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
442 3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
443 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
444 /* 2560x1600@75HZ */
445 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
446 3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
447 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
448 /* 2560x1600@85HZ */
449 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
450 3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
451 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
452 /* 2560x1600@120Hz RB */
453 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
454 2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
455 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
456};
457
458static const struct drm_display_mode edid_est_modes[] = {
459 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
460 968, 1056, 0, 600, 601, 605, 628, 0,
461 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
462 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
463 896, 1024, 0, 600, 601, 603, 625, 0,
464 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
465 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
466 720, 840, 0, 480, 481, 484, 500, 0,
467 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
468 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
469 704, 832, 0, 480, 489, 491, 520, 0,
470 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
471 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
472 768, 864, 0, 480, 483, 486, 525, 0,
473 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
474 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
475 752, 800, 0, 480, 490, 492, 525, 0,
476 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
477 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
478 846, 900, 0, 400, 421, 423, 449, 0,
479 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
480 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
481 846, 900, 0, 400, 412, 414, 449, 0,
482 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
483 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
484 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
485 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
486 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
487 1136, 1312, 0, 768, 769, 772, 800, 0,
488 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
489 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
490 1184, 1328, 0, 768, 771, 777, 806, 0,
491 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
492 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
493 1184, 1344, 0, 768, 771, 777, 806, 0,
494 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
495 { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
496 1208, 1264, 0, 768, 768, 776, 817, 0,
497 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
498 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
499 928, 1152, 0, 624, 625, 628, 667, 0,
500 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
501 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
502 896, 1056, 0, 600, 601, 604, 625, 0,
503 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
504 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
505 976, 1040, 0, 600, 637, 643, 666, 0,
506 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
507 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
508 1344, 1600, 0, 864, 865, 868, 900, 0,
509 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
510};
511
512struct minimode {
513 short w;
514 short h;
515 short r;
516 short rb;
517};
518
519static const struct minimode est3_modes[] = {
520 /* byte 6 */
521 { 640, 350, 85, 0 },
522 { 640, 400, 85, 0 },
523 { 720, 400, 85, 0 },
524 { 640, 480, 85, 0 },
525 { 848, 480, 60, 0 },
526 { 800, 600, 85, 0 },
527 { 1024, 768, 85, 0 },
528 { 1152, 864, 75, 0 },
529 /* byte 7 */
530 { 1280, 768, 60, 1 },
531 { 1280, 768, 60, 0 },
532 { 1280, 768, 75, 0 },
533 { 1280, 768, 85, 0 },
534 { 1280, 960, 60, 0 },
535 { 1280, 960, 85, 0 },
536 { 1280, 1024, 60, 0 },
537 { 1280, 1024, 85, 0 },
538 /* byte 8 */
539 { 1360, 768, 60, 0 },
540 { 1440, 900, 60, 1 },
541 { 1440, 900, 60, 0 },
542 { 1440, 900, 75, 0 },
543 { 1440, 900, 85, 0 },
544 { 1400, 1050, 60, 1 },
545 { 1400, 1050, 60, 0 },
546 { 1400, 1050, 75, 0 },
547 /* byte 9 */
548 { 1400, 1050, 85, 0 },
549 { 1680, 1050, 60, 1 },
550 { 1680, 1050, 60, 0 },
551 { 1680, 1050, 75, 0 },
552 { 1680, 1050, 85, 0 },
553 { 1600, 1200, 60, 0 },
554 { 1600, 1200, 65, 0 },
555 { 1600, 1200, 70, 0 },
556 /* byte 10 */
557 { 1600, 1200, 75, 0 },
558 { 1600, 1200, 85, 0 },
559 { 1792, 1344, 60, 0 },
560 { 1792, 1344, 85, 0 },
561 { 1856, 1392, 60, 0 },
562 { 1856, 1392, 75, 0 },
563 { 1920, 1200, 60, 1 },
564 { 1920, 1200, 60, 0 },
565 /* byte 11 */
566 { 1920, 1200, 75, 0 },
567 { 1920, 1200, 85, 0 },
568 { 1920, 1440, 60, 0 },
569 { 1920, 1440, 75, 0 },
570};
571
572static const struct minimode extra_modes[] = {
573 { 1024, 576, 60, 0 },
574 { 1366, 768, 60, 0 },
575 { 1600, 900, 60, 0 },
576 { 1680, 945, 60, 0 },
577 { 1920, 1080, 60, 0 },
578 { 2048, 1152, 60, 0 },
579 { 2048, 1536, 60, 0 },
580};
581
582/*
583 * Probably taken from CEA-861 spec.
584 * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.
585 */
586static const struct drm_display_mode edid_cea_modes[] = {
587 /* 1 - 640x480@60Hz */
588 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
589 752, 800, 0, 480, 490, 492, 525, 0,
590 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
591 /* 2 - 720x480@60Hz */
592 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
593 798, 858, 0, 480, 489, 495, 525, 0,
594 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
595 /* 3 - 720x480@60Hz */
596 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
597 798, 858, 0, 480, 489, 495, 525, 0,
598 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
599 /* 4 - 1280x720@60Hz */
600 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
601 1430, 1650, 0, 720, 725, 730, 750, 0,
602 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
603 /* 5 - 1920x1080i@60Hz */
604 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
605 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
606 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
607 DRM_MODE_FLAG_INTERLACE) },
608 /* 6 - 1440x480i@60Hz */
609 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
610 1602, 1716, 0, 480, 488, 494, 525, 0,
611 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
612 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
613 /* 7 - 1440x480i@60Hz */
614 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
615 1602, 1716, 0, 480, 488, 494, 525, 0,
616 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
617 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
618 /* 8 - 1440x240@60Hz */
619 { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
620 1602, 1716, 0, 240, 244, 247, 262, 0,
621 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
622 DRM_MODE_FLAG_DBLCLK) },
623 /* 9 - 1440x240@60Hz */
624 { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
625 1602, 1716, 0, 240, 244, 247, 262, 0,
626 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
627 DRM_MODE_FLAG_DBLCLK) },
628 /* 10 - 2880x480i@60Hz */
629 { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
630 3204, 3432, 0, 480, 488, 494, 525, 0,
631 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
632 DRM_MODE_FLAG_INTERLACE) },
633 /* 11 - 2880x480i@60Hz */
634 { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
635 3204, 3432, 0, 480, 488, 494, 525, 0,
636 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
637 DRM_MODE_FLAG_INTERLACE) },
638 /* 12 - 2880x240@60Hz */
639 { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
640 3204, 3432, 0, 240, 244, 247, 262, 0,
641 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
642 /* 13 - 2880x240@60Hz */
643 { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
644 3204, 3432, 0, 240, 244, 247, 262, 0,
645 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
646 /* 14 - 1440x480@60Hz */
647 { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
648 1596, 1716, 0, 480, 489, 495, 525, 0,
649 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
650 /* 15 - 1440x480@60Hz */
651 { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
652 1596, 1716, 0, 480, 489, 495, 525, 0,
653 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
654 /* 16 - 1920x1080@60Hz */
655 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
656 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
657 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
658 /* 17 - 720x576@50Hz */
659 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
660 796, 864, 0, 576, 581, 586, 625, 0,
661 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
662 /* 18 - 720x576@50Hz */
663 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
664 796, 864, 0, 576, 581, 586, 625, 0,
665 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
666 /* 19 - 1280x720@50Hz */
667 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
668 1760, 1980, 0, 720, 725, 730, 750, 0,
669 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
670 /* 20 - 1920x1080i@50Hz */
671 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
672 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
673 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
674 DRM_MODE_FLAG_INTERLACE) },
675 /* 21 - 1440x576i@50Hz */
676 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
677 1590, 1728, 0, 576, 580, 586, 625, 0,
678 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
679 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
680 /* 22 - 1440x576i@50Hz */
681 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
682 1590, 1728, 0, 576, 580, 586, 625, 0,
683 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
684 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
685 /* 23 - 1440x288@50Hz */
686 { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
687 1590, 1728, 0, 288, 290, 293, 312, 0,
688 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
689 DRM_MODE_FLAG_DBLCLK) },
690 /* 24 - 1440x288@50Hz */
691 { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
692 1590, 1728, 0, 288, 290, 293, 312, 0,
693 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
694 DRM_MODE_FLAG_DBLCLK) },
695 /* 25 - 2880x576i@50Hz */
696 { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
697 3180, 3456, 0, 576, 580, 586, 625, 0,
698 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
699 DRM_MODE_FLAG_INTERLACE) },
700 /* 26 - 2880x576i@50Hz */
701 { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
702 3180, 3456, 0, 576, 580, 586, 625, 0,
703 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
704 DRM_MODE_FLAG_INTERLACE) },
705 /* 27 - 2880x288@50Hz */
706 { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
707 3180, 3456, 0, 288, 290, 293, 312, 0,
708 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
709 /* 28 - 2880x288@50Hz */
710 { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
711 3180, 3456, 0, 288, 290, 293, 312, 0,
712 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
713 /* 29 - 1440x576@50Hz */
714 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
715 1592, 1728, 0, 576, 581, 586, 625, 0,
716 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
717 /* 30 - 1440x576@50Hz */
718 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
719 1592, 1728, 0, 576, 581, 586, 625, 0,
720 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
721 /* 31 - 1920x1080@50Hz */
722 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
723 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
724 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
725 /* 32 - 1920x1080@24Hz */
726 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
727 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
728 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
729 /* 33 - 1920x1080@25Hz */
730 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
731 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
732 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
733 /* 34 - 1920x1080@30Hz */
734 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
735 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
736 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
737 /* 35 - 2880x480@60Hz */
738 { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
739 3192, 3432, 0, 480, 489, 495, 525, 0,
740 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
741 /* 36 - 2880x480@60Hz */
742 { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
743 3192, 3432, 0, 480, 489, 495, 525, 0,
744 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
745 /* 37 - 2880x576@50Hz */
746 { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
747 3184, 3456, 0, 576, 581, 586, 625, 0,
748 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
749 /* 38 - 2880x576@50Hz */
750 { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
751 3184, 3456, 0, 576, 581, 586, 625, 0,
752 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
753 /* 39 - 1920x1080i@50Hz */
754 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
755 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
756 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
757 DRM_MODE_FLAG_INTERLACE) },
758 /* 40 - 1920x1080i@100Hz */
759 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
760 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
761 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
762 DRM_MODE_FLAG_INTERLACE) },
763 /* 41 - 1280x720@100Hz */
764 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
765 1760, 1980, 0, 720, 725, 730, 750, 0,
766 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
767 /* 42 - 720x576@100Hz */
768 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
769 796, 864, 0, 576, 581, 586, 625, 0,
770 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
771 /* 43 - 720x576@100Hz */
772 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
773 796, 864, 0, 576, 581, 586, 625, 0,
774 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
775 /* 44 - 1440x576i@100Hz */
776 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
777 1590, 1728, 0, 576, 580, 586, 625, 0,
778 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
779 DRM_MODE_FLAG_DBLCLK) },
780 /* 45 - 1440x576i@100Hz */
781 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
782 1590, 1728, 0, 576, 580, 586, 625, 0,
783 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
784 DRM_MODE_FLAG_DBLCLK) },
785 /* 46 - 1920x1080i@120Hz */
786 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
787 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
788 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
789 DRM_MODE_FLAG_INTERLACE) },
790 /* 47 - 1280x720@120Hz */
791 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
792 1430, 1650, 0, 720, 725, 730, 750, 0,
793 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
794 /* 48 - 720x480@120Hz */
795 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
796 798, 858, 0, 480, 489, 495, 525, 0,
797 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
798 /* 49 - 720x480@120Hz */
799 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
800 798, 858, 0, 480, 489, 495, 525, 0,
801 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
802 /* 50 - 1440x480i@120Hz */
803 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
804 1602, 1716, 0, 480, 488, 494, 525, 0,
805 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
806 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
807 /* 51 - 1440x480i@120Hz */
808 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
809 1602, 1716, 0, 480, 488, 494, 525, 0,
810 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
811 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
812 /* 52 - 720x576@200Hz */
813 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
814 796, 864, 0, 576, 581, 586, 625, 0,
815 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
816 /* 53 - 720x576@200Hz */
817 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
818 796, 864, 0, 576, 581, 586, 625, 0,
819 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
820 /* 54 - 1440x576i@200Hz */
821 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
822 1590, 1728, 0, 576, 580, 586, 625, 0,
823 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
824 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
825 /* 55 - 1440x576i@200Hz */
826 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
827 1590, 1728, 0, 576, 580, 586, 625, 0,
828 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
829 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
830 /* 56 - 720x480@240Hz */
831 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
832 798, 858, 0, 480, 489, 495, 525, 0,
833 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
834 /* 57 - 720x480@240Hz */
835 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
836 798, 858, 0, 480, 489, 495, 525, 0,
837 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
838 /* 58 - 1440x480i@240 */
839 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
840 1602, 1716, 0, 480, 488, 494, 525, 0,
841 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
842 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
843 /* 59 - 1440x480i@240 */
844 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
845 1602, 1716, 0, 480, 488, 494, 525, 0,
846 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
847 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
848 /* 60 - 1280x720@24Hz */
849 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
850 3080, 3300, 0, 720, 725, 730, 750, 0,
851 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
852 /* 61 - 1280x720@25Hz */
853 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
854 3740, 3960, 0, 720, 725, 730, 750, 0,
855 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
856 /* 62 - 1280x720@30Hz */
857 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
858 3080, 3300, 0, 720, 725, 730, 750, 0,
859 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
860 /* 63 - 1920x1080@120Hz */
861 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
862 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
863 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
864 /* 64 - 1920x1080@100Hz */
865 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
866 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
867 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
868};
869
130/*** DDC fetch and block validation ***/ 870/*** DDC fetch and block validation ***/
131 871
132static const u8 edid_header[] = { 872static const u8 edid_header[] = {
@@ -542,7 +1282,7 @@ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
542{ 1282{
543 int i; 1283 int i;
544 1284
545 for (i = 0; i < drm_num_dmt_modes; i++) { 1285 for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
546 const struct drm_display_mode *ptr = &drm_dmt_modes[i]; 1286 const struct drm_display_mode *ptr = &drm_dmt_modes[i];
547 if (hsize != ptr->hdisplay) 1287 if (hsize != ptr->hdisplay)
548 continue; 1288 continue;
@@ -1083,7 +1823,7 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
1083 struct drm_display_mode *newmode; 1823 struct drm_display_mode *newmode;
1084 struct drm_device *dev = connector->dev; 1824 struct drm_device *dev = connector->dev;
1085 1825
1086 for (i = 0; i < drm_num_dmt_modes; i++) { 1826 for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
1087 if (mode_in_range(drm_dmt_modes + i, edid, timing) && 1827 if (mode_in_range(drm_dmt_modes + i, edid, timing) &&
1088 valid_inferred_mode(connector, drm_dmt_modes + i)) { 1828 valid_inferred_mode(connector, drm_dmt_modes + i)) {
1089 newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); 1829 newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
@@ -1118,7 +1858,7 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
1118 struct drm_display_mode *newmode; 1858 struct drm_display_mode *newmode;
1119 struct drm_device *dev = connector->dev; 1859 struct drm_device *dev = connector->dev;
1120 1860
1121 for (i = 0; i < num_extra_modes; i++) { 1861 for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
1122 const struct minimode *m = &extra_modes[i]; 1862 const struct minimode *m = &extra_modes[i];
1123 newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0); 1863 newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
1124 if (!newmode) 1864 if (!newmode)
@@ -1147,7 +1887,7 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
1147 struct drm_device *dev = connector->dev; 1887 struct drm_device *dev = connector->dev;
1148 bool rb = drm_monitor_supports_rb(edid); 1888 bool rb = drm_monitor_supports_rb(edid);
1149 1889
1150 for (i = 0; i < num_extra_modes; i++) { 1890 for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
1151 const struct minimode *m = &extra_modes[i]; 1891 const struct minimode *m = &extra_modes[i];
1152 newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0); 1892 newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
1153 if (!newmode) 1893 if (!newmode)
@@ -1516,16 +2256,19 @@ u8 *drm_find_cea_extension(struct edid *edid)
1516} 2256}
1517EXPORT_SYMBOL(drm_find_cea_extension); 2257EXPORT_SYMBOL(drm_find_cea_extension);
1518 2258
1519/* 2259/**
1520 * Looks for a CEA mode matching given drm_display_mode. 2260 * drm_match_cea_mode - look for a CEA mode matching given mode
1521 * Returns its CEA Video ID code, or 0 if not found. 2261 * @to_match: display mode
2262 *
2263 * Returns the CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
2264 * mode.
1522 */ 2265 */
1523u8 drm_match_cea_mode(struct drm_display_mode *to_match) 2266u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
1524{ 2267{
1525 struct drm_display_mode *cea_mode; 2268 struct drm_display_mode *cea_mode;
1526 u8 mode; 2269 u8 mode;
1527 2270
1528 for (mode = 0; mode < drm_num_cea_modes; mode++) { 2271 for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) {
1529 cea_mode = (struct drm_display_mode *)&edid_cea_modes[mode]; 2272 cea_mode = (struct drm_display_mode *)&edid_cea_modes[mode];
1530 2273
1531 if (drm_mode_equal(to_match, cea_mode)) 2274 if (drm_mode_equal(to_match, cea_mode))
@@ -1545,7 +2288,7 @@ do_cea_modes (struct drm_connector *connector, u8 *db, u8 len)
1545 2288
1546 for (mode = db; mode < db + len; mode++) { 2289 for (mode = db; mode < db + len; mode++) {
1547 cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */ 2290 cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */
1548 if (cea_mode < drm_num_cea_modes) { 2291 if (cea_mode < ARRAY_SIZE(edid_cea_modes)) {
1549 struct drm_display_mode *newmode; 2292 struct drm_display_mode *newmode;
1550 newmode = drm_mode_duplicate(dev, 2293 newmode = drm_mode_duplicate(dev,
1551 &edid_cea_modes[cea_mode]); 2294 &edid_cea_modes[cea_mode]);
@@ -2116,20 +2859,33 @@ int drm_add_modes_noedid(struct drm_connector *connector,
2116EXPORT_SYMBOL(drm_add_modes_noedid); 2859EXPORT_SYMBOL(drm_add_modes_noedid);
2117 2860
2118/** 2861/**
2119 * drm_mode_cea_vic - return the CEA-861 VIC of a given mode 2862 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
2120 * @mode: mode 2863 * data from a DRM display mode
2864 * @frame: HDMI AVI infoframe
2865 * @mode: DRM display mode
2121 * 2866 *
2122 * RETURNS: 2867 * Returns 0 on success or a negative error code on failure.
2123 * The VIC number, 0 in case it's not a CEA-861 mode.
2124 */ 2868 */
2125uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode) 2869int
2870drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
2871 const struct drm_display_mode *mode)
2126{ 2872{
2127 uint8_t i; 2873 int err;
2874
2875 if (!frame || !mode)
2876 return -EINVAL;
2877
2878 err = hdmi_avi_infoframe_init(frame);
2879 if (err < 0)
2880 return err;
2881
2882 frame->video_code = drm_match_cea_mode(mode);
2883 if (!frame->video_code)
2884 return 0;
2128 2885
2129 for (i = 0; i < drm_num_cea_modes; i++) 2886 frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
2130 if (drm_mode_equal(mode, &edid_cea_modes[i])) 2887 frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
2131 return i + 1;
2132 2888
2133 return 0; 2889 return 0;
2134} 2890}
2135EXPORT_SYMBOL(drm_mode_cea_vic); 2891EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
deleted file mode 100644
index 5dbf7d2557b4..000000000000
--- a/drivers/gpu/drm/drm_edid_modes.h
+++ /dev/null
@@ -1,774 +0,0 @@
1/*
2 * Copyright (c) 2007-2008 Intel Corporation
3 * Jesse Barnes <jesse.barnes@intel.com>
4 * Copyright 2010 Red Hat, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26#include <linux/kernel.h>
27#include <drm/drmP.h>
28#include <drm/drm_edid.h>
29
30/*
31 * Autogenerated from the DMT spec.
32 * This table is copied from xfree86/modes/xf86EdidModes.c.
33 */
34static const struct drm_display_mode drm_dmt_modes[] = {
35 /* 640x350@85Hz */
36 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
37 736, 832, 0, 350, 382, 385, 445, 0,
38 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
39 /* 640x400@85Hz */
40 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
41 736, 832, 0, 400, 401, 404, 445, 0,
42 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
43 /* 720x400@85Hz */
44 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
45 828, 936, 0, 400, 401, 404, 446, 0,
46 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
47 /* 640x480@60Hz */
48 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
49 752, 800, 0, 480, 489, 492, 525, 0,
50 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
51 /* 640x480@72Hz */
52 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
53 704, 832, 0, 480, 489, 492, 520, 0,
54 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
55 /* 640x480@75Hz */
56 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
57 720, 840, 0, 480, 481, 484, 500, 0,
58 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
59 /* 640x480@85Hz */
60 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
61 752, 832, 0, 480, 481, 484, 509, 0,
62 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
63 /* 800x600@56Hz */
64 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
65 896, 1024, 0, 600, 601, 603, 625, 0,
66 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
67 /* 800x600@60Hz */
68 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
69 968, 1056, 0, 600, 601, 605, 628, 0,
70 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
71 /* 800x600@72Hz */
72 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
73 976, 1040, 0, 600, 637, 643, 666, 0,
74 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
75 /* 800x600@75Hz */
76 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
77 896, 1056, 0, 600, 601, 604, 625, 0,
78 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
79 /* 800x600@85Hz */
80 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
81 896, 1048, 0, 600, 601, 604, 631, 0,
82 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
83 /* 800x600@120Hz RB */
84 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
85 880, 960, 0, 600, 603, 607, 636, 0,
86 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
87 /* 848x480@60Hz */
88 { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
89 976, 1088, 0, 480, 486, 494, 517, 0,
90 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
91 /* 1024x768@43Hz, interlace */
92 { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
93 1208, 1264, 0, 768, 768, 772, 817, 0,
94 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
95 DRM_MODE_FLAG_INTERLACE) },
96 /* 1024x768@60Hz */
97 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
98 1184, 1344, 0, 768, 771, 777, 806, 0,
99 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
100 /* 1024x768@70Hz */
101 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
102 1184, 1328, 0, 768, 771, 777, 806, 0,
103 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
104 /* 1024x768@75Hz */
105 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
106 1136, 1312, 0, 768, 769, 772, 800, 0,
107 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
108 /* 1024x768@85Hz */
109 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
110 1168, 1376, 0, 768, 769, 772, 808, 0,
111 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
112 /* 1024x768@120Hz RB */
113 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
114 1104, 1184, 0, 768, 771, 775, 813, 0,
115 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
116 /* 1152x864@75Hz */
117 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
118 1344, 1600, 0, 864, 865, 868, 900, 0,
119 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
120 /* 1280x768@60Hz RB */
121 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
122 1360, 1440, 0, 768, 771, 778, 790, 0,
123 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
124 /* 1280x768@60Hz */
125 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
126 1472, 1664, 0, 768, 771, 778, 798, 0,
127 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
128 /* 1280x768@75Hz */
129 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
130 1488, 1696, 0, 768, 771, 778, 805, 0,
131 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
132 /* 1280x768@85Hz */
133 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
134 1496, 1712, 0, 768, 771, 778, 809, 0,
135 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
136 /* 1280x768@120Hz RB */
137 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
138 1360, 1440, 0, 768, 771, 778, 813, 0,
139 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
140 /* 1280x800@60Hz RB */
141 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
142 1360, 1440, 0, 800, 803, 809, 823, 0,
143 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
144 /* 1280x800@60Hz */
145 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
146 1480, 1680, 0, 800, 803, 809, 831, 0,
147 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
148 /* 1280x800@75Hz */
149 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
150 1488, 1696, 0, 800, 803, 809, 838, 0,
151 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
152 /* 1280x800@85Hz */
153 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
154 1496, 1712, 0, 800, 803, 809, 843, 0,
155 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
156 /* 1280x800@120Hz RB */
157 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
158 1360, 1440, 0, 800, 803, 809, 847, 0,
159 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
160 /* 1280x960@60Hz */
161 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
162 1488, 1800, 0, 960, 961, 964, 1000, 0,
163 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
164 /* 1280x960@85Hz */
165 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
166 1504, 1728, 0, 960, 961, 964, 1011, 0,
167 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
168 /* 1280x960@120Hz RB */
169 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
170 1360, 1440, 0, 960, 963, 967, 1017, 0,
171 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
172 /* 1280x1024@60Hz */
173 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
174 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
175 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
176 /* 1280x1024@75Hz */
177 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
178 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
179 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
180 /* 1280x1024@85Hz */
181 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
182 1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
183 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
184 /* 1280x1024@120Hz RB */
185 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
186 1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
187 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
188 /* 1360x768@60Hz */
189 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
190 1536, 1792, 0, 768, 771, 777, 795, 0,
191 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
192 /* 1360x768@120Hz RB */
193 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
194 1440, 1520, 0, 768, 771, 776, 813, 0,
195 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
196 /* 1400x1050@60Hz RB */
197 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
198 1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
199 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
200 /* 1400x1050@60Hz */
201 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
202 1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
203 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
204 /* 1400x1050@75Hz */
205 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
206 1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
207 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
208 /* 1400x1050@85Hz */
209 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
210 1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
211 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
212 /* 1400x1050@120Hz RB */
213 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
214 1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
215 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
216 /* 1440x900@60Hz RB */
217 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
218 1520, 1600, 0, 900, 903, 909, 926, 0,
219 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
220 /* 1440x900@60Hz */
221 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
222 1672, 1904, 0, 900, 903, 909, 934, 0,
223 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
224 /* 1440x900@75Hz */
225 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
226 1688, 1936, 0, 900, 903, 909, 942, 0,
227 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
228 /* 1440x900@85Hz */
229 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
230 1696, 1952, 0, 900, 903, 909, 948, 0,
231 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
232 /* 1440x900@120Hz RB */
233 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
234 1520, 1600, 0, 900, 903, 909, 953, 0,
235 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
236 /* 1600x1200@60Hz */
237 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
238 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
239 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
240 /* 1600x1200@65Hz */
241 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
242 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
243 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
244 /* 1600x1200@70Hz */
245 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
246 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
247 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
248 /* 1600x1200@75Hz */
249 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
250 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
251 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
252 /* 1600x1200@85Hz */
253 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
254 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
255 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
256 /* 1600x1200@120Hz RB */
257 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
258 1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
259 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
260 /* 1680x1050@60Hz RB */
261 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
262 1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
263 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
264 /* 1680x1050@60Hz */
265 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
266 1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
267 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
268 /* 1680x1050@75Hz */
269 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
270 1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
271 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
272 /* 1680x1050@85Hz */
273 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
274 1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
275 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
276 /* 1680x1050@120Hz RB */
277 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
278 1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
279 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
280 /* 1792x1344@60Hz */
281 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
282 2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
283 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
284 /* 1792x1344@75Hz */
285 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
286 2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
287 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
288 /* 1792x1344@120Hz RB */
289 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
290 1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
291 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
292 /* 1856x1392@60Hz */
293 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
294 2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
295 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
296 /* 1856x1392@75Hz */
297 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
298 2208, 2560, 0, 1392, 1395, 1399, 1500, 0,
299 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
300 /* 1856x1392@120Hz RB */
301 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
302 1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
303 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
304 /* 1920x1200@60Hz RB */
305 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
306 2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
307 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
308 /* 1920x1200@60Hz */
309 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
310 2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
311 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
312 /* 1920x1200@75Hz */
313 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
314 2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
315 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
316 /* 1920x1200@85Hz */
317 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
318 2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
319 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
320 /* 1920x1200@120Hz RB */
321 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
322 2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
323 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
324 /* 1920x1440@60Hz */
325 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
326 2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
327 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
328 /* 1920x1440@75Hz */
329 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
330 2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
331 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
332 /* 1920x1440@120Hz RB */
333 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
334 2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
335 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
336 /* 2560x1600@60Hz RB */
337 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
338 2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
339 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
340 /* 2560x1600@60Hz */
341 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
342 3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
343 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
344 /* 2560x1600@75HZ */
345 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
346 3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
347 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
348 /* 2560x1600@85HZ */
349 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
350 3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
351 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
352 /* 2560x1600@120Hz RB */
353 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
354 2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
355 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
356
357};
358static const int drm_num_dmt_modes =
359 sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
360
361static const struct drm_display_mode edid_est_modes[] = {
362 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
363 968, 1056, 0, 600, 601, 605, 628, 0,
364 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
365 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
366 896, 1024, 0, 600, 601, 603, 625, 0,
367 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
368 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
369 720, 840, 0, 480, 481, 484, 500, 0,
370 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
371 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
372 704, 832, 0, 480, 489, 491, 520, 0,
373 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
374 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
375 768, 864, 0, 480, 483, 486, 525, 0,
376 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
377 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
378 752, 800, 0, 480, 490, 492, 525, 0,
379 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
380 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
381 846, 900, 0, 400, 421, 423, 449, 0,
382 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
383 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
384 846, 900, 0, 400, 412, 414, 449, 0,
385 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
386 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
387 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
388 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
389 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
390 1136, 1312, 0, 768, 769, 772, 800, 0,
391 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
392 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
393 1184, 1328, 0, 768, 771, 777, 806, 0,
394 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
395 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
396 1184, 1344, 0, 768, 771, 777, 806, 0,
397 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
398 { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
399 1208, 1264, 0, 768, 768, 776, 817, 0,
400 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
401 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
402 928, 1152, 0, 624, 625, 628, 667, 0,
403 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
404 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
405 896, 1056, 0, 600, 601, 604, 625, 0,
406 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
407 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
408 976, 1040, 0, 600, 637, 643, 666, 0,
409 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
410 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
411 1344, 1600, 0, 864, 865, 868, 900, 0,
412 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
413};
414
415struct minimode {
416 short w;
417 short h;
418 short r;
419 short rb;
420};
421
422static const struct minimode est3_modes[] = {
423 /* byte 6 */
424 { 640, 350, 85, 0 },
425 { 640, 400, 85, 0 },
426 { 720, 400, 85, 0 },
427 { 640, 480, 85, 0 },
428 { 848, 480, 60, 0 },
429 { 800, 600, 85, 0 },
430 { 1024, 768, 85, 0 },
431 { 1152, 864, 75, 0 },
432 /* byte 7 */
433 { 1280, 768, 60, 1 },
434 { 1280, 768, 60, 0 },
435 { 1280, 768, 75, 0 },
436 { 1280, 768, 85, 0 },
437 { 1280, 960, 60, 0 },
438 { 1280, 960, 85, 0 },
439 { 1280, 1024, 60, 0 },
440 { 1280, 1024, 85, 0 },
441 /* byte 8 */
442 { 1360, 768, 60, 0 },
443 { 1440, 900, 60, 1 },
444 { 1440, 900, 60, 0 },
445 { 1440, 900, 75, 0 },
446 { 1440, 900, 85, 0 },
447 { 1400, 1050, 60, 1 },
448 { 1400, 1050, 60, 0 },
449 { 1400, 1050, 75, 0 },
450 /* byte 9 */
451 { 1400, 1050, 85, 0 },
452 { 1680, 1050, 60, 1 },
453 { 1680, 1050, 60, 0 },
454 { 1680, 1050, 75, 0 },
455 { 1680, 1050, 85, 0 },
456 { 1600, 1200, 60, 0 },
457 { 1600, 1200, 65, 0 },
458 { 1600, 1200, 70, 0 },
459 /* byte 10 */
460 { 1600, 1200, 75, 0 },
461 { 1600, 1200, 85, 0 },
462 { 1792, 1344, 60, 0 },
463 { 1792, 1344, 85, 0 },
464 { 1856, 1392, 60, 0 },
465 { 1856, 1392, 75, 0 },
466 { 1920, 1200, 60, 1 },
467 { 1920, 1200, 60, 0 },
468 /* byte 11 */
469 { 1920, 1200, 75, 0 },
470 { 1920, 1200, 85, 0 },
471 { 1920, 1440, 60, 0 },
472 { 1920, 1440, 75, 0 },
473};
474static const int num_est3_modes = ARRAY_SIZE(est3_modes);
475
476static const struct minimode extra_modes[] = {
477 { 1024, 576, 60, 0 },
478 { 1366, 768, 60, 0 },
479 { 1600, 900, 60, 0 },
480 { 1680, 945, 60, 0 },
481 { 1920, 1080, 60, 0 },
482 { 2048, 1152, 60, 0 },
483 { 2048, 1536, 60, 0 },
484};
485static const int num_extra_modes = ARRAY_SIZE(extra_modes);
486
487/*
488 * Probably taken from CEA-861 spec.
489 * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.
490 */
491static const struct drm_display_mode edid_cea_modes[] = {
492 /* 1 - 640x480@60Hz */
493 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
494 752, 800, 0, 480, 490, 492, 525, 0,
495 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
496 /* 2 - 720x480@60Hz */
497 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
498 798, 858, 0, 480, 489, 495, 525, 0,
499 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
500 /* 3 - 720x480@60Hz */
501 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
502 798, 858, 0, 480, 489, 495, 525, 0,
503 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
504 /* 4 - 1280x720@60Hz */
505 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
506 1430, 1650, 0, 720, 725, 730, 750, 0,
507 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
508 /* 5 - 1920x1080i@60Hz */
509 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
510 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
511 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
512 DRM_MODE_FLAG_INTERLACE) },
513 /* 6 - 1440x480i@60Hz */
514 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
515 1602, 1716, 0, 480, 488, 494, 525, 0,
516 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
517 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
518 /* 7 - 1440x480i@60Hz */
519 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
520 1602, 1716, 0, 480, 488, 494, 525, 0,
521 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
522 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
523 /* 8 - 1440x240@60Hz */
524 { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
525 1602, 1716, 0, 240, 244, 247, 262, 0,
526 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
527 DRM_MODE_FLAG_DBLCLK) },
528 /* 9 - 1440x240@60Hz */
529 { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
530 1602, 1716, 0, 240, 244, 247, 262, 0,
531 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
532 DRM_MODE_FLAG_DBLCLK) },
533 /* 10 - 2880x480i@60Hz */
534 { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
535 3204, 3432, 0, 480, 488, 494, 525, 0,
536 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
537 DRM_MODE_FLAG_INTERLACE) },
538 /* 11 - 2880x480i@60Hz */
539 { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
540 3204, 3432, 0, 480, 488, 494, 525, 0,
541 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
542 DRM_MODE_FLAG_INTERLACE) },
543 /* 12 - 2880x240@60Hz */
544 { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
545 3204, 3432, 0, 240, 244, 247, 262, 0,
546 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
547 /* 13 - 2880x240@60Hz */
548 { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
549 3204, 3432, 0, 240, 244, 247, 262, 0,
550 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
551 /* 14 - 1440x480@60Hz */
552 { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
553 1596, 1716, 0, 480, 489, 495, 525, 0,
554 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
555 /* 15 - 1440x480@60Hz */
556 { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
557 1596, 1716, 0, 480, 489, 495, 525, 0,
558 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
559 /* 16 - 1920x1080@60Hz */
560 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
561 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
562 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
563 /* 17 - 720x576@50Hz */
564 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
565 796, 864, 0, 576, 581, 586, 625, 0,
566 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
567 /* 18 - 720x576@50Hz */
568 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
569 796, 864, 0, 576, 581, 586, 625, 0,
570 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
571 /* 19 - 1280x720@50Hz */
572 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
573 1760, 1980, 0, 720, 725, 730, 750, 0,
574 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
575 /* 20 - 1920x1080i@50Hz */
576 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
577 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
578 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
579 DRM_MODE_FLAG_INTERLACE) },
580 /* 21 - 1440x576i@50Hz */
581 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
582 1590, 1728, 0, 576, 580, 586, 625, 0,
583 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
584 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
585 /* 22 - 1440x576i@50Hz */
586 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
587 1590, 1728, 0, 576, 580, 586, 625, 0,
588 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
589 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
590 /* 23 - 1440x288@50Hz */
591 { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
592 1590, 1728, 0, 288, 290, 293, 312, 0,
593 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
594 DRM_MODE_FLAG_DBLCLK) },
595 /* 24 - 1440x288@50Hz */
596 { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
597 1590, 1728, 0, 288, 290, 293, 312, 0,
598 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
599 DRM_MODE_FLAG_DBLCLK) },
600 /* 25 - 2880x576i@50Hz */
601 { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
602 3180, 3456, 0, 576, 580, 586, 625, 0,
603 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
604 DRM_MODE_FLAG_INTERLACE) },
605 /* 26 - 2880x576i@50Hz */
606 { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
607 3180, 3456, 0, 576, 580, 586, 625, 0,
608 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
609 DRM_MODE_FLAG_INTERLACE) },
610 /* 27 - 2880x288@50Hz */
611 { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
612 3180, 3456, 0, 288, 290, 293, 312, 0,
613 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
614 /* 28 - 2880x288@50Hz */
615 { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
616 3180, 3456, 0, 288, 290, 293, 312, 0,
617 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
618 /* 29 - 1440x576@50Hz */
619 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
620 1592, 1728, 0, 576, 581, 586, 625, 0,
621 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
622 /* 30 - 1440x576@50Hz */
623 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
624 1592, 1728, 0, 576, 581, 586, 625, 0,
625 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
626 /* 31 - 1920x1080@50Hz */
627 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
628 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
629 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
630 /* 32 - 1920x1080@24Hz */
631 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
632 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
633 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
634 /* 33 - 1920x1080@25Hz */
635 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
636 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
637 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
638 /* 34 - 1920x1080@30Hz */
639 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
640 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
641 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
642 /* 35 - 2880x480@60Hz */
643 { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
644 3192, 3432, 0, 480, 489, 495, 525, 0,
645 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
646 /* 36 - 2880x480@60Hz */
647 { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
648 3192, 3432, 0, 480, 489, 495, 525, 0,
649 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
650 /* 37 - 2880x576@50Hz */
651 { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
652 3184, 3456, 0, 576, 581, 586, 625, 0,
653 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
654 /* 38 - 2880x576@50Hz */
655 { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
656 3184, 3456, 0, 576, 581, 586, 625, 0,
657 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
658 /* 39 - 1920x1080i@50Hz */
659 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
660 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
661 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
662 DRM_MODE_FLAG_INTERLACE) },
663 /* 40 - 1920x1080i@100Hz */
664 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
665 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
666 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
667 DRM_MODE_FLAG_INTERLACE) },
668 /* 41 - 1280x720@100Hz */
669 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
670 1760, 1980, 0, 720, 725, 730, 750, 0,
671 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
672 /* 42 - 720x576@100Hz */
673 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
674 796, 864, 0, 576, 581, 586, 625, 0,
675 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
676 /* 43 - 720x576@100Hz */
677 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
678 796, 864, 0, 576, 581, 586, 625, 0,
679 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
680 /* 44 - 1440x576i@100Hz */
681 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
682 1590, 1728, 0, 576, 580, 586, 625, 0,
683 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
684 DRM_MODE_FLAG_DBLCLK) },
685 /* 45 - 1440x576i@100Hz */
686 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
687 1590, 1728, 0, 576, 580, 586, 625, 0,
688 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
689 DRM_MODE_FLAG_DBLCLK) },
690 /* 46 - 1920x1080i@120Hz */
691 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
692 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
693 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
694 DRM_MODE_FLAG_INTERLACE) },
695 /* 47 - 1280x720@120Hz */
696 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
697 1430, 1650, 0, 720, 725, 730, 750, 0,
698 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
699 /* 48 - 720x480@120Hz */
700 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
701 798, 858, 0, 480, 489, 495, 525, 0,
702 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
703 /* 49 - 720x480@120Hz */
704 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
705 798, 858, 0, 480, 489, 495, 525, 0,
706 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
707 /* 50 - 1440x480i@120Hz */
708 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
709 1602, 1716, 0, 480, 488, 494, 525, 0,
710 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
711 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
712 /* 51 - 1440x480i@120Hz */
713 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
714 1602, 1716, 0, 480, 488, 494, 525, 0,
715 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
716 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
717 /* 52 - 720x576@200Hz */
718 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
719 796, 864, 0, 576, 581, 586, 625, 0,
720 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
721 /* 53 - 720x576@200Hz */
722 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
723 796, 864, 0, 576, 581, 586, 625, 0,
724 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
725 /* 54 - 1440x576i@200Hz */
726 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
727 1590, 1728, 0, 576, 580, 586, 625, 0,
728 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
729 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
730 /* 55 - 1440x576i@200Hz */
731 { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
732 1590, 1728, 0, 576, 580, 586, 625, 0,
733 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
734 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
735 /* 56 - 720x480@240Hz */
736 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
737 798, 858, 0, 480, 489, 495, 525, 0,
738 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
739 /* 57 - 720x480@240Hz */
740 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
741 798, 858, 0, 480, 489, 495, 525, 0,
742 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
743 /* 58 - 1440x480i@240 */
744 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
745 1602, 1716, 0, 480, 488, 494, 525, 0,
746 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
747 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
748 /* 59 - 1440x480i@240 */
749 { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
750 1602, 1716, 0, 480, 488, 494, 525, 0,
751 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
752 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
753 /* 60 - 1280x720@24Hz */
754 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
755 3080, 3300, 0, 720, 725, 730, 750, 0,
756 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
757 /* 61 - 1280x720@25Hz */
758 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
759 3740, 3960, 0, 720, 725, 730, 750, 0,
760 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
761 /* 62 - 1280x720@30Hz */
762 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
763 3080, 3300, 0, 720, 725, 730, 750, 0,
764 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
765 /* 63 - 1920x1080@120Hz */
766 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
767 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
768 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
769 /* 64 - 1920x1080@100Hz */
770 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
771 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
772 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
773};
774static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 31c0205685ab..f61cb7998c72 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -770,7 +770,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
770 * CEA-861-E - 5.1 Default Encoding Parameters 770 * CEA-861-E - 5.1 Default Encoding Parameters
771 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry 771 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry
772 */ 772 */
773 if (bpp != 18 && drm_mode_cea_vic(adjusted_mode) > 1) 773 if (bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1)
774 intel_dp->color_range = DP_COLOR_RANGE_16_235; 774 intel_dp->color_range = DP_COLOR_RANGE_16_235;
775 else 775 else
776 intel_dp->color_range = 0; 776 intel_dp->color_range = 0;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 83d66602414b..fa8ec4a26041 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -348,7 +348,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
348 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; 348 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
349 } 349 }
350 350
351 avi_if.body.avi.VIC = drm_mode_cea_vic(adjusted_mode); 351 avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode);
352 352
353 intel_set_infoframe(encoder, &avi_if); 353 intel_set_infoframe(encoder, &avi_if);
354} 354}
@@ -781,7 +781,7 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
781 if (intel_hdmi->color_range_auto) { 781 if (intel_hdmi->color_range_auto) {
782 /* See CEA-861-E - 5.1 Default Encoding Parameters */ 782 /* See CEA-861-E - 5.1 Default Encoding Parameters */
783 if (intel_hdmi->has_hdmi_sink && 783 if (intel_hdmi->has_hdmi_sink &&
784 drm_mode_cea_vic(adjusted_mode) > 1) 784 drm_match_cea_mode(adjusted_mode) > 1)
785 intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; 785 intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235;
786 else 786 else
787 intel_hdmi->color_range = 0; 787 intel_hdmi->color_range = 0;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 33b46d9694ea..d07a8cdf998e 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1077,7 +1077,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
1077 if (intel_sdvo->color_range_auto) { 1077 if (intel_sdvo->color_range_auto) {
1078 /* See CEA-861-E - 5.1 Default Encoding Parameters */ 1078 /* See CEA-861-E - 5.1 Default Encoding Parameters */
1079 if (intel_sdvo->has_hdmi_monitor && 1079 if (intel_sdvo->has_hdmi_monitor &&
1080 drm_mode_cea_vic(adjusted_mode) > 1) 1080 drm_match_cea_mode(adjusted_mode) > 1)
1081 intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235; 1081 intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235;
1082 else 1082 else
1083 intel_sdvo->color_range = 0; 1083 intel_sdvo->color_range = 0;
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 327c08b54180..4fdecc2b4040 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -24,6 +24,7 @@
24 * Authors: Christian König 24 * Authors: Christian König
25 * Rafał Miłecki 25 * Rafał Miłecki
26 */ 26 */
27#include <linux/hdmi.h>
27#include <drm/drmP.h> 28#include <drm/drmP.h>
28#include <drm/radeon_drm.h> 29#include <drm/radeon_drm.h>
29#include "radeon.h" 30#include "radeon.h"
@@ -54,79 +55,18 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc
54} 55}
55 56
56/* 57/*
57 * calculate the crc for a given info frame
58 */
59static void evergreen_hdmi_infoframe_checksum(uint8_t packetType,
60 uint8_t versionNumber,
61 uint8_t length,
62 uint8_t *frame)
63{
64 int i;
65 frame[0] = packetType + versionNumber + length;
66 for (i = 1; i <= length; i++)
67 frame[0] += frame[i];
68 frame[0] = 0x100 - frame[0];
69}
70
71/*
72 * build a HDMI Video Info Frame 58 * build a HDMI Video Info Frame
73 */ 59 */
74static void evergreen_hdmi_videoinfoframe( 60static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
75 struct drm_encoder *encoder, 61 void *buffer, size_t size)
76 uint8_t color_format,
77 int active_information_present,
78 uint8_t active_format_aspect_ratio,
79 uint8_t scan_information,
80 uint8_t colorimetry,
81 uint8_t ex_colorimetry,
82 uint8_t quantization,
83 int ITC,
84 uint8_t picture_aspect_ratio,
85 uint8_t video_format_identification,
86 uint8_t pixel_repetition,
87 uint8_t non_uniform_picture_scaling,
88 uint8_t bar_info_data_valid,
89 uint16_t top_bar,
90 uint16_t bottom_bar,
91 uint16_t left_bar,
92 uint16_t right_bar
93)
94{ 62{
95 struct drm_device *dev = encoder->dev; 63 struct drm_device *dev = encoder->dev;
96 struct radeon_device *rdev = dev->dev_private; 64 struct radeon_device *rdev = dev->dev_private;
97 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 65 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
98 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 66 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
99 uint32_t offset = dig->afmt->offset; 67 uint32_t offset = dig->afmt->offset;
68 uint8_t *frame = buffer + 3;
100 69
101 uint8_t frame[14];
102
103 frame[0x0] = 0;
104 frame[0x1] =
105 (scan_information & 0x3) |
106 ((bar_info_data_valid & 0x3) << 2) |
107 ((active_information_present & 0x1) << 4) |
108 ((color_format & 0x3) << 5);
109 frame[0x2] =
110 (active_format_aspect_ratio & 0xF) |
111 ((picture_aspect_ratio & 0x3) << 4) |
112 ((colorimetry & 0x3) << 6);
113 frame[0x3] =
114 (non_uniform_picture_scaling & 0x3) |
115 ((quantization & 0x3) << 2) |
116 ((ex_colorimetry & 0x7) << 4) |
117 ((ITC & 0x1) << 7);
118 frame[0x4] = (video_format_identification & 0x7F);
119 frame[0x5] = (pixel_repetition & 0xF);
120 frame[0x6] = (top_bar & 0xFF);
121 frame[0x7] = (top_bar >> 8);
122 frame[0x8] = (bottom_bar & 0xFF);
123 frame[0x9] = (bottom_bar >> 8);
124 frame[0xA] = (left_bar & 0xFF);
125 frame[0xB] = (left_bar >> 8);
126 frame[0xC] = (right_bar & 0xFF);
127 frame[0xD] = (right_bar >> 8);
128
129 evergreen_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
130 /* Our header values (type, version, length) should be alright, Intel 70 /* Our header values (type, version, length) should be alright, Intel
131 * is using the same. Checksum function also seems to be OK, it works 71 * is using the same. Checksum function also seems to be OK, it works
132 * fine for audio infoframe. However calculated value is always lower 72 * fine for audio infoframe. However calculated value is always lower
@@ -154,7 +94,10 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
154 struct radeon_device *rdev = dev->dev_private; 94 struct radeon_device *rdev = dev->dev_private;
155 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 95 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
156 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 96 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
97 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
98 struct hdmi_avi_infoframe frame;
157 uint32_t offset; 99 uint32_t offset;
100 ssize_t err;
158 101
159 /* Silent, r600_hdmi_enable will raise WARN for us */ 102 /* Silent, r600_hdmi_enable will raise WARN for us */
160 if (!dig->afmt->enabled) 103 if (!dig->afmt->enabled)
@@ -200,9 +143,19 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
200 143
201 WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */ 144 WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */
202 145
203 evergreen_hdmi_videoinfoframe(encoder, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
204 0, 0, 0, 0, 0, 0); 147 if (err < 0) {
148 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
149 return;
150 }
151
152 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
153 if (err < 0) {
154 DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
155 return;
156 }
205 157
158 evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
206 evergreen_hdmi_update_ACR(encoder, mode->clock); 159 evergreen_hdmi_update_ACR(encoder, mode->clock);
207 160
208 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ 161 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 95970ec47c45..21ecc0e12dc4 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -23,6 +23,7 @@
23 * 23 *
24 * Authors: Christian König 24 * Authors: Christian König
25 */ 25 */
26#include <linux/hdmi.h>
26#include <drm/drmP.h> 27#include <drm/drmP.h>
27#include <drm/radeon_drm.h> 28#include <drm/radeon_drm.h>
28#include "radeon.h" 29#include "radeon.h"
@@ -121,79 +122,18 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
121} 122}
122 123
123/* 124/*
124 * calculate the crc for a given info frame
125 */
126static void r600_hdmi_infoframe_checksum(uint8_t packetType,
127 uint8_t versionNumber,
128 uint8_t length,
129 uint8_t *frame)
130{
131 int i;
132 frame[0] = packetType + versionNumber + length;
133 for (i = 1; i <= length; i++)
134 frame[0] += frame[i];
135 frame[0] = 0x100 - frame[0];
136}
137
138/*
139 * build a HDMI Video Info Frame 125 * build a HDMI Video Info Frame
140 */ 126 */
141static void r600_hdmi_videoinfoframe( 127static void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
142 struct drm_encoder *encoder, 128 void *buffer, size_t size)
143 enum r600_hdmi_color_format color_format,
144 int active_information_present,
145 uint8_t active_format_aspect_ratio,
146 uint8_t scan_information,
147 uint8_t colorimetry,
148 uint8_t ex_colorimetry,
149 uint8_t quantization,
150 int ITC,
151 uint8_t picture_aspect_ratio,
152 uint8_t video_format_identification,
153 uint8_t pixel_repetition,
154 uint8_t non_uniform_picture_scaling,
155 uint8_t bar_info_data_valid,
156 uint16_t top_bar,
157 uint16_t bottom_bar,
158 uint16_t left_bar,
159 uint16_t right_bar
160)
161{ 129{
162 struct drm_device *dev = encoder->dev; 130 struct drm_device *dev = encoder->dev;
163 struct radeon_device *rdev = dev->dev_private; 131 struct radeon_device *rdev = dev->dev_private;
164 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 132 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
165 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 133 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
166 uint32_t offset = dig->afmt->offset; 134 uint32_t offset = dig->afmt->offset;
135 uint8_t *frame = buffer + 3;
167 136
168 uint8_t frame[14];
169
170 frame[0x0] = 0;
171 frame[0x1] =
172 (scan_information & 0x3) |
173 ((bar_info_data_valid & 0x3) << 2) |
174 ((active_information_present & 0x1) << 4) |
175 ((color_format & 0x3) << 5);
176 frame[0x2] =
177 (active_format_aspect_ratio & 0xF) |
178 ((picture_aspect_ratio & 0x3) << 4) |
179 ((colorimetry & 0x3) << 6);
180 frame[0x3] =
181 (non_uniform_picture_scaling & 0x3) |
182 ((quantization & 0x3) << 2) |
183 ((ex_colorimetry & 0x7) << 4) |
184 ((ITC & 0x1) << 7);
185 frame[0x4] = (video_format_identification & 0x7F);
186 frame[0x5] = (pixel_repetition & 0xF);
187 frame[0x6] = (top_bar & 0xFF);
188 frame[0x7] = (top_bar >> 8);
189 frame[0x8] = (bottom_bar & 0xFF);
190 frame[0x9] = (bottom_bar >> 8);
191 frame[0xA] = (left_bar & 0xFF);
192 frame[0xB] = (left_bar >> 8);
193 frame[0xC] = (right_bar & 0xFF);
194 frame[0xD] = (right_bar >> 8);
195
196 r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
197 /* Our header values (type, version, length) should be alright, Intel 137 /* Our header values (type, version, length) should be alright, Intel
198 * is using the same. Checksum function also seems to be OK, it works 138 * is using the same. Checksum function also seems to be OK, it works
199 * fine for audio infoframe. However calculated value is always lower 139 * fine for audio infoframe. However calculated value is always lower
@@ -215,39 +155,15 @@ static void r600_hdmi_videoinfoframe(
215/* 155/*
216 * build a Audio Info Frame 156 * build a Audio Info Frame
217 */ 157 */
218static void r600_hdmi_audioinfoframe( 158static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder,
219 struct drm_encoder *encoder, 159 const void *buffer, size_t size)
220 uint8_t channel_count,
221 uint8_t coding_type,
222 uint8_t sample_size,
223 uint8_t sample_frequency,
224 uint8_t format,
225 uint8_t channel_allocation,
226 uint8_t level_shift,
227 int downmix_inhibit
228)
229{ 160{
230 struct drm_device *dev = encoder->dev; 161 struct drm_device *dev = encoder->dev;
231 struct radeon_device *rdev = dev->dev_private; 162 struct radeon_device *rdev = dev->dev_private;
232 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 163 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
233 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 164 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
234 uint32_t offset = dig->afmt->offset; 165 uint32_t offset = dig->afmt->offset;
235 166 const u8 *frame = buffer + 3;
236 uint8_t frame[11];
237
238 frame[0x0] = 0;
239 frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
240 frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
241 frame[0x3] = format;
242 frame[0x4] = channel_allocation;
243 frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
244 frame[0x6] = 0;
245 frame[0x7] = 0;
246 frame[0x8] = 0;
247 frame[0x9] = 0;
248 frame[0xA] = 0;
249
250 r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
251 167
252 WREG32(HDMI0_AUDIO_INFO0 + offset, 168 WREG32(HDMI0_AUDIO_INFO0 + offset,
253 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); 169 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -320,7 +236,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
320 struct radeon_device *rdev = dev->dev_private; 236 struct radeon_device *rdev = dev->dev_private;
321 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 237 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
322 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 238 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
239 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
240 struct hdmi_avi_infoframe frame;
323 uint32_t offset; 241 uint32_t offset;
242 ssize_t err;
324 243
325 /* Silent, r600_hdmi_enable will raise WARN for us */ 244 /* Silent, r600_hdmi_enable will raise WARN for us */
326 if (!dig->afmt->enabled) 245 if (!dig->afmt->enabled)
@@ -371,9 +290,19 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
371 290
372 WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ 291 WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */
373 292
374 r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, 293 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
375 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 294 if (err < 0) {
295 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
296 return;
297 }
376 298
299 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
300 if (err < 0) {
301 DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
302 return;
303 }
304
305 r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
377 r600_hdmi_update_ACR(encoder, mode->clock); 306 r600_hdmi_update_ACR(encoder, mode->clock);
378 307
379 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ 308 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
@@ -395,8 +324,11 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
395 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 324 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
396 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 325 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
397 struct r600_audio audio = r600_audio_status(rdev); 326 struct r600_audio audio = r600_audio_status(rdev);
327 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
328 struct hdmi_audio_infoframe frame;
398 uint32_t offset; 329 uint32_t offset;
399 uint32_t iec; 330 uint32_t iec;
331 ssize_t err;
400 332
401 if (!dig->afmt || !dig->afmt->enabled) 333 if (!dig->afmt || !dig->afmt->enabled)
402 return; 334 return;
@@ -462,9 +394,21 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
462 iec |= 0x5 << 16; 394 iec |= 0x5 << 16;
463 WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f); 395 WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f);
464 396
465 r600_hdmi_audioinfoframe(encoder, audio.channels - 1, 0, 0, 0, 0, 0, 0, 397 err = hdmi_audio_infoframe_init(&frame);
466 0); 398 if (err < 0) {
399 DRM_ERROR("failed to setup audio infoframe\n");
400 return;
401 }
402
403 frame.channels = audio.channels;
404
405 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
406 if (err < 0) {
407 DRM_ERROR("failed to pack audio infoframe\n");
408 return;
409 }
467 410
411 r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer));
468 r600_hdmi_audio_workaround(encoder); 412 r600_hdmi_audio_workaround(encoder);
469} 413}
470 414
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index be1daf7344d3..c92955df0658 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -4,6 +4,7 @@ config DRM_TEGRA
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 select DRM_GEM_CMA_HELPER 5 select DRM_GEM_CMA_HELPER
6 select DRM_KMS_CMA_HELPER 6 select DRM_KMS_CMA_HELPER
7 select DRM_HDMI
7 select FB_CFB_FILLRECT 8 select FB_CFB_FILLRECT
8 select FB_CFB_COPYAREA 9 select FB_CFB_COPYAREA
9 select FB_CFB_IMAGEBLIT 10 select FB_CFB_IMAGEBLIT
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index e060c7e6434d..0daee8e2578b 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -10,6 +10,7 @@
10#include <linux/clk.h> 10#include <linux/clk.h>
11#include <linux/debugfs.h> 11#include <linux/debugfs.h>
12#include <linux/gpio.h> 12#include <linux/gpio.h>
13#include <linux/hdmi.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/of.h> 15#include <linux/of.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
@@ -17,6 +18,8 @@
17 18
18#include <mach/clk.h> 19#include <mach/clk.h>
19 20
21#include <drm/drm_edid.h>
22
20#include "hdmi.h" 23#include "hdmi.h"
21#include "drm.h" 24#include "drm.h"
22#include "dc.h" 25#include "dc.h"
@@ -401,54 +404,65 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi, unsigned int pclk)
401 return 0; 404 return 0;
402} 405}
403 406
404static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, 407static inline unsigned long tegra_hdmi_subpack(const u8 *ptr, size_t size)
405 unsigned int offset, u8 type,
406 u8 version, void *data, size_t size)
407{ 408{
408 unsigned long value; 409 unsigned long value = 0;
409 u8 *ptr = data;
410 u32 subpack[2];
411 size_t i; 410 size_t i;
412 u8 csum;
413 411
414 /* first byte of data is the checksum */ 412 for (i = size; i > 0; i--)
415 csum = type + version + size - 1; 413 value = (value << 8) | ptr[i - 1];
416 414
417 for (i = 1; i < size; i++) 415 return value;
418 csum += ptr[i]; 416}
419 417
420 ptr[0] = 0x100 - csum; 418static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, const void *data,
419 size_t size)
420{
421 const u8 *ptr = data;
422 unsigned long offset;
423 unsigned long value;
424 size_t i, j;
421 425
422 value = INFOFRAME_HEADER_TYPE(type) | 426 switch (ptr[0]) {
423 INFOFRAME_HEADER_VERSION(version) | 427 case HDMI_INFOFRAME_TYPE_AVI:
424 INFOFRAME_HEADER_LEN(size - 1); 428 offset = HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER;
425 tegra_hdmi_writel(hdmi, value, offset); 429 break;
426 430
427 /* The audio inforame only has one set of subpack registers. The hdmi 431 case HDMI_INFOFRAME_TYPE_AUDIO:
428 * block pads the rest of the data as per the spec so we have to fixup 432 offset = HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER;
429 * the length before filling in the subpacks. 433 break;
430 */
431 if (offset == HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER)
432 size = 6;
433 434
434 /* each subpack 7 bytes devided into: 435 case HDMI_INFOFRAME_TYPE_VENDOR:
435 * subpack_low - bytes 0 - 3 436 offset = HDMI_NV_PDISP_HDMI_GENERIC_HEADER;
436 * subpack_high - bytes 4 - 6 (with byte 7 padded to 0x00) 437 break;
437 */ 438
438 for (i = 0; i < size; i++) { 439 default:
439 size_t index = i % 7; 440 dev_err(hdmi->dev, "unsupported infoframe type: %02x\n",
441 ptr[0]);
442 return;
443 }
444
445 value = INFOFRAME_HEADER_TYPE(ptr[0]) |
446 INFOFRAME_HEADER_VERSION(ptr[1]) |
447 INFOFRAME_HEADER_LEN(ptr[2]);
448 tegra_hdmi_writel(hdmi, value, offset);
449 offset++;
440 450
441 if (index == 0) 451 /*
442 memset(subpack, 0x0, sizeof(subpack)); 452 * Each subpack contains 7 bytes, divided into:
453 * - subpack_low: bytes 0 - 3
454 * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00)
455 */
456 for (i = 3, j = 0; i < size; i += 7, j += 8) {
457 size_t rem = size - i, num = min_t(size_t, rem, 4);
443 458
444 ((u8 *)subpack)[index] = ptr[i]; 459 value = tegra_hdmi_subpack(&ptr[i], num);
460 tegra_hdmi_writel(hdmi, value, offset++);
445 461
446 if (index == 6 || (i + 1 == size)) { 462 num = min_t(size_t, rem - num, 3);
447 unsigned int reg = offset + 1 + (i / 7) * 2;
448 463
449 tegra_hdmi_writel(hdmi, subpack[0], reg); 464 value = tegra_hdmi_subpack(&ptr[i + 4], num);
450 tegra_hdmi_writel(hdmi, subpack[1], reg + 1); 465 tegra_hdmi_writel(hdmi, value, offset++);
451 }
452 } 466 }
453} 467}
454 468
@@ -456,9 +470,8 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
456 struct drm_display_mode *mode) 470 struct drm_display_mode *mode)
457{ 471{
458 struct hdmi_avi_infoframe frame; 472 struct hdmi_avi_infoframe frame;
459 unsigned int h_front_porch; 473 u8 buffer[17];
460 unsigned int hsize = 16; 474 ssize_t err;
461 unsigned int vsize = 9;
462 475
463 if (hdmi->dvi) { 476 if (hdmi->dvi) {
464 tegra_hdmi_writel(hdmi, 0, 477 tegra_hdmi_writel(hdmi, 0,
@@ -466,69 +479,19 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
466 return; 479 return;
467 } 480 }
468 481
469 h_front_porch = mode->hsync_start - mode->hdisplay; 482 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
470 memset(&frame, 0, sizeof(frame)); 483 if (err < 0) {
471 frame.r = HDMI_AVI_R_SAME; 484 dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err);
472 485 return;
473 switch (mode->vdisplay) { 486 }
474 case 480:
475 if (mode->hdisplay == 640) {
476 frame.m = HDMI_AVI_M_4_3;
477 frame.vic = 1;
478 } else {
479 frame.m = HDMI_AVI_M_16_9;
480 frame.vic = 3;
481 }
482 break;
483
484 case 576:
485 if (((hsize * 10) / vsize) > 14) {
486 frame.m = HDMI_AVI_M_16_9;
487 frame.vic = 18;
488 } else {
489 frame.m = HDMI_AVI_M_4_3;
490 frame.vic = 17;
491 }
492 break;
493
494 case 720:
495 case 1470: /* stereo mode */
496 frame.m = HDMI_AVI_M_16_9;
497
498 if (h_front_porch == 110)
499 frame.vic = 4;
500 else
501 frame.vic = 19;
502 break;
503
504 case 1080:
505 case 2205: /* stereo mode */
506 frame.m = HDMI_AVI_M_16_9;
507
508 switch (h_front_porch) {
509 case 88:
510 frame.vic = 16;
511 break;
512
513 case 528:
514 frame.vic = 31;
515 break;
516
517 default:
518 frame.vic = 32;
519 break;
520 }
521 break;
522 487
523 default: 488 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
524 frame.m = HDMI_AVI_M_16_9; 489 if (err < 0) {
525 frame.vic = 0; 490 dev_err(hdmi->dev, "failed to pack AVI infoframe: %zd\n", err);
526 break; 491 return;
527 } 492 }
528 493
529 tegra_hdmi_write_infopack(hdmi, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER, 494 tegra_hdmi_write_infopack(hdmi, buffer, err);
530 HDMI_INFOFRAME_TYPE_AVI, HDMI_AVI_VERSION,
531 &frame, sizeof(frame));
532 495
533 tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE, 496 tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
534 HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 497 HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
@@ -537,6 +500,8 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
537static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi) 500static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
538{ 501{
539 struct hdmi_audio_infoframe frame; 502 struct hdmi_audio_infoframe frame;
503 u8 buffer[14];
504 ssize_t err;
540 505
541 if (hdmi->dvi) { 506 if (hdmi->dvi) {
542 tegra_hdmi_writel(hdmi, 0, 507 tegra_hdmi_writel(hdmi, 0,
@@ -544,14 +509,29 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
544 return; 509 return;
545 } 510 }
546 511
547 memset(&frame, 0, sizeof(frame)); 512 err = hdmi_audio_infoframe_init(&frame);
548 frame.cc = HDMI_AUDIO_CC_2; 513 if (err < 0) {
514 dev_err(hdmi->dev, "failed to initialize audio infoframe: %d\n",
515 err);
516 return;
517 }
518
519 frame.channels = 2;
520
521 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
522 if (err < 0) {
523 dev_err(hdmi->dev, "failed to pack audio infoframe: %zd\n",
524 err);
525 return;
526 }
549 527
550 tegra_hdmi_write_infopack(hdmi, 528 /*
551 HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER, 529 * The audio infoframe has only one set of subpack registers, so the
552 HDMI_INFOFRAME_TYPE_AUDIO, 530 * infoframe needs to be truncated. One set of subpack registers can
553 HDMI_AUDIO_VERSION, 531 * contain 7 bytes. Including the 3 byte header only the first 10
554 &frame, sizeof(frame)); 532 * bytes can be programmed.
533 */
534 tegra_hdmi_write_infopack(hdmi, buffer, min(10, err));
555 535
556 tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE, 536 tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
557 HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 537 HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
@@ -559,8 +539,10 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
559 539
560static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi) 540static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
561{ 541{
562 struct hdmi_stereo_infoframe frame; 542 struct hdmi_vendor_infoframe frame;
563 unsigned long value; 543 unsigned long value;
544 u8 buffer[10];
545 ssize_t err;
564 546
565 if (!hdmi->stereo) { 547 if (!hdmi->stereo) {
566 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 548 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
@@ -570,22 +552,32 @@ static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
570 } 552 }
571 553
572 memset(&frame, 0, sizeof(frame)); 554 memset(&frame, 0, sizeof(frame));
573 frame.regid0 = 0x03; 555
574 frame.regid1 = 0x0c; 556 frame.type = HDMI_INFOFRAME_TYPE_VENDOR;
575 frame.regid2 = 0x00; 557 frame.version = 0x01;
576 frame.hdmi_video_format = 2; 558 frame.length = 6;
559
560 frame.data[0] = 0x03; /* regid0 */
561 frame.data[1] = 0x0c; /* regid1 */
562 frame.data[2] = 0x00; /* regid2 */
563 frame.data[3] = 0x02 << 5; /* video format */
577 564
578 /* TODO: 74 MHz limit? */ 565 /* TODO: 74 MHz limit? */
579 if (1) { 566 if (1) {
580 frame._3d_structure = 0; 567 frame.data[4] = 0x00 << 4; /* 3D structure */
581 } else { 568 } else {
582 frame._3d_structure = 8; 569 frame.data[4] = 0x08 << 4; /* 3D structure */
583 frame._3d_ext_data = 0; 570 frame.data[5] = 0x00 << 4; /* 3D ext. data */
571 }
572
573 err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
574 if (err < 0) {
575 dev_err(hdmi->dev, "failed to pack vendor infoframe: %zd\n",
576 err);
577 return;
584 } 578 }
585 579
586 tegra_hdmi_write_infopack(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_HEADER, 580 tegra_hdmi_write_infopack(hdmi, buffer, err);
587 HDMI_INFOFRAME_TYPE_VENDOR,
588 HDMI_VENDOR_VERSION, &frame, 6);
589 581
590 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 582 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
591 value |= GENERIC_CTRL_ENABLE; 583 value |= GENERIC_CTRL_ENABLE;
diff --git a/drivers/gpu/drm/tegra/hdmi.h b/drivers/gpu/drm/tegra/hdmi.h
index 1477f36eb45a..52ac36e08ccb 100644
--- a/drivers/gpu/drm/tegra/hdmi.h
+++ b/drivers/gpu/drm/tegra/hdmi.h
@@ -10,195 +10,6 @@
10#ifndef TEGRA_HDMI_H 10#ifndef TEGRA_HDMI_H
11#define TEGRA_HDMI_H 1 11#define TEGRA_HDMI_H 1
12 12
13#define HDMI_INFOFRAME_TYPE_VENDOR 0x81
14#define HDMI_INFOFRAME_TYPE_AVI 0x82
15#define HDMI_INFOFRAME_TYPE_SPD 0x83
16#define HDMI_INFOFRAME_TYPE_AUDIO 0x84
17#define HDMI_INFOFRAME_TYPE_MPEG_SRC 0x85
18#define HDMI_INFOFRAME_TYPE_NTSC_VBI 0x86
19
20/* all fields little endian */
21struct hdmi_avi_infoframe {
22 /* PB0 */
23 u8 csum;
24
25 /* PB1 */
26 unsigned s:2; /* scan information */
27 unsigned b:2; /* bar info data valid */
28 unsigned a:1; /* active info present */
29 unsigned y:2; /* RGB or YCbCr */
30 unsigned res1:1;
31
32 /* PB2 */
33 unsigned r:4; /* active format aspect ratio */
34 unsigned m:2; /* picture aspect ratio */
35 unsigned c:2; /* colorimetry */
36
37 /* PB3 */
38 unsigned sc:2; /* scan information */
39 unsigned q:2; /* quantization range */
40 unsigned ec:3; /* extended colorimetry */
41 unsigned itc:1; /* it content */
42
43 /* PB4 */
44 unsigned vic:7; /* video format id code */
45 unsigned res4:1;
46
47 /* PB5 */
48 unsigned pr:4; /* pixel repetition factor */
49 unsigned cn:2; /* it content type*/
50 unsigned yq:2; /* ycc quantization range */
51
52 /* PB6-7 */
53 u16 top_bar_end_line;
54
55 /* PB8-9 */
56 u16 bot_bar_start_line;
57
58 /* PB10-11 */
59 u16 left_bar_end_pixel;
60
61 /* PB12-13 */
62 u16 right_bar_start_pixel;
63} __packed;
64
65#define HDMI_AVI_VERSION 0x02
66
67#define HDMI_AVI_Y_RGB 0x0
68#define HDMI_AVI_Y_YCBCR_422 0x1
69#define HDMI_AVI_Y_YCBCR_444 0x2
70
71#define HDMI_AVI_B_VERT 0x1
72#define HDMI_AVI_B_HORIZ 0x2
73
74#define HDMI_AVI_S_NONE 0x0
75#define HDMI_AVI_S_OVERSCAN 0x1
76#define HDMI_AVI_S_UNDERSCAN 0x2
77
78#define HDMI_AVI_C_NONE 0x0
79#define HDMI_AVI_C_SMPTE 0x1
80#define HDMI_AVI_C_ITU_R 0x2
81#define HDMI_AVI_C_EXTENDED 0x4
82
83#define HDMI_AVI_M_4_3 0x1
84#define HDMI_AVI_M_16_9 0x2
85
86#define HDMI_AVI_R_SAME 0x8
87#define HDMI_AVI_R_4_3_CENTER 0x9
88#define HDMI_AVI_R_16_9_CENTER 0xa
89#define HDMI_AVI_R_14_9_CENTER 0xb
90
91/* all fields little endian */
92struct hdmi_audio_infoframe {
93 /* PB0 */
94 u8 csum;
95
96 /* PB1 */
97 unsigned cc:3; /* channel count */
98 unsigned res1:1;
99 unsigned ct:4; /* coding type */
100
101 /* PB2 */
102 unsigned ss:2; /* sample size */
103 unsigned sf:3; /* sample frequency */
104 unsigned res2:3;
105
106 /* PB3 */
107 unsigned cxt:5; /* coding extention type */
108 unsigned res3:3;
109
110 /* PB4 */
111 u8 ca; /* channel/speaker allocation */
112
113 /* PB5 */
114 unsigned res5:3;
115 unsigned lsv:4; /* level shift value */
116 unsigned dm_inh:1; /* downmix inhibit */
117
118 /* PB6-10 reserved */
119 u8 res6;
120 u8 res7;
121 u8 res8;
122 u8 res9;
123 u8 res10;
124} __packed;
125
126#define HDMI_AUDIO_VERSION 0x01
127
128#define HDMI_AUDIO_CC_STREAM 0x0 /* specified by audio stream */
129#define HDMI_AUDIO_CC_2 0x1
130#define HDMI_AUDIO_CC_3 0x2
131#define HDMI_AUDIO_CC_4 0x3
132#define HDMI_AUDIO_CC_5 0x4
133#define HDMI_AUDIO_CC_6 0x5
134#define HDMI_AUDIO_CC_7 0x6
135#define HDMI_AUDIO_CC_8 0x7
136
137#define HDMI_AUDIO_CT_STREAM 0x0 /* specified by audio stream */
138#define HDMI_AUDIO_CT_PCM 0x1
139#define HDMI_AUDIO_CT_AC3 0x2
140#define HDMI_AUDIO_CT_MPEG1 0x3
141#define HDMI_AUDIO_CT_MP3 0x4
142#define HDMI_AUDIO_CT_MPEG2 0x5
143#define HDMI_AUDIO_CT_AAC_LC 0x6
144#define HDMI_AUDIO_CT_DTS 0x7
145#define HDMI_AUDIO_CT_ATRAC 0x8
146#define HDMI_AUDIO_CT_DSD 0x9
147#define HDMI_AUDIO_CT_E_AC3 0xa
148#define HDMI_AUDIO_CT_DTS_HD 0xb
149#define HDMI_AUDIO_CT_MLP 0xc
150#define HDMI_AUDIO_CT_DST 0xd
151#define HDMI_AUDIO_CT_WMA_PRO 0xe
152#define HDMI_AUDIO_CT_CXT 0xf
153
154#define HDMI_AUDIO_SF_STREAM 0x0 /* specified by audio stream */
155#define HDMI_AUIDO_SF_32K 0x1
156#define HDMI_AUDIO_SF_44_1K 0x2
157#define HDMI_AUDIO_SF_48K 0x3
158#define HDMI_AUDIO_SF_88_2K 0x4
159#define HDMI_AUDIO_SF_96K 0x5
160#define HDMI_AUDIO_SF_176_4K 0x6
161#define HDMI_AUDIO_SF_192K 0x7
162
163#define HDMI_AUDIO_SS_STREAM 0x0 /* specified by audio stream */
164#define HDMI_AUDIO_SS_16BIT 0x1
165#define HDMI_AUDIO_SS_20BIT 0x2
166#define HDMI_AUDIO_SS_24BIT 0x3
167
168#define HDMI_AUDIO_CXT_CT 0x0 /* refer to coding in CT */
169#define HDMI_AUDIO_CXT_HE_AAC 0x1
170#define HDMI_AUDIO_CXT_HE_AAC_V2 0x2
171#define HDMI_AUDIO_CXT_MPEG_SURROUND 0x3
172
173/* all fields little endian */
174struct hdmi_stereo_infoframe {
175 /* PB0 */
176 u8 csum;
177
178 /* PB1 */
179 u8 regid0;
180
181 /* PB2 */
182 u8 regid1;
183
184 /* PB3 */
185 u8 regid2;
186
187 /* PB4 */
188 unsigned res1:5;
189 unsigned hdmi_video_format:3;
190
191 /* PB5 */
192 unsigned res2:4;
193 unsigned _3d_structure:4;
194
195 /* PB6*/
196 unsigned res3:4;
197 unsigned _3d_ext_data:4;
198} __packed;
199
200#define HDMI_VENDOR_VERSION 0x01
201
202/* register definitions */ 13/* register definitions */
203#define HDMI_CTXSW 0x00 14#define HDMI_CTXSW 0x00
204 15
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 09f1a18c1adf..b11eeab94151 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -52,6 +52,9 @@ config OF_VIDEOMODE
52 help 52 help
53 helper to get videomodes from the devicetree 53 helper to get videomodes from the devicetree
54 54
55config HDMI
56 bool
57
55menuconfig FB 58menuconfig FB
56 tristate "Support for frame buffer devices" 59 tristate "Support for frame buffer devices"
57 ---help--- 60 ---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index f592f3b32ec7..0b50082635e3 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -5,6 +5,7 @@
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_VGASTATE) += vgastate.o 7obj-$(CONFIG_VGASTATE) += vgastate.o
8obj-$(CONFIG_HDMI) += hdmi.o
8obj-y += fb_notify.o 9obj-y += fb_notify.o
9obj-$(CONFIG_FB) += fb.o 10obj-$(CONFIG_FB) += fb.o
10fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ 11fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
new file mode 100644
index 000000000000..ab23c9b79143
--- /dev/null
+++ b/drivers/video/hdmi.c
@@ -0,0 +1,308 @@
1/*
2 * Copyright (C) 2012 Avionic Design GmbH
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/bitops.h>
10#include <linux/errno.h>
11#include <linux/export.h>
12#include <linux/hdmi.h>
13#include <linux/string.h>
14
15static void hdmi_infoframe_checksum(void *buffer, size_t size)
16{
17 u8 *ptr = buffer;
18 u8 csum = 0;
19 size_t i;
20
21 /* compute checksum */
22 for (i = 0; i < size; i++)
23 csum += ptr[i];
24
25 ptr[3] = 256 - csum;
26}
27
28/**
29 * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
30 * @frame: HDMI AVI infoframe
31 *
32 * Returns 0 on success or a negative error code on failure.
33 */
34int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
35{
36 memset(frame, 0, sizeof(*frame));
37
38 frame->type = HDMI_INFOFRAME_TYPE_AVI;
39 frame->version = 2;
40 frame->length = 13;
41
42 return 0;
43}
44EXPORT_SYMBOL(hdmi_avi_infoframe_init);
45
46/**
47 * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
48 * @frame: HDMI AVI infoframe
49 * @buffer: destination buffer
50 * @size: size of buffer
51 *
52 * Packs the information contained in the @frame structure into a binary
53 * representation that can be written into the corresponding controller
54 * registers. Also computes the checksum as required by section 5.3.5 of
55 * the HDMI 1.4 specification.
56 *
57 * Returns the number of bytes packed into the binary buffer or a negative
58 * error code on failure.
59 */
60ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
61 size_t size)
62{
63 u8 *ptr = buffer;
64 size_t length;
65
66 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
67
68 if (size < length)
69 return -ENOSPC;
70
71 memset(buffer, 0, length);
72
73 ptr[0] = frame->type;
74 ptr[1] = frame->version;
75 ptr[2] = frame->length;
76 ptr[3] = 0; /* checksum */
77
78 /* start infoframe payload */
79 ptr += HDMI_INFOFRAME_HEADER_SIZE;
80
81 ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
82
83 if (frame->active_info_valid)
84 ptr[0] |= BIT(4);
85
86 if (frame->horizontal_bar_valid)
87 ptr[0] |= BIT(3);
88
89 if (frame->vertical_bar_valid)
90 ptr[0] |= BIT(2);
91
92 ptr[1] = ((frame->colorimetry & 0x3) << 6) |
93 ((frame->picture_aspect & 0x3) << 4) |
94 (frame->active_aspect & 0xf);
95
96 ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
97 ((frame->quantization_range & 0x3) << 2) |
98 (frame->nups & 0x3);
99
100 if (frame->itc)
101 ptr[2] |= BIT(7);
102
103 ptr[3] = frame->video_code & 0x7f;
104
105 ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
106 ((frame->content_type & 0x3) << 4) |
107 (frame->pixel_repeat & 0xf);
108
109 ptr[5] = frame->top_bar & 0xff;
110 ptr[6] = (frame->top_bar >> 8) & 0xff;
111 ptr[7] = frame->bottom_bar & 0xff;
112 ptr[8] = (frame->bottom_bar >> 8) & 0xff;
113 ptr[9] = frame->left_bar & 0xff;
114 ptr[10] = (frame->left_bar >> 8) & 0xff;
115 ptr[11] = frame->right_bar & 0xff;
116 ptr[12] = (frame->right_bar >> 8) & 0xff;
117
118 hdmi_infoframe_checksum(buffer, length);
119
120 return length;
121}
122EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
123
124/**
125 * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
126 * @frame: HDMI SPD infoframe
127 * @vendor: vendor string
128 * @product: product string
129 *
130 * Returns 0 on success or a negative error code on failure.
131 */
132int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
133 const char *vendor, const char *product)
134{
135 memset(frame, 0, sizeof(*frame));
136
137 frame->type = HDMI_INFOFRAME_TYPE_SPD;
138 frame->version = 1;
139 frame->length = 25;
140
141 strncpy(frame->vendor, vendor, sizeof(frame->vendor));
142 strncpy(frame->product, product, sizeof(frame->product));
143
144 return 0;
145}
146EXPORT_SYMBOL(hdmi_spd_infoframe_init);
147
148/**
149 * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
150 * @frame: HDMI SPD infoframe
151 * @buffer: destination buffer
152 * @size: size of buffer
153 *
154 * Packs the information contained in the @frame structure into a binary
155 * representation that can be written into the corresponding controller
156 * registers. Also computes the checksum as required by section 5.3.5 of
157 * the HDMI 1.4 specification.
158 *
159 * Returns the number of bytes packed into the binary buffer or a negative
160 * error code on failure.
161 */
162ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
163 size_t size)
164{
165 u8 *ptr = buffer;
166 size_t length;
167
168 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
169
170 if (size < length)
171 return -ENOSPC;
172
173 memset(buffer, 0, length);
174
175 ptr[0] = frame->type;
176 ptr[1] = frame->version;
177 ptr[2] = frame->length;
178 ptr[3] = 0; /* checksum */
179
180 /* start infoframe payload */
181 ptr += HDMI_INFOFRAME_HEADER_SIZE;
182
183 memcpy(ptr, frame->vendor, sizeof(frame->vendor));
184 memcpy(ptr + 8, frame->product, sizeof(frame->product));
185
186 ptr[24] = frame->sdi;
187
188 hdmi_infoframe_checksum(buffer, length);
189
190 return length;
191}
192EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
193
194/**
195 * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
196 * @frame: HDMI audio infoframe
197 *
198 * Returns 0 on success or a negative error code on failure.
199 */
200int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
201{
202 memset(frame, 0, sizeof(*frame));
203
204 frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
205 frame->version = 1;
206 frame->length = 10;
207
208 return 0;
209}
210EXPORT_SYMBOL(hdmi_audio_infoframe_init);
211
212/**
213 * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
214 * @frame: HDMI audio infoframe
215 * @buffer: destination buffer
216 * @size: size of buffer
217 *
218 * Packs the information contained in the @frame structure into a binary
219 * representation that can be written into the corresponding controller
220 * registers. Also computes the checksum as required by section 5.3.5 of
221 * the HDMI 1.4 specification.
222 *
223 * Returns the number of bytes packed into the binary buffer or a negative
224 * error code on failure.
225 */
226ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
227 void *buffer, size_t size)
228{
229 unsigned char channels;
230 u8 *ptr = buffer;
231 size_t length;
232
233 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
234
235 if (size < length)
236 return -ENOSPC;
237
238 memset(buffer, 0, length);
239
240 if (frame->channels >= 2)
241 channels = frame->channels - 1;
242 else
243 channels = 0;
244
245 ptr[0] = frame->type;
246 ptr[1] = frame->version;
247 ptr[2] = frame->length;
248 ptr[3] = 0; /* checksum */
249
250 /* start infoframe payload */
251 ptr += HDMI_INFOFRAME_HEADER_SIZE;
252
253 ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
254 ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
255 (frame->sample_size & 0x3);
256 ptr[2] = frame->coding_type_ext & 0x1f;
257 ptr[3] = frame->channel_allocation;
258 ptr[4] = (frame->level_shift_value & 0xf) << 3;
259
260 if (frame->downmix_inhibit)
261 ptr[4] |= BIT(7);
262
263 hdmi_infoframe_checksum(buffer, length);
264
265 return length;
266}
267EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
268
269/**
270 * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
271 * buffer
272 * @frame: HDMI vendor infoframe
273 * @buffer: destination buffer
274 * @size: size of buffer
275 *
276 * Packs the information contained in the @frame structure into a binary
277 * representation that can be written into the corresponding controller
278 * registers. Also computes the checksum as required by section 5.3.5 of
279 * the HDMI 1.4 specification.
280 *
281 * Returns the number of bytes packed into the binary buffer or a negative
282 * error code on failure.
283 */
284ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
285 void *buffer, size_t size)
286{
287 u8 *ptr = buffer;
288 size_t length;
289
290 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
291
292 if (size < length)
293 return -ENOSPC;
294
295 memset(buffer, 0, length);
296
297 ptr[0] = frame->type;
298 ptr[1] = frame->version;
299 ptr[2] = frame->length;
300 ptr[3] = 0; /* checksum */
301
302 memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length);
303
304 hdmi_infoframe_checksum(buffer, length);
305
306 return length;
307}
308EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 8b7762728639..8839b3a24660 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -38,7 +38,8 @@ struct drm_device;
38struct drm_mode_set; 38struct drm_mode_set;
39struct drm_framebuffer; 39struct drm_framebuffer;
40struct drm_object_properties; 40struct drm_object_properties;
41 41struct drm_file;
42struct drm_clip_rect;
42 43
43#define DRM_MODE_OBJECT_CRTC 0xcccccccc 44#define DRM_MODE_OBJECT_CRTC 0xcccccccc
44#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0 45#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
@@ -1061,7 +1062,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
1061extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, 1062extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
1062 void *data, struct drm_file *file_priv); 1063 void *data, struct drm_file *file_priv);
1063extern u8 *drm_find_cea_extension(struct edid *edid); 1064extern u8 *drm_find_cea_extension(struct edid *edid);
1064extern u8 drm_match_cea_mode(struct drm_display_mode *to_match); 1065extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
1065extern bool drm_detect_hdmi_monitor(struct edid *edid); 1066extern bool drm_detect_hdmi_monitor(struct edid *edid);
1066extern bool drm_detect_monitor_audio(struct edid *edid); 1067extern bool drm_detect_monitor_audio(struct edid *edid);
1067extern bool drm_rgb_quant_range_selectable(struct edid *edid); 1068extern bool drm_rgb_quant_range_selectable(struct edid *edid);
@@ -1079,7 +1080,6 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
1079 int GTF_2C, int GTF_K, int GTF_2J); 1080 int GTF_2C, int GTF_K, int GTF_2J);
1080extern int drm_add_modes_noedid(struct drm_connector *connector, 1081extern int drm_add_modes_noedid(struct drm_connector *connector,
1081 int hdisplay, int vdisplay); 1082 int hdisplay, int vdisplay);
1082extern uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode);
1083 1083
1084extern int drm_edid_header_is_valid(const u8 *raw_edid); 1084extern int drm_edid_header_is_valid(const u8 *raw_edid);
1085extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid); 1085extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 0cac551c5347..5da1b4ae7d84 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -247,6 +247,8 @@ struct edid {
247struct drm_encoder; 247struct drm_encoder;
248struct drm_connector; 248struct drm_connector;
249struct drm_display_mode; 249struct drm_display_mode;
250struct hdmi_avi_infoframe;
251
250void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid); 252void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
251int drm_av_sync_delay(struct drm_connector *connector, 253int drm_av_sync_delay(struct drm_connector *connector,
252 struct drm_display_mode *mode); 254 struct drm_display_mode *mode);
@@ -254,4 +256,8 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
254 struct drm_display_mode *mode); 256 struct drm_display_mode *mode);
255int drm_load_edid_firmware(struct drm_connector *connector); 257int drm_load_edid_firmware(struct drm_connector *connector);
256 258
259int
260drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
261 const struct drm_display_mode *mode);
262
257#endif /* __DRM_EDID_H__ */ 263#endif /* __DRM_EDID_H__ */
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
new file mode 100644
index 000000000000..3b589440ecfe
--- /dev/null
+++ b/include/linux/hdmi.h
@@ -0,0 +1,231 @@
1/*
2 * Copyright (C) 2012 Avionic Design GmbH
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __LINUX_HDMI_H_
10#define __LINUX_HDMI_H_
11
12#include <linux/types.h>
13
14enum hdmi_infoframe_type {
15 HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
16 HDMI_INFOFRAME_TYPE_AVI = 0x82,
17 HDMI_INFOFRAME_TYPE_SPD = 0x83,
18 HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
19};
20
21#define HDMI_INFOFRAME_HEADER_SIZE 4
22#define HDMI_AVI_INFOFRAME_SIZE 13
23#define HDMI_SPD_INFOFRAME_SIZE 25
24#define HDMI_AUDIO_INFOFRAME_SIZE 10
25
26enum hdmi_colorspace {
27 HDMI_COLORSPACE_RGB,
28 HDMI_COLORSPACE_YUV422,
29 HDMI_COLORSPACE_YUV444,
30};
31
32enum hdmi_scan_mode {
33 HDMI_SCAN_MODE_NONE,
34 HDMI_SCAN_MODE_OVERSCAN,
35 HDMI_SCAN_MODE_UNDERSCAN,
36};
37
38enum hdmi_colorimetry {
39 HDMI_COLORIMETRY_NONE,
40 HDMI_COLORIMETRY_ITU_601,
41 HDMI_COLORIMETRY_ITU_709,
42 HDMI_COLORIMETRY_EXTENDED,
43};
44
45enum hdmi_picture_aspect {
46 HDMI_PICTURE_ASPECT_NONE,
47 HDMI_PICTURE_ASPECT_4_3,
48 HDMI_PICTURE_ASPECT_16_9,
49};
50
51enum hdmi_active_aspect {
52 HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
53 HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
54 HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
55 HDMI_ACTIVE_ASPECT_PICTURE = 8,
56 HDMI_ACTIVE_ASPECT_4_3 = 9,
57 HDMI_ACTIVE_ASPECT_16_9 = 10,
58 HDMI_ACTIVE_ASPECT_14_9 = 11,
59 HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
60 HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
61 HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
62};
63
64enum hdmi_extended_colorimetry {
65 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
66 HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
67 HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
68 HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
69 HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
70};
71
72enum hdmi_quantization_range {
73 HDMI_QUANTIZATION_RANGE_DEFAULT,
74 HDMI_QUANTIZATION_RANGE_LIMITED,
75 HDMI_QUANTIZATION_RANGE_FULL,
76};
77
78/* non-uniform picture scaling */
79enum hdmi_nups {
80 HDMI_NUPS_UNKNOWN,
81 HDMI_NUPS_HORIZONTAL,
82 HDMI_NUPS_VERTICAL,
83 HDMI_NUPS_BOTH,
84};
85
86enum hdmi_ycc_quantization_range {
87 HDMI_YCC_QUANTIZATION_RANGE_LIMITED,
88 HDMI_YCC_QUANTIZATION_RANGE_FULL,
89};
90
91enum hdmi_content_type {
92 HDMI_CONTENT_TYPE_NONE,
93 HDMI_CONTENT_TYPE_PHOTO,
94 HDMI_CONTENT_TYPE_CINEMA,
95 HDMI_CONTENT_TYPE_GAME,
96};
97
98struct hdmi_avi_infoframe {
99 enum hdmi_infoframe_type type;
100 unsigned char version;
101 unsigned char length;
102 enum hdmi_colorspace colorspace;
103 bool active_info_valid;
104 bool horizontal_bar_valid;
105 bool vertical_bar_valid;
106 enum hdmi_scan_mode scan_mode;
107 enum hdmi_colorimetry colorimetry;
108 enum hdmi_picture_aspect picture_aspect;
109 enum hdmi_active_aspect active_aspect;
110 bool itc;
111 enum hdmi_extended_colorimetry extended_colorimetry;
112 enum hdmi_quantization_range quantization_range;
113 enum hdmi_nups nups;
114 unsigned char video_code;
115 enum hdmi_ycc_quantization_range ycc_quantization_range;
116 enum hdmi_content_type content_type;
117 unsigned char pixel_repeat;
118 unsigned short top_bar;
119 unsigned short bottom_bar;
120 unsigned short left_bar;
121 unsigned short right_bar;
122};
123
124int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
125ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
126 size_t size);
127
128enum hdmi_spd_sdi {
129 HDMI_SPD_SDI_UNKNOWN,
130 HDMI_SPD_SDI_DSTB,
131 HDMI_SPD_SDI_DVDP,
132 HDMI_SPD_SDI_DVHS,
133 HDMI_SPD_SDI_HDDVR,
134 HDMI_SPD_SDI_DVC,
135 HDMI_SPD_SDI_DSC,
136 HDMI_SPD_SDI_VCD,
137 HDMI_SPD_SDI_GAME,
138 HDMI_SPD_SDI_PC,
139 HDMI_SPD_SDI_BD,
140 HDMI_SPD_SDI_SACD,
141 HDMI_SPD_SDI_HDDVD,
142 HDMI_SPD_SDI_PMP,
143};
144
145struct hdmi_spd_infoframe {
146 enum hdmi_infoframe_type type;
147 unsigned char version;
148 unsigned char length;
149 char vendor[8];
150 char product[16];
151 enum hdmi_spd_sdi sdi;
152};
153
154int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
155 const char *vendor, const char *product);
156ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
157 size_t size);
158
159enum hdmi_audio_coding_type {
160 HDMI_AUDIO_CODING_TYPE_STREAM,
161 HDMI_AUDIO_CODING_TYPE_PCM,
162 HDMI_AUDIO_CODING_TYPE_AC3,
163 HDMI_AUDIO_CODING_TYPE_MPEG1,
164 HDMI_AUDIO_CODING_TYPE_MP3,
165 HDMI_AUDIO_CODING_TYPE_MPEG2,
166 HDMI_AUDIO_CODING_TYPE_AAC_LC,
167 HDMI_AUDIO_CODING_TYPE_DTS,
168 HDMI_AUDIO_CODING_TYPE_ATRAC,
169 HDMI_AUDIO_CODING_TYPE_DSD,
170 HDMI_AUDIO_CODING_TYPE_EAC3,
171 HDMI_AUDIO_CODING_TYPE_DTS_HD,
172 HDMI_AUDIO_CODING_TYPE_MLP,
173 HDMI_AUDIO_CODING_TYPE_DST,
174 HDMI_AUDIO_CODING_TYPE_WMA_PRO,
175};
176
177enum hdmi_audio_sample_size {
178 HDMI_AUDIO_SAMPLE_SIZE_STREAM,
179 HDMI_AUDIO_SAMPLE_SIZE_16,
180 HDMI_AUDIO_SAMPLE_SIZE_20,
181 HDMI_AUDIO_SAMPLE_SIZE_24,
182};
183
184enum hdmi_audio_sample_frequency {
185 HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
186 HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
187 HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
188 HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
189 HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
190 HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
191 HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
192 HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
193};
194
195enum hdmi_audio_coding_type_ext {
196 HDMI_AUDIO_CODING_TYPE_EXT_STREAM,
197 HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC,
198 HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2,
199 HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND,
200};
201
202struct hdmi_audio_infoframe {
203 enum hdmi_infoframe_type type;
204 unsigned char version;
205 unsigned char length;
206 unsigned char channels;
207 enum hdmi_audio_coding_type coding_type;
208 enum hdmi_audio_sample_size sample_size;
209 enum hdmi_audio_sample_frequency sample_frequency;
210 enum hdmi_audio_coding_type_ext coding_type_ext;
211 unsigned char channel_allocation;
212 unsigned char level_shift_value;
213 bool downmix_inhibit;
214
215};
216
217int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
218ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
219 void *buffer, size_t size);
220
221struct hdmi_vendor_infoframe {
222 enum hdmi_infoframe_type type;
223 unsigned char version;
224 unsigned char length;
225 u8 data[27];
226};
227
228ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
229 void *buffer, size_t size);
230
231#endif /* _DRM_HDMI_H */