0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/bitfield.h>
0032 #include <linux/hdmi.h>
0033 #include <linux/i2c.h>
0034 #include <linux/kernel.h>
0035 #include <linux/module.h>
0036 #include <linux/pci.h>
0037 #include <linux/slab.h>
0038 #include <linux/vga_switcheroo.h>
0039
0040 #include <drm/drm_displayid.h>
0041 #include <drm/drm_drv.h>
0042 #include <drm/drm_edid.h>
0043 #include <drm/drm_encoder.h>
0044 #include <drm/drm_print.h>
0045
0046 #include "drm_crtc_internal.h"
0047
0048 static int oui(u8 first, u8 second, u8 third)
0049 {
0050 return (first << 16) | (second << 8) | third;
0051 }
0052
0053 #define EDID_EST_TIMINGS 16
0054 #define EDID_STD_TIMINGS 8
0055 #define EDID_DETAILED_TIMINGS 4
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 #define EDID_QUIRK_PREFER_LARGE_60 (1 << 0)
0066
0067 #define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1)
0068
0069 #define EDID_QUIRK_PREFER_LARGE_75 (1 << 2)
0070
0071 #define EDID_QUIRK_DETAILED_IN_CM (1 << 3)
0072
0073
0074
0075 #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4)
0076
0077 #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
0078
0079 #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7)
0080
0081 #define EDID_QUIRK_FORCE_8BPC (1 << 8)
0082
0083 #define EDID_QUIRK_FORCE_12BPC (1 << 9)
0084
0085 #define EDID_QUIRK_FORCE_6BPC (1 << 10)
0086
0087 #define EDID_QUIRK_FORCE_10BPC (1 << 11)
0088
0089 #define EDID_QUIRK_NON_DESKTOP (1 << 12)
0090
0091 #define MICROSOFT_IEEE_OUI 0xca125c
0092
0093 struct detailed_mode_closure {
0094 struct drm_connector *connector;
0095 const struct drm_edid *drm_edid;
0096 bool preferred;
0097 u32 quirks;
0098 int modes;
0099 };
0100
0101 #define LEVEL_DMT 0
0102 #define LEVEL_GTF 1
0103 #define LEVEL_GTF2 2
0104 #define LEVEL_CVT 3
0105
0106 #define EDID_QUIRK(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _quirks) \
0107 { \
0108 .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \
0109 product_id), \
0110 .quirks = _quirks \
0111 }
0112
0113 static const struct edid_quirk {
0114 u32 panel_id;
0115 u32 quirks;
0116 } edid_quirk_list[] = {
0117
0118 EDID_QUIRK('A', 'C', 'R', 44358, EDID_QUIRK_PREFER_LARGE_60),
0119
0120 EDID_QUIRK('A', 'P', 'I', 0x7602, EDID_QUIRK_PREFER_LARGE_60),
0121
0122
0123 EDID_QUIRK('A', 'E', 'O', 0, EDID_QUIRK_FORCE_6BPC),
0124
0125
0126 EDID_QUIRK('B', 'O', 'E', 0x78b, EDID_QUIRK_FORCE_6BPC),
0127
0128
0129 EDID_QUIRK('C', 'P', 'T', 0x17df, EDID_QUIRK_FORCE_6BPC),
0130
0131
0132 EDID_QUIRK('S', 'D', 'C', 0x3652, EDID_QUIRK_FORCE_6BPC),
0133
0134
0135 EDID_QUIRK('B', 'O', 'E', 0x0771, EDID_QUIRK_FORCE_6BPC),
0136
0137
0138 EDID_QUIRK('M', 'A', 'X', 1516, EDID_QUIRK_PREFER_LARGE_60),
0139 EDID_QUIRK('M', 'A', 'X', 0x77e, EDID_QUIRK_PREFER_LARGE_60),
0140
0141
0142 EDID_QUIRK('E', 'P', 'I', 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH),
0143
0144 EDID_QUIRK('E', 'P', 'I', 8232, EDID_QUIRK_PREFER_LARGE_60),
0145
0146
0147 EDID_QUIRK('F', 'C', 'M', 13600, EDID_QUIRK_PREFER_LARGE_75 |
0148 EDID_QUIRK_DETAILED_IN_CM),
0149
0150
0151 EDID_QUIRK('L', 'G', 'D', 764, EDID_QUIRK_FORCE_10BPC),
0152
0153
0154 EDID_QUIRK('L', 'P', 'L', 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE),
0155 EDID_QUIRK('L', 'P', 'L', 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE),
0156
0157
0158 EDID_QUIRK('S', 'A', 'M', 541, EDID_QUIRK_DETAILED_SYNC_PP),
0159
0160 EDID_QUIRK('S', 'A', 'M', 596, EDID_QUIRK_PREFER_LARGE_60),
0161 EDID_QUIRK('S', 'A', 'M', 638, EDID_QUIRK_PREFER_LARGE_60),
0162
0163
0164 EDID_QUIRK('S', 'N', 'Y', 0x2541, EDID_QUIRK_FORCE_12BPC),
0165
0166
0167 EDID_QUIRK('V', 'S', 'C', 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING),
0168
0169
0170 EDID_QUIRK('M', 'E', 'D', 0x7b8, EDID_QUIRK_PREFER_LARGE_75),
0171
0172
0173 EDID_QUIRK('S', 'D', 'C', 18514, EDID_QUIRK_FORCE_6BPC),
0174
0175
0176 EDID_QUIRK('S', 'E', 'C', 0xd033, EDID_QUIRK_FORCE_8BPC),
0177
0178
0179 EDID_QUIRK('E', 'T', 'R', 13896, EDID_QUIRK_FORCE_8BPC),
0180
0181
0182 EDID_QUIRK('V', 'L', 'V', 0x91a8, EDID_QUIRK_NON_DESKTOP),
0183 EDID_QUIRK('V', 'L', 'V', 0x91b0, EDID_QUIRK_NON_DESKTOP),
0184 EDID_QUIRK('V', 'L', 'V', 0x91b1, EDID_QUIRK_NON_DESKTOP),
0185 EDID_QUIRK('V', 'L', 'V', 0x91b2, EDID_QUIRK_NON_DESKTOP),
0186 EDID_QUIRK('V', 'L', 'V', 0x91b3, EDID_QUIRK_NON_DESKTOP),
0187 EDID_QUIRK('V', 'L', 'V', 0x91b4, EDID_QUIRK_NON_DESKTOP),
0188 EDID_QUIRK('V', 'L', 'V', 0x91b5, EDID_QUIRK_NON_DESKTOP),
0189 EDID_QUIRK('V', 'L', 'V', 0x91b6, EDID_QUIRK_NON_DESKTOP),
0190 EDID_QUIRK('V', 'L', 'V', 0x91b7, EDID_QUIRK_NON_DESKTOP),
0191 EDID_QUIRK('V', 'L', 'V', 0x91b8, EDID_QUIRK_NON_DESKTOP),
0192 EDID_QUIRK('V', 'L', 'V', 0x91b9, EDID_QUIRK_NON_DESKTOP),
0193 EDID_QUIRK('V', 'L', 'V', 0x91ba, EDID_QUIRK_NON_DESKTOP),
0194 EDID_QUIRK('V', 'L', 'V', 0x91bb, EDID_QUIRK_NON_DESKTOP),
0195 EDID_QUIRK('V', 'L', 'V', 0x91bc, EDID_QUIRK_NON_DESKTOP),
0196 EDID_QUIRK('V', 'L', 'V', 0x91bd, EDID_QUIRK_NON_DESKTOP),
0197 EDID_QUIRK('V', 'L', 'V', 0x91be, EDID_QUIRK_NON_DESKTOP),
0198 EDID_QUIRK('V', 'L', 'V', 0x91bf, EDID_QUIRK_NON_DESKTOP),
0199
0200
0201 EDID_QUIRK('H', 'V', 'R', 0xaa01, EDID_QUIRK_NON_DESKTOP),
0202 EDID_QUIRK('H', 'V', 'R', 0xaa02, EDID_QUIRK_NON_DESKTOP),
0203
0204
0205 EDID_QUIRK('O', 'V', 'R', 0x0001, EDID_QUIRK_NON_DESKTOP),
0206 EDID_QUIRK('O', 'V', 'R', 0x0003, EDID_QUIRK_NON_DESKTOP),
0207 EDID_QUIRK('O', 'V', 'R', 0x0004, EDID_QUIRK_NON_DESKTOP),
0208 EDID_QUIRK('O', 'V', 'R', 0x0012, EDID_QUIRK_NON_DESKTOP),
0209
0210
0211 EDID_QUIRK('A', 'C', 'R', 0x7fce, EDID_QUIRK_NON_DESKTOP),
0212 EDID_QUIRK('L', 'E', 'N', 0x0408, EDID_QUIRK_NON_DESKTOP),
0213 EDID_QUIRK('F', 'U', 'J', 0x1970, EDID_QUIRK_NON_DESKTOP),
0214 EDID_QUIRK('D', 'E', 'L', 0x7fce, EDID_QUIRK_NON_DESKTOP),
0215 EDID_QUIRK('S', 'E', 'C', 0x144a, EDID_QUIRK_NON_DESKTOP),
0216 EDID_QUIRK('A', 'U', 'S', 0xc102, EDID_QUIRK_NON_DESKTOP),
0217
0218
0219 EDID_QUIRK('S', 'N', 'Y', 0x0704, EDID_QUIRK_NON_DESKTOP),
0220
0221
0222 EDID_QUIRK('S', 'E', 'N', 0x1019, EDID_QUIRK_NON_DESKTOP),
0223
0224
0225 EDID_QUIRK('S', 'V', 'R', 0x1019, EDID_QUIRK_NON_DESKTOP),
0226 };
0227
0228
0229
0230
0231
0232 static const struct drm_display_mode drm_dmt_modes[] = {
0233
0234 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
0235 736, 832, 0, 350, 382, 385, 445, 0,
0236 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0237
0238 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
0239 736, 832, 0, 400, 401, 404, 445, 0,
0240 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0241
0242 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
0243 828, 936, 0, 400, 401, 404, 446, 0,
0244 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0245
0246 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
0247 752, 800, 0, 480, 490, 492, 525, 0,
0248 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0249
0250 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
0251 704, 832, 0, 480, 489, 492, 520, 0,
0252 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0253
0254 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
0255 720, 840, 0, 480, 481, 484, 500, 0,
0256 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0257
0258 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
0259 752, 832, 0, 480, 481, 484, 509, 0,
0260 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0261
0262 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
0263 896, 1024, 0, 600, 601, 603, 625, 0,
0264 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0265
0266 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
0267 968, 1056, 0, 600, 601, 605, 628, 0,
0268 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0269
0270 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
0271 976, 1040, 0, 600, 637, 643, 666, 0,
0272 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0273
0274 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
0275 896, 1056, 0, 600, 601, 604, 625, 0,
0276 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0277
0278 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
0279 896, 1048, 0, 600, 601, 604, 631, 0,
0280 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0281
0282 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
0283 880, 960, 0, 600, 603, 607, 636, 0,
0284 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0285
0286 { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
0287 976, 1088, 0, 480, 486, 494, 517, 0,
0288 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0289
0290 { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
0291 1208, 1264, 0, 768, 768, 776, 817, 0,
0292 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
0293 DRM_MODE_FLAG_INTERLACE) },
0294
0295 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
0296 1184, 1344, 0, 768, 771, 777, 806, 0,
0297 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0298
0299 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
0300 1184, 1328, 0, 768, 771, 777, 806, 0,
0301 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0302
0303 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
0304 1136, 1312, 0, 768, 769, 772, 800, 0,
0305 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0306
0307 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
0308 1168, 1376, 0, 768, 769, 772, 808, 0,
0309 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0310
0311 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
0312 1104, 1184, 0, 768, 771, 775, 813, 0,
0313 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0314
0315 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
0316 1344, 1600, 0, 864, 865, 868, 900, 0,
0317 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0318
0319 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
0320 1430, 1650, 0, 720, 725, 730, 750, 0,
0321 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0322
0323 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
0324 1360, 1440, 0, 768, 771, 778, 790, 0,
0325 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0326
0327 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
0328 1472, 1664, 0, 768, 771, 778, 798, 0,
0329 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0330
0331 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
0332 1488, 1696, 0, 768, 771, 778, 805, 0,
0333 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0334
0335 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
0336 1496, 1712, 0, 768, 771, 778, 809, 0,
0337 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0338
0339 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
0340 1360, 1440, 0, 768, 771, 778, 813, 0,
0341 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0342
0343 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
0344 1360, 1440, 0, 800, 803, 809, 823, 0,
0345 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0346
0347 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
0348 1480, 1680, 0, 800, 803, 809, 831, 0,
0349 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0350
0351 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
0352 1488, 1696, 0, 800, 803, 809, 838, 0,
0353 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0354
0355 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
0356 1496, 1712, 0, 800, 803, 809, 843, 0,
0357 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0358
0359 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
0360 1360, 1440, 0, 800, 803, 809, 847, 0,
0361 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0362
0363 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
0364 1488, 1800, 0, 960, 961, 964, 1000, 0,
0365 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0366
0367 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
0368 1504, 1728, 0, 960, 961, 964, 1011, 0,
0369 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0370
0371 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
0372 1360, 1440, 0, 960, 963, 967, 1017, 0,
0373 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0374
0375 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
0376 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
0377 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0378
0379 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
0380 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
0381 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0382
0383 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
0384 1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
0385 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0386
0387 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
0388 1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
0389 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0390
0391 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
0392 1536, 1792, 0, 768, 771, 777, 795, 0,
0393 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0394
0395 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
0396 1440, 1520, 0, 768, 771, 776, 813, 0,
0397 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0398
0399 { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85500, 1366, 1436,
0400 1579, 1792, 0, 768, 771, 774, 798, 0,
0401 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0402
0403 { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 72000, 1366, 1380,
0404 1436, 1500, 0, 768, 769, 772, 800, 0,
0405 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0406
0407 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
0408 1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
0409 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0410
0411 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
0412 1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
0413 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0414
0415 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
0416 1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
0417 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0418
0419 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
0420 1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
0421 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0422
0423 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
0424 1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
0425 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0426
0427 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
0428 1520, 1600, 0, 900, 903, 909, 926, 0,
0429 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0430
0431 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
0432 1672, 1904, 0, 900, 903, 909, 934, 0,
0433 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0434
0435 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
0436 1688, 1936, 0, 900, 903, 909, 942, 0,
0437 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0438
0439 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
0440 1696, 1952, 0, 900, 903, 909, 948, 0,
0441 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0442
0443 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
0444 1520, 1600, 0, 900, 903, 909, 953, 0,
0445 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0446
0447 { DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 108000, 1600, 1624,
0448 1704, 1800, 0, 900, 901, 904, 1000, 0,
0449 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0450
0451 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
0452 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
0453 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0454
0455 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
0456 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
0457 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0458
0459 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
0460 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
0461 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0462
0463 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
0464 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
0465 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0466
0467 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
0468 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
0469 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0470
0471 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
0472 1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
0473 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0474
0475 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
0476 1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
0477 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0478
0479 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
0480 1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
0481 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0482
0483 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
0484 1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
0485 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0486
0487 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
0488 1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
0489 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0490
0491 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
0492 1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
0493 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0494
0495 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
0496 2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
0497 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0498
0499 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
0500 2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
0501 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0502
0503 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
0504 1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
0505 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0506
0507 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
0508 2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
0509 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0510
0511 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
0512 2208, 2560, 0, 1392, 1393, 1396, 1500, 0,
0513 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0514
0515 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
0516 1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
0517 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0518
0519 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
0520 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
0521 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0522
0523 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
0524 2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
0525 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0526
0527 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
0528 2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
0529 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0530
0531 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
0532 2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
0533 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0534
0535 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
0536 2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
0537 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0538
0539 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
0540 2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
0541 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0542
0543 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
0544 2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
0545 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0546
0547 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
0548 2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
0549 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0550
0551 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
0552 2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
0553 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0554
0555 { DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 162000, 2048, 2074,
0556 2154, 2250, 0, 1152, 1153, 1156, 1200, 0,
0557 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0558
0559 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
0560 2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
0561 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0562
0563 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
0564 3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
0565 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0566
0567 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
0568 3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
0569 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0570
0571 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
0572 3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
0573 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0574
0575 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
0576 2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
0577 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0578
0579 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556744, 4096, 4104,
0580 4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
0581 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0582
0583 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
0584 4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
0585 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
0586 };
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 static const struct drm_display_mode edid_est_modes[] = {
0598 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
0599 968, 1056, 0, 600, 601, 605, 628, 0,
0600 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0601 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
0602 896, 1024, 0, 600, 601, 603, 625, 0,
0603 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0604 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
0605 720, 840, 0, 480, 481, 484, 500, 0,
0606 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0607 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
0608 704, 832, 0, 480, 489, 492, 520, 0,
0609 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0610 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
0611 768, 864, 0, 480, 483, 486, 525, 0,
0612 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0613 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
0614 752, 800, 0, 480, 490, 492, 525, 0,
0615 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0616 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
0617 846, 900, 0, 400, 421, 423, 449, 0,
0618 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0619 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
0620 846, 900, 0, 400, 412, 414, 449, 0,
0621 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
0622 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
0623 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
0624 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0625 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
0626 1136, 1312, 0, 768, 769, 772, 800, 0,
0627 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0628 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
0629 1184, 1328, 0, 768, 771, 777, 806, 0,
0630 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0631 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
0632 1184, 1344, 0, 768, 771, 777, 806, 0,
0633 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0634 { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
0635 1208, 1264, 0, 768, 768, 776, 817, 0,
0636 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) },
0637 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
0638 928, 1152, 0, 624, 625, 628, 667, 0,
0639 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0640 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
0641 896, 1056, 0, 600, 601, 604, 625, 0,
0642 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0643 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
0644 976, 1040, 0, 600, 637, 643, 666, 0,
0645 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0646 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
0647 1344, 1600, 0, 864, 865, 868, 900, 0,
0648 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0649 };
0650
0651 struct minimode {
0652 short w;
0653 short h;
0654 short r;
0655 short rb;
0656 };
0657
0658 static const struct minimode est3_modes[] = {
0659
0660 { 640, 350, 85, 0 },
0661 { 640, 400, 85, 0 },
0662 { 720, 400, 85, 0 },
0663 { 640, 480, 85, 0 },
0664 { 848, 480, 60, 0 },
0665 { 800, 600, 85, 0 },
0666 { 1024, 768, 85, 0 },
0667 { 1152, 864, 75, 0 },
0668
0669 { 1280, 768, 60, 1 },
0670 { 1280, 768, 60, 0 },
0671 { 1280, 768, 75, 0 },
0672 { 1280, 768, 85, 0 },
0673 { 1280, 960, 60, 0 },
0674 { 1280, 960, 85, 0 },
0675 { 1280, 1024, 60, 0 },
0676 { 1280, 1024, 85, 0 },
0677
0678 { 1360, 768, 60, 0 },
0679 { 1440, 900, 60, 1 },
0680 { 1440, 900, 60, 0 },
0681 { 1440, 900, 75, 0 },
0682 { 1440, 900, 85, 0 },
0683 { 1400, 1050, 60, 1 },
0684 { 1400, 1050, 60, 0 },
0685 { 1400, 1050, 75, 0 },
0686
0687 { 1400, 1050, 85, 0 },
0688 { 1680, 1050, 60, 1 },
0689 { 1680, 1050, 60, 0 },
0690 { 1680, 1050, 75, 0 },
0691 { 1680, 1050, 85, 0 },
0692 { 1600, 1200, 60, 0 },
0693 { 1600, 1200, 65, 0 },
0694 { 1600, 1200, 70, 0 },
0695
0696 { 1600, 1200, 75, 0 },
0697 { 1600, 1200, 85, 0 },
0698 { 1792, 1344, 60, 0 },
0699 { 1792, 1344, 75, 0 },
0700 { 1856, 1392, 60, 0 },
0701 { 1856, 1392, 75, 0 },
0702 { 1920, 1200, 60, 1 },
0703 { 1920, 1200, 60, 0 },
0704
0705 { 1920, 1200, 75, 0 },
0706 { 1920, 1200, 85, 0 },
0707 { 1920, 1440, 60, 0 },
0708 { 1920, 1440, 75, 0 },
0709 };
0710
0711 static const struct minimode extra_modes[] = {
0712 { 1024, 576, 60, 0 },
0713 { 1366, 768, 60, 0 },
0714 { 1600, 900, 60, 0 },
0715 { 1680, 945, 60, 0 },
0716 { 1920, 1080, 60, 0 },
0717 { 2048, 1152, 60, 0 },
0718 { 2048, 1536, 60, 0 },
0719 };
0720
0721
0722
0723
0724
0725
0726 static const struct drm_display_mode edid_cea_modes_1[] = {
0727
0728 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
0729 752, 800, 0, 480, 490, 492, 525, 0,
0730 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0731 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0732
0733 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
0734 798, 858, 0, 480, 489, 495, 525, 0,
0735 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0736 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0737
0738 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
0739 798, 858, 0, 480, 489, 495, 525, 0,
0740 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0741 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0742
0743 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
0744 1430, 1650, 0, 720, 725, 730, 750, 0,
0745 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0746 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0747
0748 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
0749 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
0750 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
0751 DRM_MODE_FLAG_INTERLACE),
0752 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0753
0754 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
0755 801, 858, 0, 480, 488, 494, 525, 0,
0756 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0757 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0758 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0759
0760 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
0761 801, 858, 0, 480, 488, 494, 525, 0,
0762 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0763 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0764 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0765
0766 { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
0767 801, 858, 0, 240, 244, 247, 262, 0,
0768 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0769 DRM_MODE_FLAG_DBLCLK),
0770 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0771
0772 { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
0773 801, 858, 0, 240, 244, 247, 262, 0,
0774 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0775 DRM_MODE_FLAG_DBLCLK),
0776 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0777
0778 { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
0779 3204, 3432, 0, 480, 488, 494, 525, 0,
0780 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0781 DRM_MODE_FLAG_INTERLACE),
0782 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0783
0784 { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
0785 3204, 3432, 0, 480, 488, 494, 525, 0,
0786 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0787 DRM_MODE_FLAG_INTERLACE),
0788 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0789
0790 { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
0791 3204, 3432, 0, 240, 244, 247, 262, 0,
0792 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0793 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0794
0795 { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
0796 3204, 3432, 0, 240, 244, 247, 262, 0,
0797 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0798 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0799
0800 { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
0801 1596, 1716, 0, 480, 489, 495, 525, 0,
0802 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0803 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0804
0805 { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
0806 1596, 1716, 0, 480, 489, 495, 525, 0,
0807 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0808 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0809
0810 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
0811 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
0812 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0813 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0814
0815 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
0816 796, 864, 0, 576, 581, 586, 625, 0,
0817 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0818 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0819
0820 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
0821 796, 864, 0, 576, 581, 586, 625, 0,
0822 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0823 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0824
0825 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
0826 1760, 1980, 0, 720, 725, 730, 750, 0,
0827 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0828 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0829
0830 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
0831 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
0832 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
0833 DRM_MODE_FLAG_INTERLACE),
0834 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0835
0836 { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
0837 795, 864, 0, 576, 580, 586, 625, 0,
0838 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0839 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0840 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0841
0842 { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
0843 795, 864, 0, 576, 580, 586, 625, 0,
0844 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0845 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0846 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0847
0848 { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
0849 795, 864, 0, 288, 290, 293, 312, 0,
0850 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0851 DRM_MODE_FLAG_DBLCLK),
0852 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0853
0854 { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
0855 795, 864, 0, 288, 290, 293, 312, 0,
0856 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0857 DRM_MODE_FLAG_DBLCLK),
0858 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0859
0860 { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
0861 3180, 3456, 0, 576, 580, 586, 625, 0,
0862 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0863 DRM_MODE_FLAG_INTERLACE),
0864 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0865
0866 { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
0867 3180, 3456, 0, 576, 580, 586, 625, 0,
0868 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0869 DRM_MODE_FLAG_INTERLACE),
0870 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0871
0872 { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
0873 3180, 3456, 0, 288, 290, 293, 312, 0,
0874 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0875 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0876
0877 { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
0878 3180, 3456, 0, 288, 290, 293, 312, 0,
0879 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0880 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0881
0882 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
0883 1592, 1728, 0, 576, 581, 586, 625, 0,
0884 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0885 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0886
0887 { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
0888 1592, 1728, 0, 576, 581, 586, 625, 0,
0889 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0890 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0891
0892 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
0893 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
0894 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0895 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0896
0897 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
0898 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
0899 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0900 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0901
0902 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
0903 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
0904 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0905 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0906
0907 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
0908 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
0909 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0910 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0911
0912 { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
0913 3192, 3432, 0, 480, 489, 495, 525, 0,
0914 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0915 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0916
0917 { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
0918 3192, 3432, 0, 480, 489, 495, 525, 0,
0919 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0920 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0921
0922 { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
0923 3184, 3456, 0, 576, 581, 586, 625, 0,
0924 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0925 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0926
0927 { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
0928 3184, 3456, 0, 576, 581, 586, 625, 0,
0929 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0930 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0931
0932 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
0933 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
0934 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
0935 DRM_MODE_FLAG_INTERLACE),
0936 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0937
0938 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
0939 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
0940 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
0941 DRM_MODE_FLAG_INTERLACE),
0942 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0943
0944 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
0945 1760, 1980, 0, 720, 725, 730, 750, 0,
0946 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0947 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0948
0949 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
0950 796, 864, 0, 576, 581, 586, 625, 0,
0951 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0952 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0953
0954 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
0955 796, 864, 0, 576, 581, 586, 625, 0,
0956 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0957 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0958
0959 { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
0960 795, 864, 0, 576, 580, 586, 625, 0,
0961 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0962 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0963 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0964
0965 { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
0966 795, 864, 0, 576, 580, 586, 625, 0,
0967 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0968 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0969 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0970
0971 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
0972 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
0973 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
0974 DRM_MODE_FLAG_INTERLACE),
0975 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0976
0977 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
0978 1430, 1650, 0, 720, 725, 730, 750, 0,
0979 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
0980 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0981
0982 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
0983 798, 858, 0, 480, 489, 495, 525, 0,
0984 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0985 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0986
0987 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
0988 798, 858, 0, 480, 489, 495, 525, 0,
0989 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
0990 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
0991
0992 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
0993 801, 858, 0, 480, 488, 494, 525, 0,
0994 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
0995 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
0996 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
0997
0998 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
0999 801, 858, 0, 480, 488, 494, 525, 0,
1000 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
1001 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
1002 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1003
1004 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
1005 796, 864, 0, 576, 581, 586, 625, 0,
1006 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1007 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
1008
1009 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
1010 796, 864, 0, 576, 581, 586, 625, 0,
1011 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1012 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1013
1014 { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
1015 795, 864, 0, 576, 580, 586, 625, 0,
1016 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
1017 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
1018 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
1019
1020 { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
1021 795, 864, 0, 576, 580, 586, 625, 0,
1022 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
1023 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
1024 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1025
1026 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
1027 798, 858, 0, 480, 489, 495, 525, 0,
1028 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1029 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
1030
1031 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
1032 798, 858, 0, 480, 489, 495, 525, 0,
1033 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1034 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1035
1036 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
1037 801, 858, 0, 480, 488, 494, 525, 0,
1038 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
1039 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
1040 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
1041
1042 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
1043 801, 858, 0, 480, 488, 494, 525, 0,
1044 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
1045 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
1046 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1047
1048 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
1049 3080, 3300, 0, 720, 725, 730, 750, 0,
1050 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1051 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1052
1053 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
1054 3740, 3960, 0, 720, 725, 730, 750, 0,
1055 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1056 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1057
1058 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
1059 3080, 3300, 0, 720, 725, 730, 750, 0,
1060 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1061 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1062
1063 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
1064 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1065 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1066 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1067
1068 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
1069 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
1070 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1071 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1072
1073 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
1074 3080, 3300, 0, 720, 725, 730, 750, 0,
1075 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1076 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1077
1078 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
1079 3740, 3960, 0, 720, 725, 730, 750, 0,
1080 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1081 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1082
1083 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
1084 3080, 3300, 0, 720, 725, 730, 750, 0,
1085 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1086 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1087
1088 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
1089 1760, 1980, 0, 720, 725, 730, 750, 0,
1090 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1091 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1092
1093 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
1094 1430, 1650, 0, 720, 725, 730, 750, 0,
1095 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1096 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1097
1098 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
1099 1760, 1980, 0, 720, 725, 730, 750, 0,
1100 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1101 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1102
1103 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
1104 1430, 1650, 0, 720, 725, 730, 750, 0,
1105 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1106 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1107
1108 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
1109 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
1110 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1111 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1112
1113 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
1114 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
1115 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1116 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1117
1118 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
1119 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1120 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1121 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1122
1123 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
1124 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
1125 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1126 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1127
1128 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
1129 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1130 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1131 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1132
1133 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
1134 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
1135 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1136 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1137
1138 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
1139 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1140 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1141 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1142
1143 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 3040,
1144 3080, 3300, 0, 720, 725, 730, 750, 0,
1145 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1146 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1147
1148 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2908,
1149 2948, 3168, 0, 720, 725, 730, 750, 0,
1150 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1151 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1152
1153 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2380,
1154 2420, 2640, 0, 720, 725, 730, 750, 0,
1155 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1156 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1157
1158 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 82500, 1680, 1940,
1159 1980, 2200, 0, 720, 725, 730, 750, 0,
1160 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1161 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1162
1163 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 1940,
1164 1980, 2200, 0, 720, 725, 730, 750, 0,
1165 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1166 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1167
1168 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 165000, 1680, 1740,
1169 1780, 2000, 0, 720, 725, 730, 825, 0,
1170 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1171 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1172
1173 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 198000, 1680, 1740,
1174 1780, 2000, 0, 720, 725, 730, 825, 0,
1175 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1176 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1177
1178 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 99000, 2560, 3558,
1179 3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
1180 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1181 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1182
1183 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 90000, 2560, 3008,
1184 3052, 3200, 0, 1080, 1084, 1089, 1125, 0,
1185 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1186 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1187
1188 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 118800, 2560, 3328,
1189 3372, 3520, 0, 1080, 1084, 1089, 1125, 0,
1190 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1191 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1192
1193 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 185625, 2560, 3108,
1194 3152, 3300, 0, 1080, 1084, 1089, 1125, 0,
1195 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1196 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1197
1198 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 2808,
1199 2852, 3000, 0, 1080, 1084, 1089, 1100, 0,
1200 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1201 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1202
1203 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 371250, 2560, 2778,
1204 2822, 2970, 0, 1080, 1084, 1089, 1250, 0,
1205 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1206 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1207
1208 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 495000, 2560, 3108,
1209 3152, 3300, 0, 1080, 1084, 1089, 1250, 0,
1210 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1211 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1212
1213 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
1214 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
1215 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1216 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1217
1218 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
1219 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1220 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1221 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1222
1223 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
1224 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
1225 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1226 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1227
1228 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
1229 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1230 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1231 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1232
1233 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
1234 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
1235 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1236 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1237
1238 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5116,
1239 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
1240 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1241 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1242
1243 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5064,
1244 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
1245 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1246 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1247
1248 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
1249 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
1250 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1251 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1252
1253 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
1254 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
1255 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1256 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1257
1258 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
1259 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
1260 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1261 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1262
1263 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
1264 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
1265 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1266 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1267
1268 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
1269 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1270 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1271 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1272
1273 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
1274 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
1275 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1276 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1277
1278 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
1279 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1280 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1281 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1282
1283 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
1284 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
1285 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1286 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1287
1288 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 90000, 1280, 2240,
1289 2280, 2500, 0, 720, 725, 730, 750, 0,
1290 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1291 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1292
1293 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 90000, 1280, 2240,
1294 2280, 2500, 0, 720, 725, 730, 750, 0,
1295 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1296 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1297
1298 { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490,
1299 2530, 2750, 0, 720, 725, 730, 750, 0,
1300 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1301 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1302
1303 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
1304 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
1305 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1306 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1307
1308 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
1309 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
1310 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1311 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1312
1313 { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558,
1314 3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
1315 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1316 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1317
1318 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
1319 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
1320 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1321 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1322
1323 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116,
1324 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
1325 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1326 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1327
1328 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
1329 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
1330 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1331 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1332
1333 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
1334 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1335 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1336 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1337
1338 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
1339 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
1340 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1341 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1342
1343 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
1344 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1345 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1346 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1347
1348 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
1349 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
1350 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1351 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1352
1353 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 7116,
1354 7204, 7500, 0, 2160, 2168, 2178, 2200, 0,
1355 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1356 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1357
1358 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 6816,
1359 6904, 7200, 0, 2160, 2168, 2178, 2200, 0,
1360 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1361 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1362
1363 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 5784,
1364 5872, 6000, 0, 2160, 2168, 2178, 2200, 0,
1365 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1366 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1367
1368 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 5866,
1369 5954, 6250, 0, 2160, 2168, 2178, 2475, 0,
1370 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1371 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1372
1373 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 6216,
1374 6304, 6600, 0, 2160, 2168, 2178, 2250, 0,
1375 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1376 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1377
1378 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 5284,
1379 5372, 5500, 0, 2160, 2168, 2178, 2250, 0,
1380 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1381 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1382
1383 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 1485000, 5120, 6216,
1384 6304, 6600, 0, 2160, 2168, 2178, 2250, 0,
1385 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1386 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1387 };
1388
1389
1390
1391
1392
1393
1394 static const struct drm_display_mode edid_cea_modes_193[] = {
1395
1396 { DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 1485000, 5120, 5284,
1397 5372, 5500, 0, 2160, 2168, 2178, 2250, 0,
1398 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1399 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1400
1401 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10232,
1402 10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
1403 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1404 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1405
1406 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10032,
1407 10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
1408 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1409 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1410
1411 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 8232,
1412 8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
1413 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1414 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1415
1416 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10232,
1417 10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
1418 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1419 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1420
1421 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10032,
1422 10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
1423 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1424 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1425
1426 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 8232,
1427 8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
1428 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1429 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1430
1431 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 9792,
1432 9968, 10560, 0, 4320, 4336, 4356, 4500, 0,
1433 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1434 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1435
1436 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 8032,
1437 8208, 8800, 0, 4320, 4336, 4356, 4500, 0,
1438 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1439 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1440
1441 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10232,
1442 10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
1443 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1444 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1445
1446 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10032,
1447 10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
1448 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1449 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1450
1451 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 8232,
1452 8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
1453 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1454 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1455
1456 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10232,
1457 10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
1458 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1459 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1460
1461 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10032,
1462 10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
1463 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1464 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1465
1466 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 8232,
1467 8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
1468 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1469 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1470
1471 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 9792,
1472 9968, 10560, 0, 4320, 4336, 4356, 4500, 0,
1473 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1474 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1475
1476 { DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 8032,
1477 8208, 8800, 0, 4320, 4336, 4356, 4500, 0,
1478 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1479 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1480
1481 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 1485000, 10240, 11732,
1482 11908, 12500, 0, 4320, 4336, 4356, 4950, 0,
1483 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1484 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1485
1486 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 1485000, 10240, 12732,
1487 12908, 13500, 0, 4320, 4336, 4356, 4400, 0,
1488 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1489 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1490
1491 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 1485000, 10240, 10528,
1492 10704, 11000, 0, 4320, 4336, 4356, 4500, 0,
1493 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1494 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1495
1496 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 2970000, 10240, 11732,
1497 11908, 12500, 0, 4320, 4336, 4356, 4950, 0,
1498 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1499 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1500
1501 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 2970000, 10240, 12732,
1502 12908, 13500, 0, 4320, 4336, 4356, 4400, 0,
1503 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1504 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1505
1506 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 2970000, 10240, 10528,
1507 10704, 11000, 0, 4320, 4336, 4356, 4500, 0,
1508 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1509 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1510
1511 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 5940000, 10240, 12432,
1512 12608, 13200, 0, 4320, 4336, 4356, 4500, 0,
1513 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1514 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1515
1516 { DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 5940000, 10240, 10528,
1517 10704, 11000, 0, 4320, 4336, 4356, 4500, 0,
1518 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1519 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
1520
1521 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 1188000, 4096, 4896,
1522 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
1523 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1524 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1525
1526 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 1188000, 4096, 4184,
1527 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
1528 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1529 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1530 };
1531
1532
1533
1534
1535 static const struct drm_display_mode edid_4k_modes[] = {
1536
1537 { },
1538
1539 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
1540 3840, 4016, 4104, 4400, 0,
1541 2160, 2168, 2178, 2250, 0,
1542 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1543 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1544
1545 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
1546 3840, 4896, 4984, 5280, 0,
1547 2160, 2168, 2178, 2250, 0,
1548 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1549 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1550
1551 { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
1552 3840, 5116, 5204, 5500, 0,
1553 2160, 2168, 2178, 2250, 0,
1554 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1555 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
1556
1557 { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000,
1558 4096, 5116, 5204, 5500, 0,
1559 2160, 2168, 2178, 2250, 0,
1560 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
1561 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
1562 };
1563
1564
1565
1566
1567
1568
1569 struct drm_edid {
1570
1571 size_t size;
1572 const struct edid *edid;
1573 };
1574
1575 static bool version_greater(const struct drm_edid *drm_edid,
1576 u8 version, u8 revision)
1577 {
1578 const struct edid *edid = drm_edid->edid;
1579
1580 return edid->version > version ||
1581 (edid->version == version && edid->revision > revision);
1582 }
1583
1584 static int edid_hfeeodb_extension_block_count(const struct edid *edid);
1585
1586 static int edid_hfeeodb_block_count(const struct edid *edid)
1587 {
1588 int eeodb = edid_hfeeodb_extension_block_count(edid);
1589
1590 return eeodb ? eeodb + 1 : 0;
1591 }
1592
1593 static int edid_extension_block_count(const struct edid *edid)
1594 {
1595 return edid->extensions;
1596 }
1597
1598 static int edid_block_count(const struct edid *edid)
1599 {
1600 return edid_extension_block_count(edid) + 1;
1601 }
1602
1603 static int edid_size_by_blocks(int num_blocks)
1604 {
1605 return num_blocks * EDID_LENGTH;
1606 }
1607
1608 static int edid_size(const struct edid *edid)
1609 {
1610 return edid_size_by_blocks(edid_block_count(edid));
1611 }
1612
1613 static const void *edid_block_data(const struct edid *edid, int index)
1614 {
1615 BUILD_BUG_ON(sizeof(*edid) != EDID_LENGTH);
1616
1617 return edid + index;
1618 }
1619
1620 static const void *edid_extension_block_data(const struct edid *edid, int index)
1621 {
1622 return edid_block_data(edid, index + 1);
1623 }
1624
1625 static int drm_edid_block_count(const struct drm_edid *drm_edid)
1626 {
1627 int num_blocks;
1628
1629
1630 num_blocks = edid_block_count(drm_edid->edid);
1631
1632
1633 if (drm_edid->size >= edid_size_by_blocks(2)) {
1634 int eeodb;
1635
1636
1637
1638
1639
1640 eeodb = edid_hfeeodb_block_count(drm_edid->edid);
1641 if (eeodb)
1642 num_blocks = eeodb;
1643 }
1644
1645
1646 num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
1647
1648 return num_blocks;
1649 }
1650
1651 static int drm_edid_extension_block_count(const struct drm_edid *drm_edid)
1652 {
1653 return drm_edid_block_count(drm_edid) - 1;
1654 }
1655
1656 static const void *drm_edid_block_data(const struct drm_edid *drm_edid, int index)
1657 {
1658 return edid_block_data(drm_edid->edid, index);
1659 }
1660
1661 static const void *drm_edid_extension_block_data(const struct drm_edid *drm_edid,
1662 int index)
1663 {
1664 return edid_extension_block_data(drm_edid->edid, index);
1665 }
1666
1667
1668
1669
1670
1671 static const struct drm_edid *drm_edid_legacy_init(struct drm_edid *drm_edid,
1672 const struct edid *edid)
1673 {
1674 if (!edid)
1675 return NULL;
1676
1677 memset(drm_edid, 0, sizeof(*drm_edid));
1678
1679 drm_edid->edid = edid;
1680 drm_edid->size = edid_size(edid);
1681
1682 return drm_edid;
1683 }
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697 struct drm_edid_iter {
1698 const struct drm_edid *drm_edid;
1699
1700
1701 int index;
1702 };
1703
1704 static void drm_edid_iter_begin(const struct drm_edid *drm_edid,
1705 struct drm_edid_iter *iter)
1706 {
1707 memset(iter, 0, sizeof(*iter));
1708
1709 iter->drm_edid = drm_edid;
1710 }
1711
1712 static const void *__drm_edid_iter_next(struct drm_edid_iter *iter)
1713 {
1714 const void *block = NULL;
1715
1716 if (!iter->drm_edid)
1717 return NULL;
1718
1719 if (iter->index < drm_edid_block_count(iter->drm_edid))
1720 block = drm_edid_block_data(iter->drm_edid, iter->index++);
1721
1722 return block;
1723 }
1724
1725 #define drm_edid_iter_for_each(__block, __iter) \
1726 while (((__block) = __drm_edid_iter_next(__iter)))
1727
1728 static void drm_edid_iter_end(struct drm_edid_iter *iter)
1729 {
1730 memset(iter, 0, sizeof(*iter));
1731 }
1732
1733 static const u8 edid_header[] = {
1734 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
1735 };
1736
1737 static void edid_header_fix(void *edid)
1738 {
1739 memcpy(edid, edid_header, sizeof(edid_header));
1740 }
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750 int drm_edid_header_is_valid(const void *_edid)
1751 {
1752 const struct edid *edid = _edid;
1753 int i, score = 0;
1754
1755 for (i = 0; i < sizeof(edid_header); i++) {
1756 if (edid->header[i] == edid_header[i])
1757 score++;
1758 }
1759
1760 return score;
1761 }
1762 EXPORT_SYMBOL(drm_edid_header_is_valid);
1763
1764 static int edid_fixup __read_mostly = 6;
1765 module_param_named(edid_fixup, edid_fixup, int, 0400);
1766 MODULE_PARM_DESC(edid_fixup,
1767 "Minimum number of valid EDID header bytes (0-8, default 6)");
1768
1769 static int edid_block_compute_checksum(const void *_block)
1770 {
1771 const u8 *block = _block;
1772 int i;
1773 u8 csum = 0, crc = 0;
1774
1775 for (i = 0; i < EDID_LENGTH - 1; i++)
1776 csum += block[i];
1777
1778 crc = 0x100 - csum;
1779
1780 return crc;
1781 }
1782
1783 static int edid_block_get_checksum(const void *_block)
1784 {
1785 const struct edid *block = _block;
1786
1787 return block->checksum;
1788 }
1789
1790 static int edid_block_tag(const void *_block)
1791 {
1792 const u8 *block = _block;
1793
1794 return block[0];
1795 }
1796
1797 static bool edid_block_is_zero(const void *edid)
1798 {
1799 return !memchr_inv(edid, 0, EDID_LENGTH);
1800 }
1801
1802
1803
1804
1805
1806
1807
1808
1809 bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
1810 {
1811 int edid1_len, edid2_len;
1812 bool edid1_present = edid1 != NULL;
1813 bool edid2_present = edid2 != NULL;
1814
1815 if (edid1_present != edid2_present)
1816 return false;
1817
1818 if (edid1) {
1819 edid1_len = edid_size(edid1);
1820 edid2_len = edid_size(edid2);
1821
1822 if (edid1_len != edid2_len)
1823 return false;
1824
1825 if (memcmp(edid1, edid2, edid1_len))
1826 return false;
1827 }
1828
1829 return true;
1830 }
1831 EXPORT_SYMBOL(drm_edid_are_equal);
1832
1833 enum edid_block_status {
1834 EDID_BLOCK_OK = 0,
1835 EDID_BLOCK_READ_FAIL,
1836 EDID_BLOCK_NULL,
1837 EDID_BLOCK_ZERO,
1838 EDID_BLOCK_HEADER_CORRUPT,
1839 EDID_BLOCK_HEADER_REPAIR,
1840 EDID_BLOCK_HEADER_FIXED,
1841 EDID_BLOCK_CHECKSUM,
1842 EDID_BLOCK_VERSION,
1843 };
1844
1845 static enum edid_block_status edid_block_check(const void *_block,
1846 bool is_base_block)
1847 {
1848 const struct edid *block = _block;
1849
1850 if (!block)
1851 return EDID_BLOCK_NULL;
1852
1853 if (is_base_block) {
1854 int score = drm_edid_header_is_valid(block);
1855
1856 if (score < clamp(edid_fixup, 0, 8)) {
1857 if (edid_block_is_zero(block))
1858 return EDID_BLOCK_ZERO;
1859 else
1860 return EDID_BLOCK_HEADER_CORRUPT;
1861 }
1862
1863 if (score < 8)
1864 return EDID_BLOCK_HEADER_REPAIR;
1865 }
1866
1867 if (edid_block_compute_checksum(block) != edid_block_get_checksum(block)) {
1868 if (edid_block_is_zero(block))
1869 return EDID_BLOCK_ZERO;
1870 else
1871 return EDID_BLOCK_CHECKSUM;
1872 }
1873
1874 if (is_base_block) {
1875 if (block->version != 1)
1876 return EDID_BLOCK_VERSION;
1877 }
1878
1879 return EDID_BLOCK_OK;
1880 }
1881
1882 static bool edid_block_status_valid(enum edid_block_status status, int tag)
1883 {
1884 return status == EDID_BLOCK_OK ||
1885 status == EDID_BLOCK_HEADER_FIXED ||
1886 (status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
1887 }
1888
1889 static bool edid_block_valid(const void *block, bool base)
1890 {
1891 return edid_block_status_valid(edid_block_check(block, base),
1892 edid_block_tag(block));
1893 }
1894
1895 static void edid_block_status_print(enum edid_block_status status,
1896 const struct edid *block,
1897 int block_num)
1898 {
1899 switch (status) {
1900 case EDID_BLOCK_OK:
1901 break;
1902 case EDID_BLOCK_READ_FAIL:
1903 pr_debug("EDID block %d read failed\n", block_num);
1904 break;
1905 case EDID_BLOCK_NULL:
1906 pr_debug("EDID block %d pointer is NULL\n", block_num);
1907 break;
1908 case EDID_BLOCK_ZERO:
1909 pr_notice("EDID block %d is all zeroes\n", block_num);
1910 break;
1911 case EDID_BLOCK_HEADER_CORRUPT:
1912 pr_notice("EDID has corrupt header\n");
1913 break;
1914 case EDID_BLOCK_HEADER_REPAIR:
1915 pr_debug("EDID corrupt header needs repair\n");
1916 break;
1917 case EDID_BLOCK_HEADER_FIXED:
1918 pr_debug("EDID corrupt header fixed\n");
1919 break;
1920 case EDID_BLOCK_CHECKSUM:
1921 if (edid_block_status_valid(status, edid_block_tag(block))) {
1922 pr_debug("EDID block %d (tag 0x%02x) checksum is invalid, remainder is %d, ignoring\n",
1923 block_num, edid_block_tag(block),
1924 edid_block_compute_checksum(block));
1925 } else {
1926 pr_notice("EDID block %d (tag 0x%02x) checksum is invalid, remainder is %d\n",
1927 block_num, edid_block_tag(block),
1928 edid_block_compute_checksum(block));
1929 }
1930 break;
1931 case EDID_BLOCK_VERSION:
1932 pr_notice("EDID has major version %d, instead of 1\n",
1933 block->version);
1934 break;
1935 default:
1936 WARN(1, "EDID block %d unknown edid block status code %d\n",
1937 block_num, status);
1938 break;
1939 }
1940 }
1941
1942 static void edid_block_dump(const char *level, const void *block, int block_num)
1943 {
1944 enum edid_block_status status;
1945 char prefix[20];
1946
1947 status = edid_block_check(block, block_num == 0);
1948 if (status == EDID_BLOCK_ZERO)
1949 sprintf(prefix, "\t[%02x] ZERO ", block_num);
1950 else if (!edid_block_status_valid(status, edid_block_tag(block)))
1951 sprintf(prefix, "\t[%02x] BAD ", block_num);
1952 else
1953 sprintf(prefix, "\t[%02x] GOOD ", block_num);
1954
1955 print_hex_dump(level, prefix, DUMP_PREFIX_NONE, 16, 1,
1956 block, EDID_LENGTH, false);
1957 }
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971 bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
1972 bool *edid_corrupt)
1973 {
1974 struct edid *block = (struct edid *)_block;
1975 enum edid_block_status status;
1976 bool is_base_block = block_num == 0;
1977 bool valid;
1978
1979 if (WARN_ON(!block))
1980 return false;
1981
1982 status = edid_block_check(block, is_base_block);
1983 if (status == EDID_BLOCK_HEADER_REPAIR) {
1984 DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
1985 edid_header_fix(block);
1986
1987
1988 status = edid_block_check(block, is_base_block);
1989 if (status == EDID_BLOCK_OK)
1990 status = EDID_BLOCK_HEADER_FIXED;
1991 }
1992
1993 if (edid_corrupt) {
1994
1995
1996
1997
1998 if (is_base_block &&
1999 (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
2000 *edid_corrupt = false;
2001 else if (status != EDID_BLOCK_OK)
2002 *edid_corrupt = true;
2003 }
2004
2005 edid_block_status_print(status, block, block_num);
2006
2007
2008 valid = edid_block_status_valid(status, edid_block_tag(block));
2009
2010 if (!valid && print_bad_edid && status != EDID_BLOCK_ZERO) {
2011 pr_notice("Raw EDID:\n");
2012 edid_block_dump(KERN_NOTICE, block, block_num);
2013 }
2014
2015 return valid;
2016 }
2017 EXPORT_SYMBOL(drm_edid_block_valid);
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027 bool drm_edid_is_valid(struct edid *edid)
2028 {
2029 int i;
2030
2031 if (!edid)
2032 return false;
2033
2034 for (i = 0; i < edid_block_count(edid); i++) {
2035 void *block = (void *)edid_block_data(edid, i);
2036
2037 if (!drm_edid_block_valid(block, i, true, NULL))
2038 return false;
2039 }
2040
2041 return true;
2042 }
2043 EXPORT_SYMBOL(drm_edid_is_valid);
2044
2045 static struct edid *edid_filter_invalid_blocks(struct edid *edid,
2046 size_t *alloc_size)
2047 {
2048 struct edid *new;
2049 int i, valid_blocks = 0;
2050
2051
2052
2053
2054
2055
2056 for (i = 0; i < edid_block_count(edid); i++) {
2057 const void *src_block = edid_block_data(edid, i);
2058
2059 if (edid_block_valid(src_block, i == 0)) {
2060 void *dst_block = (void *)edid_block_data(edid, valid_blocks);
2061
2062 memmove(dst_block, src_block, EDID_LENGTH);
2063 valid_blocks++;
2064 }
2065 }
2066
2067
2068 if (WARN_ON(!valid_blocks)) {
2069 kfree(edid);
2070 return NULL;
2071 }
2072
2073 edid->extensions = valid_blocks - 1;
2074 edid->checksum = edid_block_compute_checksum(edid);
2075
2076 *alloc_size = edid_size_by_blocks(valid_blocks);
2077
2078 new = krealloc(edid, *alloc_size, GFP_KERNEL);
2079 if (!new)
2080 kfree(edid);
2081
2082 return new;
2083 }
2084
2085 #define DDC_SEGMENT_ADDR 0x30
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097 static int
2098 drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
2099 {
2100 struct i2c_adapter *adapter = data;
2101 unsigned char start = block * EDID_LENGTH;
2102 unsigned char segment = block >> 1;
2103 unsigned char xfers = segment ? 3 : 2;
2104 int ret, retries = 5;
2105
2106
2107
2108
2109
2110
2111
2112
2113 do {
2114 struct i2c_msg msgs[] = {
2115 {
2116 .addr = DDC_SEGMENT_ADDR,
2117 .flags = 0,
2118 .len = 1,
2119 .buf = &segment,
2120 }, {
2121 .addr = DDC_ADDR,
2122 .flags = 0,
2123 .len = 1,
2124 .buf = &start,
2125 }, {
2126 .addr = DDC_ADDR,
2127 .flags = I2C_M_RD,
2128 .len = len,
2129 .buf = buf,
2130 }
2131 };
2132
2133
2134
2135
2136
2137 ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
2138
2139 if (ret == -ENXIO) {
2140 DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
2141 adapter->name);
2142 break;
2143 }
2144 } while (ret != xfers && --retries);
2145
2146 return ret == xfers ? 0 : -1;
2147 }
2148
2149 static void connector_bad_edid(struct drm_connector *connector,
2150 const struct edid *edid, int num_blocks)
2151 {
2152 int i;
2153 u8 last_block;
2154
2155
2156
2157
2158
2159
2160
2161 last_block = edid->extensions;
2162
2163
2164 if (last_block < num_blocks)
2165 connector->real_edid_checksum =
2166 edid_block_compute_checksum(edid + last_block);
2167
2168 if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
2169 return;
2170
2171 drm_dbg_kms(connector->dev, "%s: EDID is invalid:\n", connector->name);
2172 for (i = 0; i < num_blocks; i++)
2173 edid_block_dump(KERN_DEBUG, edid + i, i);
2174 }
2175
2176
2177 static struct edid *drm_get_override_edid(struct drm_connector *connector,
2178 size_t *alloc_size)
2179 {
2180 struct edid *override = NULL;
2181
2182 if (connector->override_edid)
2183 override = drm_edid_duplicate(connector->edid_blob_ptr->data);
2184
2185 if (!override)
2186 override = drm_load_edid_firmware(connector);
2187
2188
2189 if (!IS_ERR_OR_NULL(override) && alloc_size)
2190 *alloc_size = edid_size(override);
2191
2192 return IS_ERR(override) ? NULL : override;
2193 }
2194
2195
2196 int drm_edid_override_set(struct drm_connector *connector, const void *edid,
2197 size_t size)
2198 {
2199 int ret;
2200
2201 if (size < EDID_LENGTH || edid_size(edid) > size)
2202 return -EINVAL;
2203
2204 connector->override_edid = false;
2205
2206 ret = drm_connector_update_edid_property(connector, edid);
2207 if (!ret)
2208 connector->override_edid = true;
2209
2210 return ret;
2211 }
2212
2213
2214 int drm_edid_override_reset(struct drm_connector *connector)
2215 {
2216 connector->override_edid = false;
2217
2218 return drm_connector_update_edid_property(connector, NULL);
2219 }
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232 int drm_add_override_edid_modes(struct drm_connector *connector)
2233 {
2234 struct edid *override;
2235 int num_modes = 0;
2236
2237 override = drm_get_override_edid(connector, NULL);
2238 if (override) {
2239 drm_connector_update_edid_property(connector, override);
2240 num_modes = drm_add_edid_modes(connector, override);
2241 kfree(override);
2242
2243 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] adding %d modes via fallback override/firmware EDID\n",
2244 connector->base.id, connector->name, num_modes);
2245 }
2246
2247 return num_modes;
2248 }
2249 EXPORT_SYMBOL(drm_add_override_edid_modes);
2250
2251 typedef int read_block_fn(void *context, u8 *buf, unsigned int block, size_t len);
2252
2253 static enum edid_block_status edid_block_read(void *block, unsigned int block_num,
2254 read_block_fn read_block,
2255 void *context)
2256 {
2257 enum edid_block_status status;
2258 bool is_base_block = block_num == 0;
2259 int try;
2260
2261 for (try = 0; try < 4; try++) {
2262 if (read_block(context, block, block_num, EDID_LENGTH))
2263 return EDID_BLOCK_READ_FAIL;
2264
2265 status = edid_block_check(block, is_base_block);
2266 if (status == EDID_BLOCK_HEADER_REPAIR) {
2267 edid_header_fix(block);
2268
2269
2270 status = edid_block_check(block, is_base_block);
2271 if (status == EDID_BLOCK_OK)
2272 status = EDID_BLOCK_HEADER_FIXED;
2273 }
2274
2275 if (edid_block_status_valid(status, edid_block_tag(block)))
2276 break;
2277
2278
2279 if (try == 0 && is_base_block && status == EDID_BLOCK_ZERO)
2280 break;
2281 }
2282
2283 return status;
2284 }
2285
2286 static struct edid *_drm_do_get_edid(struct drm_connector *connector,
2287 read_block_fn read_block, void *context,
2288 size_t *size)
2289 {
2290 enum edid_block_status status;
2291 int i, num_blocks, invalid_blocks = 0;
2292 struct edid *edid, *new;
2293 size_t alloc_size = EDID_LENGTH;
2294
2295 edid = drm_get_override_edid(connector, &alloc_size);
2296 if (edid)
2297 goto ok;
2298
2299 edid = kmalloc(alloc_size, GFP_KERNEL);
2300 if (!edid)
2301 return NULL;
2302
2303 status = edid_block_read(edid, 0, read_block, context);
2304
2305 edid_block_status_print(status, edid, 0);
2306
2307 if (status == EDID_BLOCK_READ_FAIL)
2308 goto fail;
2309
2310
2311 if (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION)
2312 connector->edid_corrupt = false;
2313 else
2314 connector->edid_corrupt = true;
2315
2316 if (!edid_block_status_valid(status, edid_block_tag(edid))) {
2317 if (status == EDID_BLOCK_ZERO)
2318 connector->null_edid_counter++;
2319
2320 connector_bad_edid(connector, edid, 1);
2321 goto fail;
2322 }
2323
2324 if (!edid_extension_block_count(edid))
2325 goto ok;
2326
2327 alloc_size = edid_size(edid);
2328 new = krealloc(edid, alloc_size, GFP_KERNEL);
2329 if (!new)
2330 goto fail;
2331 edid = new;
2332
2333 num_blocks = edid_block_count(edid);
2334 for (i = 1; i < num_blocks; i++) {
2335 void *block = (void *)edid_block_data(edid, i);
2336
2337 status = edid_block_read(block, i, read_block, context);
2338
2339 edid_block_status_print(status, block, i);
2340
2341 if (!edid_block_status_valid(status, edid_block_tag(block))) {
2342 if (status == EDID_BLOCK_READ_FAIL)
2343 goto fail;
2344 invalid_blocks++;
2345 } else if (i == 1) {
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355 int eeodb = edid_hfeeodb_block_count(edid);
2356
2357 if (eeodb > num_blocks) {
2358 num_blocks = eeodb;
2359 alloc_size = edid_size_by_blocks(num_blocks);
2360 new = krealloc(edid, alloc_size, GFP_KERNEL);
2361 if (!new)
2362 goto fail;
2363 edid = new;
2364 }
2365 }
2366 }
2367
2368 if (invalid_blocks) {
2369 connector_bad_edid(connector, edid, num_blocks);
2370
2371 edid = edid_filter_invalid_blocks(edid, &alloc_size);
2372 }
2373
2374 ok:
2375 if (size)
2376 *size = alloc_size;
2377
2378 return edid;
2379
2380 fail:
2381 kfree(edid);
2382 return NULL;
2383 }
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405 struct edid *drm_do_get_edid(struct drm_connector *connector,
2406 read_block_fn read_block,
2407 void *context)
2408 {
2409 return _drm_do_get_edid(connector, read_block, context, NULL);
2410 }
2411 EXPORT_SYMBOL_GPL(drm_do_get_edid);
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423 const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
2424 {
2425 if (!drm_edid || !drm_edid->size)
2426 return NULL;
2427
2428
2429
2430
2431
2432 if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
2433 return NULL;
2434
2435 return drm_edid->edid;
2436 }
2437 EXPORT_SYMBOL(drm_edid_raw);
2438
2439
2440 static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
2441 {
2442 struct drm_edid *drm_edid;
2443
2444 if (!edid || !size || size < EDID_LENGTH)
2445 return NULL;
2446
2447 drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
2448 if (drm_edid) {
2449 drm_edid->edid = edid;
2450 drm_edid->size = size;
2451 }
2452
2453 return drm_edid;
2454 }
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470 const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
2471 {
2472 const struct drm_edid *drm_edid;
2473
2474 if (!edid || !size || size < EDID_LENGTH)
2475 return NULL;
2476
2477 edid = kmemdup(edid, size, GFP_KERNEL);
2478 if (!edid)
2479 return NULL;
2480
2481 drm_edid = _drm_edid_alloc(edid, size);
2482 if (!drm_edid)
2483 kfree(edid);
2484
2485 return drm_edid;
2486 }
2487 EXPORT_SYMBOL(drm_edid_alloc);
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497 const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
2498 {
2499 if (!drm_edid)
2500 return NULL;
2501
2502 return drm_edid_alloc(drm_edid->edid, drm_edid->size);
2503 }
2504 EXPORT_SYMBOL(drm_edid_dup);
2505
2506
2507
2508
2509
2510 void drm_edid_free(const struct drm_edid *drm_edid)
2511 {
2512 if (!drm_edid)
2513 return;
2514
2515 kfree(drm_edid->edid);
2516 kfree(drm_edid);
2517 }
2518 EXPORT_SYMBOL(drm_edid_free);
2519
2520
2521
2522
2523
2524
2525
2526 bool
2527 drm_probe_ddc(struct i2c_adapter *adapter)
2528 {
2529 unsigned char out;
2530
2531 return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
2532 }
2533 EXPORT_SYMBOL(drm_probe_ddc);
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545 struct edid *drm_get_edid(struct drm_connector *connector,
2546 struct i2c_adapter *adapter)
2547 {
2548 struct edid *edid;
2549
2550 if (connector->force == DRM_FORCE_OFF)
2551 return NULL;
2552
2553 if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
2554 return NULL;
2555
2556 edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
2557 drm_connector_update_edid_property(connector, edid);
2558 return edid;
2559 }
2560 EXPORT_SYMBOL(drm_get_edid);
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585 const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
2586 read_block_fn read_block,
2587 void *context)
2588 {
2589 const struct drm_edid *drm_edid;
2590 struct edid *edid;
2591 size_t size = 0;
2592
2593 edid = _drm_do_get_edid(connector, read_block, context, &size);
2594 if (!edid)
2595 return NULL;
2596
2597
2598 drm_WARN_ON(connector->dev, !size);
2599
2600 drm_edid = _drm_edid_alloc(edid, size);
2601 if (!drm_edid)
2602 kfree(edid);
2603
2604 return drm_edid;
2605 }
2606 EXPORT_SYMBOL(drm_edid_read_custom);
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626 const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
2627 struct i2c_adapter *adapter)
2628 {
2629 const struct drm_edid *drm_edid;
2630
2631 if (connector->force == DRM_FORCE_OFF)
2632 return NULL;
2633
2634 if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
2635 return NULL;
2636
2637 drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
2638
2639
2640
2641 return drm_edid;
2642 }
2643 EXPORT_SYMBOL(drm_edid_read_ddc);
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659 const struct drm_edid *drm_edid_read(struct drm_connector *connector)
2660 {
2661 if (drm_WARN_ON(connector->dev, !connector->ddc))
2662 return NULL;
2663
2664 return drm_edid_read_ddc(connector, connector->ddc);
2665 }
2666 EXPORT_SYMBOL(drm_edid_read);
2667
2668 static u32 edid_extract_panel_id(const struct edid *edid)
2669 {
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683 return (u32)edid->mfg_id[0] << 24 |
2684 (u32)edid->mfg_id[1] << 16 |
2685 (u32)EDID_PRODUCT_ID(edid);
2686 }
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712 u32 drm_edid_get_panel_id(struct i2c_adapter *adapter)
2713 {
2714 enum edid_block_status status;
2715 void *base_block;
2716 u32 panel_id = 0;
2717
2718
2719
2720
2721
2722
2723 base_block = kmalloc(EDID_LENGTH, GFP_KERNEL);
2724 if (!base_block)
2725 return 0;
2726
2727 status = edid_block_read(base_block, 0, drm_do_probe_ddc_edid, adapter);
2728
2729 edid_block_status_print(status, base_block, 0);
2730
2731 if (edid_block_status_valid(status, edid_block_tag(base_block)))
2732 panel_id = edid_extract_panel_id(base_block);
2733
2734 kfree(base_block);
2735
2736 return panel_id;
2737 }
2738 EXPORT_SYMBOL(drm_edid_get_panel_id);
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751 struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
2752 struct i2c_adapter *adapter)
2753 {
2754 struct drm_device *dev = connector->dev;
2755 struct pci_dev *pdev = to_pci_dev(dev->dev);
2756 struct edid *edid;
2757
2758 if (drm_WARN_ON_ONCE(dev, !dev_is_pci(dev->dev)))
2759 return NULL;
2760
2761 vga_switcheroo_lock_ddc(pdev);
2762 edid = drm_get_edid(connector, adapter);
2763 vga_switcheroo_unlock_ddc(pdev);
2764
2765 return edid;
2766 }
2767 EXPORT_SYMBOL(drm_get_edid_switcheroo);
2768
2769
2770
2771
2772
2773
2774
2775 struct edid *drm_edid_duplicate(const struct edid *edid)
2776 {
2777 return kmemdup(edid, edid_size(edid), GFP_KERNEL);
2778 }
2779 EXPORT_SYMBOL(drm_edid_duplicate);
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789 static u32 edid_get_quirks(const struct drm_edid *drm_edid)
2790 {
2791 u32 panel_id = edid_extract_panel_id(drm_edid->edid);
2792 const struct edid_quirk *quirk;
2793 int i;
2794
2795 for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
2796 quirk = &edid_quirk_list[i];
2797 if (quirk->panel_id == panel_id)
2798 return quirk->quirks;
2799 }
2800
2801 return 0;
2802 }
2803
2804 #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
2805 #define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
2806
2807
2808
2809
2810
2811 static void edid_fixup_preferred(struct drm_connector *connector,
2812 u32 quirks)
2813 {
2814 struct drm_display_mode *t, *cur_mode, *preferred_mode;
2815 int target_refresh = 0;
2816 int cur_vrefresh, preferred_vrefresh;
2817
2818 if (list_empty(&connector->probed_modes))
2819 return;
2820
2821 if (quirks & EDID_QUIRK_PREFER_LARGE_60)
2822 target_refresh = 60;
2823 if (quirks & EDID_QUIRK_PREFER_LARGE_75)
2824 target_refresh = 75;
2825
2826 preferred_mode = list_first_entry(&connector->probed_modes,
2827 struct drm_display_mode, head);
2828
2829 list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
2830 cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
2831
2832 if (cur_mode == preferred_mode)
2833 continue;
2834
2835
2836 if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
2837 preferred_mode = cur_mode;
2838
2839 cur_vrefresh = drm_mode_vrefresh(cur_mode);
2840 preferred_vrefresh = drm_mode_vrefresh(preferred_mode);
2841
2842 if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
2843 MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
2844 MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
2845 preferred_mode = cur_mode;
2846 }
2847 }
2848
2849 preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
2850 }
2851
2852 static bool
2853 mode_is_rb(const struct drm_display_mode *mode)
2854 {
2855 return (mode->htotal - mode->hdisplay == 160) &&
2856 (mode->hsync_end - mode->hdisplay == 80) &&
2857 (mode->hsync_end - mode->hsync_start == 32) &&
2858 (mode->vsync_start - mode->vdisplay == 3);
2859 }
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873 struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
2874 int hsize, int vsize, int fresh,
2875 bool rb)
2876 {
2877 int i;
2878
2879 for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
2880 const struct drm_display_mode *ptr = &drm_dmt_modes[i];
2881
2882 if (hsize != ptr->hdisplay)
2883 continue;
2884 if (vsize != ptr->vdisplay)
2885 continue;
2886 if (fresh != drm_mode_vrefresh(ptr))
2887 continue;
2888 if (rb != mode_is_rb(ptr))
2889 continue;
2890
2891 return drm_mode_duplicate(dev, ptr);
2892 }
2893
2894 return NULL;
2895 }
2896 EXPORT_SYMBOL(drm_mode_find_dmt);
2897
2898 static bool is_display_descriptor(const struct detailed_timing *descriptor, u8 type)
2899 {
2900 BUILD_BUG_ON(offsetof(typeof(*descriptor), pixel_clock) != 0);
2901 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.pad1) != 2);
2902 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.type) != 3);
2903
2904 return descriptor->pixel_clock == 0 &&
2905 descriptor->data.other_data.pad1 == 0 &&
2906 descriptor->data.other_data.type == type;
2907 }
2908
2909 static bool is_detailed_timing_descriptor(const struct detailed_timing *descriptor)
2910 {
2911 BUILD_BUG_ON(offsetof(typeof(*descriptor), pixel_clock) != 0);
2912
2913 return descriptor->pixel_clock != 0;
2914 }
2915
2916 typedef void detailed_cb(const struct detailed_timing *timing, void *closure);
2917
2918 static void
2919 cea_for_each_detailed_block(const u8 *ext, detailed_cb *cb, void *closure)
2920 {
2921 int i, n;
2922 u8 d = ext[0x02];
2923 const u8 *det_base = ext + d;
2924
2925 if (d < 4 || d > 127)
2926 return;
2927
2928 n = (127 - d) / 18;
2929 for (i = 0; i < n; i++)
2930 cb((const struct detailed_timing *)(det_base + 18 * i), closure);
2931 }
2932
2933 static void
2934 vtb_for_each_detailed_block(const u8 *ext, detailed_cb *cb, void *closure)
2935 {
2936 unsigned int i, n = min((int)ext[0x02], 6);
2937 const u8 *det_base = ext + 5;
2938
2939 if (ext[0x01] != 1)
2940 return;
2941
2942 for (i = 0; i < n; i++)
2943 cb((const struct detailed_timing *)(det_base + 18 * i), closure);
2944 }
2945
2946 static void drm_for_each_detailed_block(const struct drm_edid *drm_edid,
2947 detailed_cb *cb, void *closure)
2948 {
2949 struct drm_edid_iter edid_iter;
2950 const u8 *ext;
2951 int i;
2952
2953 if (!drm_edid)
2954 return;
2955
2956 for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
2957 cb(&drm_edid->edid->detailed_timings[i], closure);
2958
2959 drm_edid_iter_begin(drm_edid, &edid_iter);
2960 drm_edid_iter_for_each(ext, &edid_iter) {
2961 switch (*ext) {
2962 case CEA_EXT:
2963 cea_for_each_detailed_block(ext, cb, closure);
2964 break;
2965 case VTB_EXT:
2966 vtb_for_each_detailed_block(ext, cb, closure);
2967 break;
2968 default:
2969 break;
2970 }
2971 }
2972 drm_edid_iter_end(&edid_iter);
2973 }
2974
2975 static void
2976 is_rb(const struct detailed_timing *descriptor, void *data)
2977 {
2978 bool *res = data;
2979
2980 if (!is_display_descriptor(descriptor, EDID_DETAIL_MONITOR_RANGE))
2981 return;
2982
2983 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.flags) != 10);
2984 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.cvt.flags) != 15);
2985
2986 if (descriptor->data.other_data.data.range.flags == DRM_EDID_CVT_SUPPORT_FLAG &&
2987 descriptor->data.other_data.data.range.formula.cvt.flags & 0x10)
2988 *res = true;
2989 }
2990
2991
2992 static bool
2993 drm_monitor_supports_rb(const struct drm_edid *drm_edid)
2994 {
2995 if (drm_edid->edid->revision >= 4) {
2996 bool ret = false;
2997
2998 drm_for_each_detailed_block(drm_edid, is_rb, &ret);
2999 return ret;
3000 }
3001
3002 return ((drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL) != 0);
3003 }
3004
3005 static void
3006 find_gtf2(const struct detailed_timing *descriptor, void *data)
3007 {
3008 const struct detailed_timing **res = data;
3009
3010 if (!is_display_descriptor(descriptor, EDID_DETAIL_MONITOR_RANGE))
3011 return;
3012
3013 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.flags) != 10);
3014
3015 if (descriptor->data.other_data.data.range.flags == 0x02)
3016 *res = descriptor;
3017 }
3018
3019
3020 static int
3021 drm_gtf2_hbreak(const struct drm_edid *drm_edid)
3022 {
3023 const struct detailed_timing *descriptor = NULL;
3024
3025 drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
3026
3027 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.hfreq_start_khz) != 12);
3028
3029 return descriptor ? descriptor->data.other_data.data.range.formula.gtf2.hfreq_start_khz * 2 : 0;
3030 }
3031
3032 static int
3033 drm_gtf2_2c(const struct drm_edid *drm_edid)
3034 {
3035 const struct detailed_timing *descriptor = NULL;
3036
3037 drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
3038
3039 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.c) != 13);
3040
3041 return descriptor ? descriptor->data.other_data.data.range.formula.gtf2.c : 0;
3042 }
3043
3044 static int
3045 drm_gtf2_m(const struct drm_edid *drm_edid)
3046 {
3047 const struct detailed_timing *descriptor = NULL;
3048
3049 drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
3050
3051 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.m) != 14);
3052
3053 return descriptor ? le16_to_cpu(descriptor->data.other_data.data.range.formula.gtf2.m) : 0;
3054 }
3055
3056 static int
3057 drm_gtf2_k(const struct drm_edid *drm_edid)
3058 {
3059 const struct detailed_timing *descriptor = NULL;
3060
3061 drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
3062
3063 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.k) != 16);
3064
3065 return descriptor ? descriptor->data.other_data.data.range.formula.gtf2.k : 0;
3066 }
3067
3068 static int
3069 drm_gtf2_2j(const struct drm_edid *drm_edid)
3070 {
3071 const struct detailed_timing *descriptor = NULL;
3072
3073 drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
3074
3075 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.j) != 17);
3076
3077 return descriptor ? descriptor->data.other_data.data.range.formula.gtf2.j : 0;
3078 }
3079
3080
3081 static int standard_timing_level(const struct drm_edid *drm_edid)
3082 {
3083 const struct edid *edid = drm_edid->edid;
3084
3085 if (edid->revision >= 2) {
3086 if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
3087 return LEVEL_CVT;
3088 if (drm_gtf2_hbreak(drm_edid))
3089 return LEVEL_GTF2;
3090 if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
3091 return LEVEL_GTF;
3092 }
3093 return LEVEL_DMT;
3094 }
3095
3096
3097
3098
3099
3100 static int
3101 bad_std_timing(u8 a, u8 b)
3102 {
3103 return (a == 0x00 && b == 0x00) ||
3104 (a == 0x01 && b == 0x01) ||
3105 (a == 0x20 && b == 0x20);
3106 }
3107
3108 static int drm_mode_hsync(const struct drm_display_mode *mode)
3109 {
3110 if (mode->htotal <= 0)
3111 return 0;
3112
3113 return DIV_ROUND_CLOSEST(mode->clock, mode->htotal);
3114 }
3115
3116
3117
3118
3119
3120 static struct drm_display_mode *drm_mode_std(struct drm_connector *connector,
3121 const struct drm_edid *drm_edid,
3122 const struct std_timing *t)
3123 {
3124 struct drm_device *dev = connector->dev;
3125 struct drm_display_mode *m, *mode = NULL;
3126 int hsize, vsize;
3127 int vrefresh_rate;
3128 unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
3129 >> EDID_TIMING_ASPECT_SHIFT;
3130 unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
3131 >> EDID_TIMING_VFREQ_SHIFT;
3132 int timing_level = standard_timing_level(drm_edid);
3133
3134 if (bad_std_timing(t->hsize, t->vfreq_aspect))
3135 return NULL;
3136
3137
3138 hsize = t->hsize * 8 + 248;
3139
3140 vrefresh_rate = vfreq + 60;
3141
3142 if (aspect_ratio == 0) {
3143 if (drm_edid->edid->revision < 3)
3144 vsize = hsize;
3145 else
3146 vsize = (hsize * 10) / 16;
3147 } else if (aspect_ratio == 1)
3148 vsize = (hsize * 3) / 4;
3149 else if (aspect_ratio == 2)
3150 vsize = (hsize * 4) / 5;
3151 else
3152 vsize = (hsize * 9) / 16;
3153
3154
3155 if (vrefresh_rate == 60 &&
3156 ((hsize == 1360 && vsize == 765) ||
3157 (hsize == 1368 && vsize == 769))) {
3158 hsize = 1366;
3159 vsize = 768;
3160 }
3161
3162
3163
3164
3165
3166
3167
3168 list_for_each_entry(m, &connector->probed_modes, head)
3169 if (m->hdisplay == hsize && m->vdisplay == vsize &&
3170 drm_mode_vrefresh(m) == vrefresh_rate)
3171 return NULL;
3172
3173
3174 if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) {
3175 mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
3176 false);
3177 if (!mode)
3178 return NULL;
3179 mode->hdisplay = 1366;
3180 mode->hsync_start = mode->hsync_start - 1;
3181 mode->hsync_end = mode->hsync_end - 1;
3182 return mode;
3183 }
3184
3185
3186 if (drm_monitor_supports_rb(drm_edid)) {
3187 mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate,
3188 true);
3189 if (mode)
3190 return mode;
3191 }
3192 mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false);
3193 if (mode)
3194 return mode;
3195
3196
3197 switch (timing_level) {
3198 case LEVEL_DMT:
3199 break;
3200 case LEVEL_GTF:
3201 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
3202 break;
3203 case LEVEL_GTF2:
3204
3205
3206
3207
3208
3209 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
3210 if (!mode)
3211 return NULL;
3212 if (drm_mode_hsync(mode) > drm_gtf2_hbreak(drm_edid)) {
3213 drm_mode_destroy(dev, mode);
3214 mode = drm_gtf_mode_complex(dev, hsize, vsize,
3215 vrefresh_rate, 0, 0,
3216 drm_gtf2_m(drm_edid),
3217 drm_gtf2_2c(drm_edid),
3218 drm_gtf2_k(drm_edid),
3219 drm_gtf2_2j(drm_edid));
3220 }
3221 break;
3222 case LEVEL_CVT:
3223 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
3224 false);
3225 break;
3226 }
3227 return mode;
3228 }
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238 static void
3239 drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
3240 const struct detailed_pixel_timing *pt)
3241 {
3242 int i;
3243 static const struct {
3244 int w, h;
3245 } cea_interlaced[] = {
3246 { 1920, 1080 },
3247 { 720, 480 },
3248 { 1440, 480 },
3249 { 2880, 480 },
3250 { 720, 576 },
3251 { 1440, 576 },
3252 { 2880, 576 },
3253 };
3254
3255 if (!(pt->misc & DRM_EDID_PT_INTERLACED))
3256 return;
3257
3258 for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) {
3259 if ((mode->hdisplay == cea_interlaced[i].w) &&
3260 (mode->vdisplay == cea_interlaced[i].h / 2)) {
3261 mode->vdisplay *= 2;
3262 mode->vsync_start *= 2;
3263 mode->vsync_end *= 2;
3264 mode->vtotal *= 2;
3265 mode->vtotal |= 1;
3266 }
3267 }
3268
3269 mode->flags |= DRM_MODE_FLAG_INTERLACE;
3270 }
3271
3272
3273
3274
3275
3276
3277 static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
3278 const struct drm_edid *drm_edid,
3279 const struct detailed_timing *timing,
3280 u32 quirks)
3281 {
3282 struct drm_display_mode *mode;
3283 const struct detailed_pixel_timing *pt = &timing->data.pixel_data;
3284 unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
3285 unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
3286 unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
3287 unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
3288 unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
3289 unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
3290 unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
3291 unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
3292
3293
3294 if (hactive < 64 || vactive < 64)
3295 return NULL;
3296
3297 if (pt->misc & DRM_EDID_PT_STEREO) {
3298 DRM_DEBUG_KMS("stereo mode not supported\n");
3299 return NULL;
3300 }
3301 if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
3302 DRM_DEBUG_KMS("composite sync not supported\n");
3303 }
3304
3305
3306 if (!hsync_pulse_width || !vsync_pulse_width) {
3307 DRM_DEBUG_KMS("Incorrect Detailed timing. "
3308 "Wrong Hsync/Vsync pulse width\n");
3309 return NULL;
3310 }
3311
3312 if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
3313 mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
3314 if (!mode)
3315 return NULL;
3316
3317 goto set_size;
3318 }
3319
3320 mode = drm_mode_create(dev);
3321 if (!mode)
3322 return NULL;
3323
3324 if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
3325 mode->clock = 1088 * 10;
3326 else
3327 mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
3328
3329 mode->hdisplay = hactive;
3330 mode->hsync_start = mode->hdisplay + hsync_offset;
3331 mode->hsync_end = mode->hsync_start + hsync_pulse_width;
3332 mode->htotal = mode->hdisplay + hblank;
3333
3334 mode->vdisplay = vactive;
3335 mode->vsync_start = mode->vdisplay + vsync_offset;
3336 mode->vsync_end = mode->vsync_start + vsync_pulse_width;
3337 mode->vtotal = mode->vdisplay + vblank;
3338
3339
3340 if (mode->hsync_end > mode->htotal)
3341 mode->htotal = mode->hsync_end + 1;
3342 if (mode->vsync_end > mode->vtotal)
3343 mode->vtotal = mode->vsync_end + 1;
3344
3345 drm_mode_do_interlace_quirk(mode, pt);
3346
3347 if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
3348 mode->flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
3349 } else {
3350 mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
3351 DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
3352 mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
3353 DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
3354 }
3355
3356 set_size:
3357 mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
3358 mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
3359
3360 if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
3361 mode->width_mm *= 10;
3362 mode->height_mm *= 10;
3363 }
3364
3365 if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
3366 mode->width_mm = drm_edid->edid->width_cm * 10;
3367 mode->height_mm = drm_edid->edid->height_cm * 10;
3368 }
3369
3370 mode->type = DRM_MODE_TYPE_DRIVER;
3371 drm_mode_set_name(mode);
3372
3373 return mode;
3374 }
3375
3376 static bool
3377 mode_in_hsync_range(const struct drm_display_mode *mode,
3378 const struct edid *edid, const u8 *t)
3379 {
3380 int hsync, hmin, hmax;
3381
3382 hmin = t[7];
3383 if (edid->revision >= 4)
3384 hmin += ((t[4] & 0x04) ? 255 : 0);
3385 hmax = t[8];
3386 if (edid->revision >= 4)
3387 hmax += ((t[4] & 0x08) ? 255 : 0);
3388 hsync = drm_mode_hsync(mode);
3389
3390 return (hsync <= hmax && hsync >= hmin);
3391 }
3392
3393 static bool
3394 mode_in_vsync_range(const struct drm_display_mode *mode,
3395 const struct edid *edid, const u8 *t)
3396 {
3397 int vsync, vmin, vmax;
3398
3399 vmin = t[5];
3400 if (edid->revision >= 4)
3401 vmin += ((t[4] & 0x01) ? 255 : 0);
3402 vmax = t[6];
3403 if (edid->revision >= 4)
3404 vmax += ((t[4] & 0x02) ? 255 : 0);
3405 vsync = drm_mode_vrefresh(mode);
3406
3407 return (vsync <= vmax && vsync >= vmin);
3408 }
3409
3410 static u32
3411 range_pixel_clock(const struct edid *edid, const u8 *t)
3412 {
3413
3414 if (t[9] == 0 || t[9] == 255)
3415 return 0;
3416
3417
3418 if (edid->revision >= 4 && t[10] == 0x04)
3419 return (t[9] * 10000) - ((t[12] >> 2) * 250);
3420
3421
3422 return t[9] * 10000 + 5001;
3423 }
3424
3425 static bool mode_in_range(const struct drm_display_mode *mode,
3426 const struct drm_edid *drm_edid,
3427 const struct detailed_timing *timing)
3428 {
3429 const struct edid *edid = drm_edid->edid;
3430 u32 max_clock;
3431 const u8 *t = (const u8 *)timing;
3432
3433 if (!mode_in_hsync_range(mode, edid, t))
3434 return false;
3435
3436 if (!mode_in_vsync_range(mode, edid, t))
3437 return false;
3438
3439 if ((max_clock = range_pixel_clock(edid, t)))
3440 if (mode->clock > max_clock)
3441 return false;
3442
3443
3444 if (edid->revision >= 4 && t[10] == 0x04)
3445 if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3))))
3446 return false;
3447
3448 if (mode_is_rb(mode) && !drm_monitor_supports_rb(drm_edid))
3449 return false;
3450
3451 return true;
3452 }
3453
3454 static bool valid_inferred_mode(const struct drm_connector *connector,
3455 const struct drm_display_mode *mode)
3456 {
3457 const struct drm_display_mode *m;
3458 bool ok = false;
3459
3460 list_for_each_entry(m, &connector->probed_modes, head) {
3461 if (mode->hdisplay == m->hdisplay &&
3462 mode->vdisplay == m->vdisplay &&
3463 drm_mode_vrefresh(mode) == drm_mode_vrefresh(m))
3464 return false;
3465 if (mode->hdisplay <= m->hdisplay &&
3466 mode->vdisplay <= m->vdisplay)
3467 ok = true;
3468 }
3469 return ok;
3470 }
3471
3472 static int drm_dmt_modes_for_range(struct drm_connector *connector,
3473 const struct drm_edid *drm_edid,
3474 const struct detailed_timing *timing)
3475 {
3476 int i, modes = 0;
3477 struct drm_display_mode *newmode;
3478 struct drm_device *dev = connector->dev;
3479
3480 for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
3481 if (mode_in_range(drm_dmt_modes + i, drm_edid, timing) &&
3482 valid_inferred_mode(connector, drm_dmt_modes + i)) {
3483 newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
3484 if (newmode) {
3485 drm_mode_probed_add(connector, newmode);
3486 modes++;
3487 }
3488 }
3489 }
3490
3491 return modes;
3492 }
3493
3494
3495
3496
3497 void drm_mode_fixup_1366x768(struct drm_display_mode *mode)
3498 {
3499 if (mode->hdisplay == 1368 && mode->vdisplay == 768) {
3500 mode->hdisplay = 1366;
3501 mode->hsync_start--;
3502 mode->hsync_end--;
3503 drm_mode_set_name(mode);
3504 }
3505 }
3506
3507 static int drm_gtf_modes_for_range(struct drm_connector *connector,
3508 const struct drm_edid *drm_edid,
3509 const struct detailed_timing *timing)
3510 {
3511 int i, modes = 0;
3512 struct drm_display_mode *newmode;
3513 struct drm_device *dev = connector->dev;
3514
3515 for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
3516 const struct minimode *m = &extra_modes[i];
3517
3518 newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
3519 if (!newmode)
3520 return modes;
3521
3522 drm_mode_fixup_1366x768(newmode);
3523 if (!mode_in_range(newmode, drm_edid, timing) ||
3524 !valid_inferred_mode(connector, newmode)) {
3525 drm_mode_destroy(dev, newmode);
3526 continue;
3527 }
3528
3529 drm_mode_probed_add(connector, newmode);
3530 modes++;
3531 }
3532
3533 return modes;
3534 }
3535
3536 static int drm_cvt_modes_for_range(struct drm_connector *connector,
3537 const struct drm_edid *drm_edid,
3538 const struct detailed_timing *timing)
3539 {
3540 int i, modes = 0;
3541 struct drm_display_mode *newmode;
3542 struct drm_device *dev = connector->dev;
3543 bool rb = drm_monitor_supports_rb(drm_edid);
3544
3545 for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
3546 const struct minimode *m = &extra_modes[i];
3547
3548 newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
3549 if (!newmode)
3550 return modes;
3551
3552 drm_mode_fixup_1366x768(newmode);
3553 if (!mode_in_range(newmode, drm_edid, timing) ||
3554 !valid_inferred_mode(connector, newmode)) {
3555 drm_mode_destroy(dev, newmode);
3556 continue;
3557 }
3558
3559 drm_mode_probed_add(connector, newmode);
3560 modes++;
3561 }
3562
3563 return modes;
3564 }
3565
3566 static void
3567 do_inferred_modes(const struct detailed_timing *timing, void *c)
3568 {
3569 struct detailed_mode_closure *closure = c;
3570 const struct detailed_non_pixel *data = &timing->data.other_data;
3571 const struct detailed_data_monitor_range *range = &data->data.range;
3572
3573 if (!is_display_descriptor(timing, EDID_DETAIL_MONITOR_RANGE))
3574 return;
3575
3576 closure->modes += drm_dmt_modes_for_range(closure->connector,
3577 closure->drm_edid,
3578 timing);
3579
3580 if (!version_greater(closure->drm_edid, 1, 1))
3581 return;
3582
3583 switch (range->flags) {
3584 case 0x02:
3585 case 0x00:
3586 closure->modes += drm_gtf_modes_for_range(closure->connector,
3587 closure->drm_edid,
3588 timing);
3589 break;
3590 case 0x04:
3591 if (!version_greater(closure->drm_edid, 1, 3))
3592 break;
3593
3594 closure->modes += drm_cvt_modes_for_range(closure->connector,
3595 closure->drm_edid,
3596 timing);
3597 break;
3598 case 0x01:
3599 default:
3600 break;
3601 }
3602 }
3603
3604 static int add_inferred_modes(struct drm_connector *connector,
3605 const struct drm_edid *drm_edid)
3606 {
3607 struct detailed_mode_closure closure = {
3608 .connector = connector,
3609 .drm_edid = drm_edid,
3610 };
3611
3612 if (version_greater(drm_edid, 1, 0))
3613 drm_for_each_detailed_block(drm_edid, do_inferred_modes, &closure);
3614
3615 return closure.modes;
3616 }
3617
3618 static int
3619 drm_est3_modes(struct drm_connector *connector, const struct detailed_timing *timing)
3620 {
3621 int i, j, m, modes = 0;
3622 struct drm_display_mode *mode;
3623 const u8 *est = ((const u8 *)timing) + 6;
3624
3625 for (i = 0; i < 6; i++) {
3626 for (j = 7; j >= 0; j--) {
3627 m = (i * 8) + (7 - j);
3628 if (m >= ARRAY_SIZE(est3_modes))
3629 break;
3630 if (est[i] & (1 << j)) {
3631 mode = drm_mode_find_dmt(connector->dev,
3632 est3_modes[m].w,
3633 est3_modes[m].h,
3634 est3_modes[m].r,
3635 est3_modes[m].rb);
3636 if (mode) {
3637 drm_mode_probed_add(connector, mode);
3638 modes++;
3639 }
3640 }
3641 }
3642 }
3643
3644 return modes;
3645 }
3646
3647 static void
3648 do_established_modes(const struct detailed_timing *timing, void *c)
3649 {
3650 struct detailed_mode_closure *closure = c;
3651
3652 if (!is_display_descriptor(timing, EDID_DETAIL_EST_TIMINGS))
3653 return;
3654
3655 closure->modes += drm_est3_modes(closure->connector, timing);
3656 }
3657
3658
3659
3660
3661
3662
3663 static int add_established_modes(struct drm_connector *connector,
3664 const struct drm_edid *drm_edid)
3665 {
3666 struct drm_device *dev = connector->dev;
3667 const struct edid *edid = drm_edid->edid;
3668 unsigned long est_bits = edid->established_timings.t1 |
3669 (edid->established_timings.t2 << 8) |
3670 ((edid->established_timings.mfg_rsvd & 0x80) << 9);
3671 int i, modes = 0;
3672 struct detailed_mode_closure closure = {
3673 .connector = connector,
3674 .drm_edid = drm_edid,
3675 };
3676
3677 for (i = 0; i <= EDID_EST_TIMINGS; i++) {
3678 if (est_bits & (1<<i)) {
3679 struct drm_display_mode *newmode;
3680
3681 newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
3682 if (newmode) {
3683 drm_mode_probed_add(connector, newmode);
3684 modes++;
3685 }
3686 }
3687 }
3688
3689 if (version_greater(drm_edid, 1, 0))
3690 drm_for_each_detailed_block(drm_edid, do_established_modes,
3691 &closure);
3692
3693 return modes + closure.modes;
3694 }
3695
3696 static void
3697 do_standard_modes(const struct detailed_timing *timing, void *c)
3698 {
3699 struct detailed_mode_closure *closure = c;
3700 const struct detailed_non_pixel *data = &timing->data.other_data;
3701 struct drm_connector *connector = closure->connector;
3702 int i;
3703
3704 if (!is_display_descriptor(timing, EDID_DETAIL_STD_MODES))
3705 return;
3706
3707 for (i = 0; i < 6; i++) {
3708 const struct std_timing *std = &data->data.timings[i];
3709 struct drm_display_mode *newmode;
3710
3711 newmode = drm_mode_std(connector, closure->drm_edid, std);
3712 if (newmode) {
3713 drm_mode_probed_add(connector, newmode);
3714 closure->modes++;
3715 }
3716 }
3717 }
3718
3719
3720
3721
3722
3723
3724 static int add_standard_modes(struct drm_connector *connector,
3725 const struct drm_edid *drm_edid)
3726 {
3727 int i, modes = 0;
3728 struct detailed_mode_closure closure = {
3729 .connector = connector,
3730 .drm_edid = drm_edid,
3731 };
3732
3733 for (i = 0; i < EDID_STD_TIMINGS; i++) {
3734 struct drm_display_mode *newmode;
3735
3736 newmode = drm_mode_std(connector, drm_edid,
3737 &drm_edid->edid->standard_timings[i]);
3738 if (newmode) {
3739 drm_mode_probed_add(connector, newmode);
3740 modes++;
3741 }
3742 }
3743
3744 if (version_greater(drm_edid, 1, 0))
3745 drm_for_each_detailed_block(drm_edid, do_standard_modes,
3746 &closure);
3747
3748
3749
3750 return modes + closure.modes;
3751 }
3752
3753 static int drm_cvt_modes(struct drm_connector *connector,
3754 const struct detailed_timing *timing)
3755 {
3756 int i, j, modes = 0;
3757 struct drm_display_mode *newmode;
3758 struct drm_device *dev = connector->dev;
3759 const struct cvt_timing *cvt;
3760 const int rates[] = { 60, 85, 75, 60, 50 };
3761 const u8 empty[3] = { 0, 0, 0 };
3762
3763 for (i = 0; i < 4; i++) {
3764 int width, height;
3765
3766 cvt = &(timing->data.other_data.data.cvt[i]);
3767
3768 if (!memcmp(cvt->code, empty, 3))
3769 continue;
3770
3771 height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2;
3772 switch (cvt->code[1] & 0x0c) {
3773
3774 default:
3775 case 0x00:
3776 width = height * 4 / 3;
3777 break;
3778 case 0x04:
3779 width = height * 16 / 9;
3780 break;
3781 case 0x08:
3782 width = height * 16 / 10;
3783 break;
3784 case 0x0c:
3785 width = height * 15 / 9;
3786 break;
3787 }
3788
3789 for (j = 1; j < 5; j++) {
3790 if (cvt->code[2] & (1 << j)) {
3791 newmode = drm_cvt_mode(dev, width, height,
3792 rates[j], j == 0,
3793 false, false);
3794 if (newmode) {
3795 drm_mode_probed_add(connector, newmode);
3796 modes++;
3797 }
3798 }
3799 }
3800 }
3801
3802 return modes;
3803 }
3804
3805 static void
3806 do_cvt_mode(const struct detailed_timing *timing, void *c)
3807 {
3808 struct detailed_mode_closure *closure = c;
3809
3810 if (!is_display_descriptor(timing, EDID_DETAIL_CVT_3BYTE))
3811 return;
3812
3813 closure->modes += drm_cvt_modes(closure->connector, timing);
3814 }
3815
3816 static int
3817 add_cvt_modes(struct drm_connector *connector, const struct drm_edid *drm_edid)
3818 {
3819 struct detailed_mode_closure closure = {
3820 .connector = connector,
3821 .drm_edid = drm_edid,
3822 };
3823
3824 if (version_greater(drm_edid, 1, 2))
3825 drm_for_each_detailed_block(drm_edid, do_cvt_mode, &closure);
3826
3827
3828
3829 return closure.modes;
3830 }
3831
3832 static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode);
3833
3834 static void
3835 do_detailed_mode(const struct detailed_timing *timing, void *c)
3836 {
3837 struct detailed_mode_closure *closure = c;
3838 struct drm_display_mode *newmode;
3839
3840 if (!is_detailed_timing_descriptor(timing))
3841 return;
3842
3843 newmode = drm_mode_detailed(closure->connector->dev,
3844 closure->drm_edid, timing,
3845 closure->quirks);
3846 if (!newmode)
3847 return;
3848
3849 if (closure->preferred)
3850 newmode->type |= DRM_MODE_TYPE_PREFERRED;
3851
3852
3853
3854
3855
3856
3857 fixup_detailed_cea_mode_clock(newmode);
3858
3859 drm_mode_probed_add(closure->connector, newmode);
3860 closure->modes++;
3861 closure->preferred = false;
3862 }
3863
3864
3865
3866
3867
3868
3869
3870 static int add_detailed_modes(struct drm_connector *connector,
3871 const struct drm_edid *drm_edid, u32 quirks)
3872 {
3873 struct detailed_mode_closure closure = {
3874 .connector = connector,
3875 .drm_edid = drm_edid,
3876 .preferred = true,
3877 .quirks = quirks,
3878 };
3879
3880 if (closure.preferred && !version_greater(drm_edid, 1, 3))
3881 closure.preferred =
3882 (drm_edid->edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
3883
3884 drm_for_each_detailed_block(drm_edid, do_detailed_mode, &closure);
3885
3886 return closure.modes;
3887 }
3888
3889
3890 #define CTA_DB_AUDIO 1
3891 #define CTA_DB_VIDEO 2
3892 #define CTA_DB_VENDOR 3
3893 #define CTA_DB_SPEAKER 4
3894 #define CTA_DB_EXTENDED_TAG 7
3895
3896
3897 #define CTA_EXT_DB_VIDEO_CAP 0
3898 #define CTA_EXT_DB_VENDOR 1
3899 #define CTA_EXT_DB_HDR_STATIC_METADATA 6
3900 #define CTA_EXT_DB_420_VIDEO_DATA 14
3901 #define CTA_EXT_DB_420_VIDEO_CAP_MAP 15
3902 #define CTA_EXT_DB_HF_EEODB 0x78
3903 #define CTA_EXT_DB_HF_SCDB 0x79
3904
3905 #define EDID_BASIC_AUDIO (1 << 6)
3906 #define EDID_CEA_YCRCB444 (1 << 5)
3907 #define EDID_CEA_YCRCB422 (1 << 4)
3908 #define EDID_CEA_VCDB_QS (1 << 6)
3909
3910
3911
3912
3913
3914
3915 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
3916 int ext_id, int *ext_index)
3917 {
3918 const u8 *edid_ext = NULL;
3919 int i;
3920
3921
3922 if (!drm_edid || !drm_edid_extension_block_count(drm_edid))
3923 return NULL;
3924
3925
3926 for (i = *ext_index; i < drm_edid_extension_block_count(drm_edid); i++) {
3927 edid_ext = drm_edid_extension_block_data(drm_edid, i);
3928 if (edid_block_tag(edid_ext) == ext_id)
3929 break;
3930 }
3931
3932 if (i >= drm_edid_extension_block_count(drm_edid))
3933 return NULL;
3934
3935 *ext_index = i + 1;
3936
3937 return edid_ext;
3938 }
3939
3940
3941 static bool drm_edid_has_cta_extension(const struct drm_edid *drm_edid)
3942 {
3943 const struct displayid_block *block;
3944 struct displayid_iter iter;
3945 int ext_index = 0;
3946 bool found = false;
3947
3948
3949 if (drm_find_edid_extension(drm_edid, CEA_EXT, &ext_index))
3950 return true;
3951
3952
3953 displayid_iter_edid_begin(drm_edid, &iter);
3954 displayid_iter_for_each(block, &iter) {
3955 if (block->tag == DATA_BLOCK_CTA) {
3956 found = true;
3957 break;
3958 }
3959 }
3960 displayid_iter_end(&iter);
3961
3962 return found;
3963 }
3964
3965 static __always_inline const struct drm_display_mode *cea_mode_for_vic(u8 vic)
3966 {
3967 BUILD_BUG_ON(1 + ARRAY_SIZE(edid_cea_modes_1) - 1 != 127);
3968 BUILD_BUG_ON(193 + ARRAY_SIZE(edid_cea_modes_193) - 1 != 219);
3969
3970 if (vic >= 1 && vic < 1 + ARRAY_SIZE(edid_cea_modes_1))
3971 return &edid_cea_modes_1[vic - 1];
3972 if (vic >= 193 && vic < 193 + ARRAY_SIZE(edid_cea_modes_193))
3973 return &edid_cea_modes_193[vic - 193];
3974 return NULL;
3975 }
3976
3977 static u8 cea_num_vics(void)
3978 {
3979 return 193 + ARRAY_SIZE(edid_cea_modes_193);
3980 }
3981
3982 static u8 cea_next_vic(u8 vic)
3983 {
3984 if (++vic == 1 + ARRAY_SIZE(edid_cea_modes_1))
3985 vic = 193;
3986 return vic;
3987 }
3988
3989
3990
3991
3992
3993 static unsigned int
3994 cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
3995 {
3996 unsigned int clock = cea_mode->clock;
3997
3998 if (drm_mode_vrefresh(cea_mode) % 6 != 0)
3999 return clock;
4000
4001
4002
4003
4004
4005
4006 if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
4007 clock = DIV_ROUND_CLOSEST(clock * 1001, 1000);
4008 else
4009 clock = DIV_ROUND_CLOSEST(clock * 1000, 1001);
4010
4011 return clock;
4012 }
4013
4014 static bool
4015 cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
4016 {
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026 BUILD_BUG_ON(cea_mode_for_vic(8)->vtotal != 262 ||
4027 cea_mode_for_vic(9)->vtotal != 262 ||
4028 cea_mode_for_vic(12)->vtotal != 262 ||
4029 cea_mode_for_vic(13)->vtotal != 262 ||
4030 cea_mode_for_vic(23)->vtotal != 312 ||
4031 cea_mode_for_vic(24)->vtotal != 312 ||
4032 cea_mode_for_vic(27)->vtotal != 312 ||
4033 cea_mode_for_vic(28)->vtotal != 312);
4034
4035 if (((vic == 8 || vic == 9 ||
4036 vic == 12 || vic == 13) && mode->vtotal < 263) ||
4037 ((vic == 23 || vic == 24 ||
4038 vic == 27 || vic == 28) && mode->vtotal < 314)) {
4039 mode->vsync_start++;
4040 mode->vsync_end++;
4041 mode->vtotal++;
4042
4043 return true;
4044 }
4045
4046 return false;
4047 }
4048
4049 static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
4050 unsigned int clock_tolerance)
4051 {
4052 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
4053 u8 vic;
4054
4055 if (!to_match->clock)
4056 return 0;
4057
4058 if (to_match->picture_aspect_ratio)
4059 match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
4060
4061 for (vic = 1; vic < cea_num_vics(); vic = cea_next_vic(vic)) {
4062 struct drm_display_mode cea_mode;
4063 unsigned int clock1, clock2;
4064
4065 drm_mode_init(&cea_mode, cea_mode_for_vic(vic));
4066
4067
4068 clock1 = cea_mode.clock;
4069 clock2 = cea_mode_alternate_clock(&cea_mode);
4070
4071 if (abs(to_match->clock - clock1) > clock_tolerance &&
4072 abs(to_match->clock - clock2) > clock_tolerance)
4073 continue;
4074
4075 do {
4076 if (drm_mode_match(to_match, &cea_mode, match_flags))
4077 return vic;
4078 } while (cea_mode_alternate_timings(vic, &cea_mode));
4079 }
4080
4081 return 0;
4082 }
4083
4084
4085
4086
4087
4088
4089
4090
4091 u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
4092 {
4093 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
4094 u8 vic;
4095
4096 if (!to_match->clock)
4097 return 0;
4098
4099 if (to_match->picture_aspect_ratio)
4100 match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
4101
4102 for (vic = 1; vic < cea_num_vics(); vic = cea_next_vic(vic)) {
4103 struct drm_display_mode cea_mode;
4104 unsigned int clock1, clock2;
4105
4106 drm_mode_init(&cea_mode, cea_mode_for_vic(vic));
4107
4108
4109 clock1 = cea_mode.clock;
4110 clock2 = cea_mode_alternate_clock(&cea_mode);
4111
4112 if (KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock1) &&
4113 KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock2))
4114 continue;
4115
4116 do {
4117 if (drm_mode_match(to_match, &cea_mode, match_flags))
4118 return vic;
4119 } while (cea_mode_alternate_timings(vic, &cea_mode));
4120 }
4121
4122 return 0;
4123 }
4124 EXPORT_SYMBOL(drm_match_cea_mode);
4125
4126 static bool drm_valid_cea_vic(u8 vic)
4127 {
4128 return cea_mode_for_vic(vic) != NULL;
4129 }
4130
4131 static enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)
4132 {
4133 const struct drm_display_mode *mode = cea_mode_for_vic(video_code);
4134
4135 if (mode)
4136 return mode->picture_aspect_ratio;
4137
4138 return HDMI_PICTURE_ASPECT_NONE;
4139 }
4140
4141 static enum hdmi_picture_aspect drm_get_hdmi_aspect_ratio(const u8 video_code)
4142 {
4143 return edid_4k_modes[video_code].picture_aspect_ratio;
4144 }
4145
4146
4147
4148
4149
4150 static unsigned int
4151 hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
4152 {
4153 return cea_mode_alternate_clock(hdmi_mode);
4154 }
4155
4156 static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match,
4157 unsigned int clock_tolerance)
4158 {
4159 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
4160 u8 vic;
4161
4162 if (!to_match->clock)
4163 return 0;
4164
4165 if (to_match->picture_aspect_ratio)
4166 match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
4167
4168 for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) {
4169 const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic];
4170 unsigned int clock1, clock2;
4171
4172
4173 clock1 = hdmi_mode->clock;
4174 clock2 = hdmi_mode_alternate_clock(hdmi_mode);
4175
4176 if (abs(to_match->clock - clock1) > clock_tolerance &&
4177 abs(to_match->clock - clock2) > clock_tolerance)
4178 continue;
4179
4180 if (drm_mode_match(to_match, hdmi_mode, match_flags))
4181 return vic;
4182 }
4183
4184 return 0;
4185 }
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195 static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
4196 {
4197 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
4198 u8 vic;
4199
4200 if (!to_match->clock)
4201 return 0;
4202
4203 if (to_match->picture_aspect_ratio)
4204 match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
4205
4206 for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) {
4207 const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic];
4208 unsigned int clock1, clock2;
4209
4210
4211 clock1 = hdmi_mode->clock;
4212 clock2 = hdmi_mode_alternate_clock(hdmi_mode);
4213
4214 if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
4215 KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
4216 drm_mode_match(to_match, hdmi_mode, match_flags))
4217 return vic;
4218 }
4219 return 0;
4220 }
4221
4222 static bool drm_valid_hdmi_vic(u8 vic)
4223 {
4224 return vic > 0 && vic < ARRAY_SIZE(edid_4k_modes);
4225 }
4226
4227 static int add_alternate_cea_modes(struct drm_connector *connector,
4228 const struct drm_edid *drm_edid)
4229 {
4230 struct drm_device *dev = connector->dev;
4231 struct drm_display_mode *mode, *tmp;
4232 LIST_HEAD(list);
4233 int modes = 0;
4234
4235
4236 if (!drm_edid_has_cta_extension(drm_edid))
4237 return 0;
4238
4239
4240
4241
4242
4243 list_for_each_entry(mode, &connector->probed_modes, head) {
4244 const struct drm_display_mode *cea_mode = NULL;
4245 struct drm_display_mode *newmode;
4246 u8 vic = drm_match_cea_mode(mode);
4247 unsigned int clock1, clock2;
4248
4249 if (drm_valid_cea_vic(vic)) {
4250 cea_mode = cea_mode_for_vic(vic);
4251 clock2 = cea_mode_alternate_clock(cea_mode);
4252 } else {
4253 vic = drm_match_hdmi_mode(mode);
4254 if (drm_valid_hdmi_vic(vic)) {
4255 cea_mode = &edid_4k_modes[vic];
4256 clock2 = hdmi_mode_alternate_clock(cea_mode);
4257 }
4258 }
4259
4260 if (!cea_mode)
4261 continue;
4262
4263 clock1 = cea_mode->clock;
4264
4265 if (clock1 == clock2)
4266 continue;
4267
4268 if (mode->clock != clock1 && mode->clock != clock2)
4269 continue;
4270
4271 newmode = drm_mode_duplicate(dev, cea_mode);
4272 if (!newmode)
4273 continue;
4274
4275
4276 newmode->flags |= mode->flags & DRM_MODE_FLAG_3D_MASK;
4277
4278
4279
4280
4281
4282 if (mode->clock != clock1)
4283 newmode->clock = clock1;
4284 else
4285 newmode->clock = clock2;
4286
4287 list_add_tail(&newmode->head, &list);
4288 }
4289
4290 list_for_each_entry_safe(mode, tmp, &list, head) {
4291 list_del(&mode->head);
4292 drm_mode_probed_add(connector, mode);
4293 modes++;
4294 }
4295
4296 return modes;
4297 }
4298
4299 static u8 svd_to_vic(u8 svd)
4300 {
4301
4302 if ((svd >= 1 && svd <= 64) || (svd >= 129 && svd <= 192))
4303 return svd & 127;
4304
4305 return svd;
4306 }
4307
4308 static struct drm_display_mode *
4309 drm_display_mode_from_vic_index(struct drm_connector *connector,
4310 const u8 *video_db, u8 video_len,
4311 u8 video_index)
4312 {
4313 struct drm_device *dev = connector->dev;
4314 struct drm_display_mode *newmode;
4315 u8 vic;
4316
4317 if (video_db == NULL || video_index >= video_len)
4318 return NULL;
4319
4320
4321 vic = svd_to_vic(video_db[video_index]);
4322 if (!drm_valid_cea_vic(vic))
4323 return NULL;
4324
4325 newmode = drm_mode_duplicate(dev, cea_mode_for_vic(vic));
4326 if (!newmode)
4327 return NULL;
4328
4329 return newmode;
4330 }
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342 static int do_y420vdb_modes(struct drm_connector *connector,
4343 const u8 *svds, u8 svds_len)
4344 {
4345 int modes = 0, i;
4346 struct drm_device *dev = connector->dev;
4347 struct drm_display_info *info = &connector->display_info;
4348 struct drm_hdmi_info *hdmi = &info->hdmi;
4349
4350 for (i = 0; i < svds_len; i++) {
4351 u8 vic = svd_to_vic(svds[i]);
4352 struct drm_display_mode *newmode;
4353
4354 if (!drm_valid_cea_vic(vic))
4355 continue;
4356
4357 newmode = drm_mode_duplicate(dev, cea_mode_for_vic(vic));
4358 if (!newmode)
4359 break;
4360 bitmap_set(hdmi->y420_vdb_modes, vic, 1);
4361 drm_mode_probed_add(connector, newmode);
4362 modes++;
4363 }
4364
4365 if (modes > 0)
4366 info->color_formats |= DRM_COLOR_FORMAT_YCBCR420;
4367 return modes;
4368 }
4369
4370
4371
4372
4373
4374
4375
4376
4377 static void
4378 drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
4379 {
4380 u8 vic = svd_to_vic(svd);
4381 struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
4382
4383 if (!drm_valid_cea_vic(vic))
4384 return;
4385
4386 bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
4387 }
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398 struct drm_display_mode *
4399 drm_display_mode_from_cea_vic(struct drm_device *dev,
4400 u8 video_code)
4401 {
4402 const struct drm_display_mode *cea_mode;
4403 struct drm_display_mode *newmode;
4404
4405 cea_mode = cea_mode_for_vic(video_code);
4406 if (!cea_mode)
4407 return NULL;
4408
4409 newmode = drm_mode_duplicate(dev, cea_mode);
4410 if (!newmode)
4411 return NULL;
4412
4413 return newmode;
4414 }
4415 EXPORT_SYMBOL(drm_display_mode_from_cea_vic);
4416
4417 static int
4418 do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
4419 {
4420 int i, modes = 0;
4421 struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
4422
4423 for (i = 0; i < len; i++) {
4424 struct drm_display_mode *mode;
4425
4426 mode = drm_display_mode_from_vic_index(connector, db, len, i);
4427 if (mode) {
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437 if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i))
4438 drm_add_cmdb_modes(connector, db[i]);
4439
4440 drm_mode_probed_add(connector, mode);
4441 modes++;
4442 }
4443 }
4444
4445 return modes;
4446 }
4447
4448 struct stereo_mandatory_mode {
4449 int width, height, vrefresh;
4450 unsigned int flags;
4451 };
4452
4453 static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
4454 { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
4455 { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING },
4456 { 1920, 1080, 50,
4457 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
4458 { 1920, 1080, 60,
4459 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
4460 { 1280, 720, 50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
4461 { 1280, 720, 50, DRM_MODE_FLAG_3D_FRAME_PACKING },
4462 { 1280, 720, 60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
4463 { 1280, 720, 60, DRM_MODE_FLAG_3D_FRAME_PACKING }
4464 };
4465
4466 static bool
4467 stereo_match_mandatory(const struct drm_display_mode *mode,
4468 const struct stereo_mandatory_mode *stereo_mode)
4469 {
4470 unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
4471
4472 return mode->hdisplay == stereo_mode->width &&
4473 mode->vdisplay == stereo_mode->height &&
4474 interlaced == (stereo_mode->flags & DRM_MODE_FLAG_INTERLACE) &&
4475 drm_mode_vrefresh(mode) == stereo_mode->vrefresh;
4476 }
4477
4478 static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
4479 {
4480 struct drm_device *dev = connector->dev;
4481 const struct drm_display_mode *mode;
4482 struct list_head stereo_modes;
4483 int modes = 0, i;
4484
4485 INIT_LIST_HEAD(&stereo_modes);
4486
4487 list_for_each_entry(mode, &connector->probed_modes, head) {
4488 for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) {
4489 const struct stereo_mandatory_mode *mandatory;
4490 struct drm_display_mode *new_mode;
4491
4492 if (!stereo_match_mandatory(mode,
4493 &stereo_mandatory_modes[i]))
4494 continue;
4495
4496 mandatory = &stereo_mandatory_modes[i];
4497 new_mode = drm_mode_duplicate(dev, mode);
4498 if (!new_mode)
4499 continue;
4500
4501 new_mode->flags |= mandatory->flags;
4502 list_add_tail(&new_mode->head, &stereo_modes);
4503 modes++;
4504 }
4505 }
4506
4507 list_splice_tail(&stereo_modes, &connector->probed_modes);
4508
4509 return modes;
4510 }
4511
4512 static int add_hdmi_mode(struct drm_connector *connector, u8 vic)
4513 {
4514 struct drm_device *dev = connector->dev;
4515 struct drm_display_mode *newmode;
4516
4517 if (!drm_valid_hdmi_vic(vic)) {
4518 DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
4519 return 0;
4520 }
4521
4522 newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
4523 if (!newmode)
4524 return 0;
4525
4526 drm_mode_probed_add(connector, newmode);
4527
4528 return 1;
4529 }
4530
4531 static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
4532 const u8 *video_db, u8 video_len, u8 video_index)
4533 {
4534 struct drm_display_mode *newmode;
4535 int modes = 0;
4536
4537 if (structure & (1 << 0)) {
4538 newmode = drm_display_mode_from_vic_index(connector, video_db,
4539 video_len,
4540 video_index);
4541 if (newmode) {
4542 newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
4543 drm_mode_probed_add(connector, newmode);
4544 modes++;
4545 }
4546 }
4547 if (structure & (1 << 6)) {
4548 newmode = drm_display_mode_from_vic_index(connector, video_db,
4549 video_len,
4550 video_index);
4551 if (newmode) {
4552 newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
4553 drm_mode_probed_add(connector, newmode);
4554 modes++;
4555 }
4556 }
4557 if (structure & (1 << 8)) {
4558 newmode = drm_display_mode_from_vic_index(connector, video_db,
4559 video_len,
4560 video_index);
4561 if (newmode) {
4562 newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
4563 drm_mode_probed_add(connector, newmode);
4564 modes++;
4565 }
4566 }
4567
4568 return modes;
4569 }
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580 static int
4581 do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
4582 const u8 *video_db, u8 video_len)
4583 {
4584 struct drm_display_info *info = &connector->display_info;
4585 int modes = 0, offset = 0, i, multi_present = 0, multi_len;
4586 u8 vic_len, hdmi_3d_len = 0;
4587 u16 mask;
4588 u16 structure_all;
4589
4590 if (len < 8)
4591 goto out;
4592
4593
4594 if (!(db[8] & (1 << 5)))
4595 goto out;
4596
4597
4598 if (db[8] & (1 << 7))
4599 offset += 2;
4600
4601
4602 if (db[8] & (1 << 6))
4603 offset += 2;
4604
4605
4606
4607 if (len < (8 + offset + 2))
4608 goto out;
4609
4610
4611 offset++;
4612 if (db[8 + offset] & (1 << 7)) {
4613 modes += add_hdmi_mandatory_stereo_modes(connector);
4614
4615
4616 multi_present = (db[8 + offset] & 0x60) >> 5;
4617 }
4618
4619 offset++;
4620 vic_len = db[8 + offset] >> 5;
4621 hdmi_3d_len = db[8 + offset] & 0x1f;
4622
4623 for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
4624 u8 vic;
4625
4626 vic = db[9 + offset + i];
4627 modes += add_hdmi_mode(connector, vic);
4628 }
4629 offset += 1 + vic_len;
4630
4631 if (multi_present == 1)
4632 multi_len = 2;
4633 else if (multi_present == 2)
4634 multi_len = 4;
4635 else
4636 multi_len = 0;
4637
4638 if (len < (8 + offset + hdmi_3d_len - 1))
4639 goto out;
4640
4641 if (hdmi_3d_len < multi_len)
4642 goto out;
4643
4644 if (multi_present == 1 || multi_present == 2) {
4645
4646 structure_all = (db[8 + offset] << 8) | db[9 + offset];
4647
4648
4649 if (multi_present == 2)
4650 mask = (db[10 + offset] << 8) | db[11 + offset];
4651 else
4652 mask = 0xffff;
4653
4654 for (i = 0; i < 16; i++) {
4655 if (mask & (1 << i))
4656 modes += add_3d_struct_modes(connector,
4657 structure_all,
4658 video_db,
4659 video_len, i);
4660 }
4661 }
4662
4663 offset += multi_len;
4664
4665 for (i = 0; i < (hdmi_3d_len - multi_len); i++) {
4666 int vic_index;
4667 struct drm_display_mode *newmode = NULL;
4668 unsigned int newflag = 0;
4669 bool detail_present;
4670
4671 detail_present = ((db[8 + offset + i] & 0x0f) > 7);
4672
4673 if (detail_present && (i + 1 == hdmi_3d_len - multi_len))
4674 break;
4675
4676
4677 vic_index = db[8 + offset + i] >> 4;
4678
4679
4680 switch (db[8 + offset + i] & 0x0f) {
4681 case 0:
4682 newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
4683 break;
4684 case 6:
4685 newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
4686 break;
4687 case 8:
4688
4689 if ((db[9 + offset + i] >> 4) == 1)
4690 newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
4691 break;
4692 }
4693
4694 if (newflag != 0) {
4695 newmode = drm_display_mode_from_vic_index(connector,
4696 video_db,
4697 video_len,
4698 vic_index);
4699
4700 if (newmode) {
4701 newmode->flags |= newflag;
4702 drm_mode_probed_add(connector, newmode);
4703 modes++;
4704 }
4705 }
4706
4707 if (detail_present)
4708 i++;
4709 }
4710
4711 out:
4712 if (modes > 0)
4713 info->has_hdmi_infoframe = true;
4714 return modes;
4715 }
4716
4717 static int
4718 cea_revision(const u8 *cea)
4719 {
4720
4721
4722
4723
4724
4725
4726
4727 return cea[1];
4728 }
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745 struct cea_db_iter {
4746 struct drm_edid_iter edid_iter;
4747 struct displayid_iter displayid_iter;
4748
4749
4750 const u8 *collection;
4751
4752
4753 int index;
4754
4755
4756 int end;
4757 };
4758
4759
4760 struct cea_db {
4761 u8 tag_length;
4762 u8 data[];
4763 } __packed;
4764
4765 static int cea_db_tag(const struct cea_db *db)
4766 {
4767 return db->tag_length >> 5;
4768 }
4769
4770 static int cea_db_payload_len(const void *_db)
4771 {
4772
4773 const struct cea_db *db = _db;
4774
4775 return db->tag_length & 0x1f;
4776 }
4777
4778 static const void *cea_db_data(const struct cea_db *db)
4779 {
4780 return db->data;
4781 }
4782
4783 static bool cea_db_is_extended_tag(const struct cea_db *db, int tag)
4784 {
4785 return cea_db_tag(db) == CTA_DB_EXTENDED_TAG &&
4786 cea_db_payload_len(db) >= 1 &&
4787 db->data[0] == tag;
4788 }
4789
4790 static bool cea_db_is_vendor(const struct cea_db *db, int vendor_oui)
4791 {
4792 const u8 *data = cea_db_data(db);
4793
4794 return cea_db_tag(db) == CTA_DB_VENDOR &&
4795 cea_db_payload_len(db) >= 3 &&
4796 oui(data[2], data[1], data[0]) == vendor_oui;
4797 }
4798
4799 static void cea_db_iter_edid_begin(const struct drm_edid *drm_edid,
4800 struct cea_db_iter *iter)
4801 {
4802 memset(iter, 0, sizeof(*iter));
4803
4804 drm_edid_iter_begin(drm_edid, &iter->edid_iter);
4805 displayid_iter_edid_begin(drm_edid, &iter->displayid_iter);
4806 }
4807
4808 static const struct cea_db *
4809 __cea_db_iter_current_block(const struct cea_db_iter *iter)
4810 {
4811 const struct cea_db *db;
4812
4813 if (!iter->collection)
4814 return NULL;
4815
4816 db = (const struct cea_db *)&iter->collection[iter->index];
4817
4818 if (iter->index + sizeof(*db) <= iter->end &&
4819 iter->index + sizeof(*db) + cea_db_payload_len(db) <= iter->end)
4820 return db;
4821
4822 return NULL;
4823 }
4824
4825
4826
4827
4828
4829 static int cea_db_collection_size(const u8 *cta)
4830 {
4831 u8 d = cta[2];
4832
4833 if (d < 4 || d > 127)
4834 return 0;
4835
4836 return d - 4;
4837 }
4838
4839
4840
4841
4842
4843
4844 static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
4845 {
4846 const u8 *ext;
4847
4848 drm_edid_iter_for_each(ext, &iter->edid_iter) {
4849 int size;
4850
4851
4852 if (ext[0] != CEA_EXT || cea_revision(ext) < 3)
4853 continue;
4854
4855 size = cea_db_collection_size(ext);
4856 if (!size)
4857 continue;
4858
4859 iter->index = 4;
4860 iter->end = iter->index + size;
4861
4862 return ext;
4863 }
4864
4865 return NULL;
4866 }
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876 static const void *__cea_db_iter_displayid_next(struct cea_db_iter *iter)
4877 {
4878 const struct displayid_block *block;
4879
4880 displayid_iter_for_each(block, &iter->displayid_iter) {
4881 if (block->tag != DATA_BLOCK_CTA)
4882 continue;
4883
4884
4885
4886
4887
4888 iter->index = sizeof(*block);
4889 iter->end = iter->index + block->num_bytes;
4890
4891 return block;
4892 }
4893
4894 return NULL;
4895 }
4896
4897 static const struct cea_db *__cea_db_iter_next(struct cea_db_iter *iter)
4898 {
4899 const struct cea_db *db;
4900
4901 if (iter->collection) {
4902
4903 db = __cea_db_iter_current_block(iter);
4904 if (WARN_ON(!db)) {
4905 iter->collection = NULL;
4906 return NULL;
4907 }
4908
4909
4910 iter->index += sizeof(*db) + cea_db_payload_len(db);
4911
4912 db = __cea_db_iter_current_block(iter);
4913 if (db)
4914 return db;
4915 }
4916
4917 for (;;) {
4918
4919
4920
4921
4922
4923
4924
4925
4926 iter->collection = __cea_db_iter_edid_next(iter);
4927 if (!iter->collection)
4928 iter->collection = __cea_db_iter_displayid_next(iter);
4929
4930 if (!iter->collection)
4931 return NULL;
4932
4933 db = __cea_db_iter_current_block(iter);
4934 if (db)
4935 return db;
4936 }
4937 }
4938
4939 #define cea_db_iter_for_each(__db, __iter) \
4940 while (((__db) = __cea_db_iter_next(__iter)))
4941
4942 static void cea_db_iter_end(struct cea_db_iter *iter)
4943 {
4944 displayid_iter_end(&iter->displayid_iter);
4945 drm_edid_iter_end(&iter->edid_iter);
4946
4947 memset(iter, 0, sizeof(*iter));
4948 }
4949
4950 static bool cea_db_is_hdmi_vsdb(const struct cea_db *db)
4951 {
4952 return cea_db_is_vendor(db, HDMI_IEEE_OUI) &&
4953 cea_db_payload_len(db) >= 5;
4954 }
4955
4956 static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
4957 {
4958 return cea_db_is_vendor(db, HDMI_FORUM_IEEE_OUI) &&
4959 cea_db_payload_len(db) >= 7;
4960 }
4961
4962 static bool cea_db_is_hdmi_forum_eeodb(const void *db)
4963 {
4964 return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) &&
4965 cea_db_payload_len(db) >= 2;
4966 }
4967
4968 static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
4969 {
4970 return cea_db_is_vendor(db, MICROSOFT_IEEE_OUI) &&
4971 cea_db_payload_len(db) == 21;
4972 }
4973
4974 static bool cea_db_is_vcdb(const struct cea_db *db)
4975 {
4976 return cea_db_is_extended_tag(db, CTA_EXT_DB_VIDEO_CAP) &&
4977 cea_db_payload_len(db) == 2;
4978 }
4979
4980 static bool cea_db_is_hdmi_forum_scdb(const struct cea_db *db)
4981 {
4982 return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_SCDB) &&
4983 cea_db_payload_len(db) >= 7;
4984 }
4985
4986 static bool cea_db_is_y420cmdb(const struct cea_db *db)
4987 {
4988 return cea_db_is_extended_tag(db, CTA_EXT_DB_420_VIDEO_CAP_MAP);
4989 }
4990
4991 static bool cea_db_is_y420vdb(const struct cea_db *db)
4992 {
4993 return cea_db_is_extended_tag(db, CTA_EXT_DB_420_VIDEO_DATA);
4994 }
4995
4996 static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
4997 {
4998 return cea_db_is_extended_tag(db, CTA_EXT_DB_HDR_STATIC_METADATA) &&
4999 cea_db_payload_len(db) >= 3;
5000 }
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015 static int edid_hfeeodb_extension_block_count(const struct edid *edid)
5016 {
5017 const u8 *cta;
5018
5019
5020 if (!edid_extension_block_count(edid))
5021 return 0;
5022
5023
5024 cta = edid_extension_block_data(edid, 0);
5025 if (edid_block_tag(cta) != CEA_EXT || cea_revision(cta) < 3)
5026 return 0;
5027
5028
5029 if (cea_db_collection_size(cta) < 3)
5030 return 0;
5031
5032
5033
5034
5035
5036
5037 if (!cea_db_is_hdmi_forum_eeodb(&cta[4]))
5038 return 0;
5039
5040 return cta[4 + 2];
5041 }
5042
5043 static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
5044 const u8 *db)
5045 {
5046 struct drm_display_info *info = &connector->display_info;
5047 struct drm_hdmi_info *hdmi = &info->hdmi;
5048 u8 map_len = cea_db_payload_len(db) - 1;
5049 u8 count;
5050 u64 map = 0;
5051
5052 if (map_len == 0) {
5053
5054 hdmi->y420_cmdb_map = U64_MAX;
5055 info->color_formats |= DRM_COLOR_FORMAT_YCBCR420;
5056 return;
5057 }
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071 if (WARN_ON_ONCE(map_len > 8))
5072 map_len = 8;
5073
5074 for (count = 0; count < map_len; count++)
5075 map |= (u64)db[2 + count] << (8 * count);
5076
5077 if (map)
5078 info->color_formats |= DRM_COLOR_FORMAT_YCBCR420;
5079
5080 hdmi->y420_cmdb_map = map;
5081 }
5082
5083 static int add_cea_modes(struct drm_connector *connector,
5084 const struct drm_edid *drm_edid)
5085 {
5086 const struct cea_db *db;
5087 struct cea_db_iter iter;
5088 int modes = 0;
5089
5090 cea_db_iter_edid_begin(drm_edid, &iter);
5091 cea_db_iter_for_each(db, &iter) {
5092 const u8 *hdmi = NULL, *video = NULL;
5093 u8 hdmi_len = 0, video_len = 0;
5094
5095 if (cea_db_tag(db) == CTA_DB_VIDEO) {
5096 video = cea_db_data(db);
5097 video_len = cea_db_payload_len(db);
5098 modes += do_cea_modes(connector, video, video_len);
5099 } else if (cea_db_is_hdmi_vsdb(db)) {
5100
5101 hdmi = (const u8 *)db;
5102 hdmi_len = cea_db_payload_len(db);
5103 } else if (cea_db_is_y420vdb(db)) {
5104 const u8 *vdb420 = cea_db_data(db) + 1;
5105
5106
5107 modes += do_y420vdb_modes(connector, vdb420,
5108 cea_db_payload_len(db) - 1);
5109 }
5110
5111
5112
5113
5114
5115
5116 if (hdmi)
5117 modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len,
5118 video, video_len);
5119 }
5120 cea_db_iter_end(&iter);
5121
5122 return modes;
5123 }
5124
5125 static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
5126 {
5127 const struct drm_display_mode *cea_mode;
5128 int clock1, clock2, clock;
5129 u8 vic;
5130 const char *type;
5131
5132
5133
5134
5135
5136 vic = drm_match_cea_mode_clock_tolerance(mode, 5);
5137 if (drm_valid_cea_vic(vic)) {
5138 type = "CEA";
5139 cea_mode = cea_mode_for_vic(vic);
5140 clock1 = cea_mode->clock;
5141 clock2 = cea_mode_alternate_clock(cea_mode);
5142 } else {
5143 vic = drm_match_hdmi_mode_clock_tolerance(mode, 5);
5144 if (drm_valid_hdmi_vic(vic)) {
5145 type = "HDMI";
5146 cea_mode = &edid_4k_modes[vic];
5147 clock1 = cea_mode->clock;
5148 clock2 = hdmi_mode_alternate_clock(cea_mode);
5149 } else {
5150 return;
5151 }
5152 }
5153
5154
5155 if (abs(mode->clock - clock1) < abs(mode->clock - clock2))
5156 clock = clock1;
5157 else
5158 clock = clock2;
5159
5160 if (mode->clock == clock)
5161 return;
5162
5163 DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n",
5164 type, vic, mode->clock, clock);
5165 mode->clock = clock;
5166 }
5167
5168 static uint8_t eotf_supported(const u8 *edid_ext)
5169 {
5170 return edid_ext[2] &
5171 (BIT(HDMI_EOTF_TRADITIONAL_GAMMA_SDR) |
5172 BIT(HDMI_EOTF_TRADITIONAL_GAMMA_HDR) |
5173 BIT(HDMI_EOTF_SMPTE_ST2084) |
5174 BIT(HDMI_EOTF_BT_2100_HLG));
5175 }
5176
5177 static uint8_t hdr_metadata_type(const u8 *edid_ext)
5178 {
5179 return edid_ext[3] &
5180 BIT(HDMI_STATIC_METADATA_TYPE1);
5181 }
5182
5183 static void
5184 drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
5185 {
5186 u16 len;
5187
5188 len = cea_db_payload_len(db);
5189
5190 connector->hdr_sink_metadata.hdmi_type1.eotf =
5191 eotf_supported(db);
5192 connector->hdr_sink_metadata.hdmi_type1.metadata_type =
5193 hdr_metadata_type(db);
5194
5195 if (len >= 4)
5196 connector->hdr_sink_metadata.hdmi_type1.max_cll = db[4];
5197 if (len >= 5)
5198 connector->hdr_sink_metadata.hdmi_type1.max_fall = db[5];
5199 if (len >= 6)
5200 connector->hdr_sink_metadata.hdmi_type1.min_cll = db[6];
5201 }
5202
5203 static void
5204 drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
5205 {
5206 u8 len = cea_db_payload_len(db);
5207
5208 if (len >= 6 && (db[6] & (1 << 7)))
5209 connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_SUPPORTS_AI;
5210 if (len >= 8) {
5211 connector->latency_present[0] = db[8] >> 7;
5212 connector->latency_present[1] = (db[8] >> 6) & 1;
5213 }
5214 if (len >= 9)
5215 connector->video_latency[0] = db[9];
5216 if (len >= 10)
5217 connector->audio_latency[0] = db[10];
5218 if (len >= 11)
5219 connector->video_latency[1] = db[11];
5220 if (len >= 12)
5221 connector->audio_latency[1] = db[12];
5222
5223 DRM_DEBUG_KMS("HDMI: latency present %d %d, "
5224 "video latency %d %d, "
5225 "audio latency %d %d\n",
5226 connector->latency_present[0],
5227 connector->latency_present[1],
5228 connector->video_latency[0],
5229 connector->video_latency[1],
5230 connector->audio_latency[0],
5231 connector->audio_latency[1]);
5232 }
5233
5234 static void
5235 monitor_name(const struct detailed_timing *timing, void *data)
5236 {
5237 const char **res = data;
5238
5239 if (!is_display_descriptor(timing, EDID_DETAIL_MONITOR_NAME))
5240 return;
5241
5242 *res = timing->data.other_data.data.str.str;
5243 }
5244
5245 static int get_monitor_name(const struct drm_edid *drm_edid, char name[13])
5246 {
5247 const char *edid_name = NULL;
5248 int mnl;
5249
5250 if (!drm_edid || !name)
5251 return 0;
5252
5253 drm_for_each_detailed_block(drm_edid, monitor_name, &edid_name);
5254 for (mnl = 0; edid_name && mnl < 13; mnl++) {
5255 if (edid_name[mnl] == 0x0a)
5256 break;
5257
5258 name[mnl] = edid_name[mnl];
5259 }
5260
5261 return mnl;
5262 }
5263
5264
5265
5266
5267
5268
5269
5270
5271 void drm_edid_get_monitor_name(const struct edid *edid, char *name, int bufsize)
5272 {
5273 int name_length = 0;
5274
5275 if (bufsize <= 0)
5276 return;
5277
5278 if (edid) {
5279 char buf[13];
5280 struct drm_edid drm_edid = {
5281 .edid = edid,
5282 .size = edid_size(edid),
5283 };
5284
5285 name_length = min(get_monitor_name(&drm_edid, buf), bufsize - 1);
5286 memcpy(name, buf, name_length);
5287 }
5288
5289 name[name_length] = '\0';
5290 }
5291 EXPORT_SYMBOL(drm_edid_get_monitor_name);
5292
5293 static void clear_eld(struct drm_connector *connector)
5294 {
5295 memset(connector->eld, 0, sizeof(connector->eld));
5296
5297 connector->latency_present[0] = false;
5298 connector->latency_present[1] = false;
5299 connector->video_latency[0] = 0;
5300 connector->audio_latency[0] = 0;
5301 connector->video_latency[1] = 0;
5302 connector->audio_latency[1] = 0;
5303 }
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313 static void drm_edid_to_eld(struct drm_connector *connector,
5314 const struct drm_edid *drm_edid)
5315 {
5316 const struct drm_display_info *info = &connector->display_info;
5317 const struct cea_db *db;
5318 struct cea_db_iter iter;
5319 uint8_t *eld = connector->eld;
5320 int total_sad_count = 0;
5321 int mnl;
5322
5323 clear_eld(connector);
5324
5325 if (!drm_edid)
5326 return;
5327
5328 mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
5329 DRM_DEBUG_KMS("ELD monitor %s\n", &eld[DRM_ELD_MONITOR_NAME_STRING]);
5330
5331 eld[DRM_ELD_CEA_EDID_VER_MNL] = info->cea_rev << DRM_ELD_CEA_EDID_VER_SHIFT;
5332 eld[DRM_ELD_CEA_EDID_VER_MNL] |= mnl;
5333
5334 eld[DRM_ELD_VER] = DRM_ELD_VER_CEA861D;
5335
5336 eld[DRM_ELD_MANUFACTURER_NAME0] = drm_edid->edid->mfg_id[0];
5337 eld[DRM_ELD_MANUFACTURER_NAME1] = drm_edid->edid->mfg_id[1];
5338 eld[DRM_ELD_PRODUCT_CODE0] = drm_edid->edid->prod_code[0];
5339 eld[DRM_ELD_PRODUCT_CODE1] = drm_edid->edid->prod_code[1];
5340
5341 cea_db_iter_edid_begin(drm_edid, &iter);
5342 cea_db_iter_for_each(db, &iter) {
5343 const u8 *data = cea_db_data(db);
5344 int len = cea_db_payload_len(db);
5345 int sad_count;
5346
5347 switch (cea_db_tag(db)) {
5348 case CTA_DB_AUDIO:
5349
5350 sad_count = min(len / 3, 15 - total_sad_count);
5351 if (sad_count >= 1)
5352 memcpy(&eld[DRM_ELD_CEA_SAD(mnl, total_sad_count)],
5353 data, sad_count * 3);
5354 total_sad_count += sad_count;
5355 break;
5356 case CTA_DB_SPEAKER:
5357
5358 if (len >= 1)
5359 eld[DRM_ELD_SPEAKER] = data[0];
5360 break;
5361 case CTA_DB_VENDOR:
5362
5363 if (cea_db_is_hdmi_vsdb(db))
5364 drm_parse_hdmi_vsdb_audio(connector, (const u8 *)db);
5365 break;
5366 default:
5367 break;
5368 }
5369 }
5370 cea_db_iter_end(&iter);
5371
5372 eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= total_sad_count << DRM_ELD_SAD_COUNT_SHIFT;
5373
5374 if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
5375 connector->connector_type == DRM_MODE_CONNECTOR_eDP)
5376 eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_DP;
5377 else
5378 eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_HDMI;
5379
5380 eld[DRM_ELD_BASELINE_ELD_LEN] =
5381 DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4);
5382
5383 DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
5384 drm_eld_size(eld), total_sad_count);
5385 }
5386
5387 static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
5388 struct cea_sad **sads)
5389 {
5390 const struct cea_db *db;
5391 struct cea_db_iter iter;
5392 int count = 0;
5393
5394 cea_db_iter_edid_begin(drm_edid, &iter);
5395 cea_db_iter_for_each(db, &iter) {
5396 if (cea_db_tag(db) == CTA_DB_AUDIO) {
5397 int j;
5398
5399 count = cea_db_payload_len(db) / 3;
5400 *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
5401 if (!*sads)
5402 return -ENOMEM;
5403 for (j = 0; j < count; j++) {
5404 const u8 *sad = &db->data[j * 3];
5405
5406 (*sads)[j].format = (sad[0] & 0x78) >> 3;
5407 (*sads)[j].channels = sad[0] & 0x7;
5408 (*sads)[j].freq = sad[1] & 0x7F;
5409 (*sads)[j].byte2 = sad[2];
5410 }
5411 break;
5412 }
5413 }
5414 cea_db_iter_end(&iter);
5415
5416 DRM_DEBUG_KMS("Found %d Short Audio Descriptors\n", count);
5417
5418 return count;
5419 }
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432 int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads)
5433 {
5434 struct drm_edid drm_edid;
5435
5436 return _drm_edid_to_sad(drm_edid_legacy_init(&drm_edid, edid), sads);
5437 }
5438 EXPORT_SYMBOL(drm_edid_to_sad);
5439
5440 static int _drm_edid_to_speaker_allocation(const struct drm_edid *drm_edid,
5441 u8 **sadb)
5442 {
5443 const struct cea_db *db;
5444 struct cea_db_iter iter;
5445 int count = 0;
5446
5447 cea_db_iter_edid_begin(drm_edid, &iter);
5448 cea_db_iter_for_each(db, &iter) {
5449 if (cea_db_tag(db) == CTA_DB_SPEAKER &&
5450 cea_db_payload_len(db) == 3) {
5451 *sadb = kmemdup(db->data, cea_db_payload_len(db),
5452 GFP_KERNEL);
5453 if (!*sadb)
5454 return -ENOMEM;
5455 count = cea_db_payload_len(db);
5456 break;
5457 }
5458 }
5459 cea_db_iter_end(&iter);
5460
5461 DRM_DEBUG_KMS("Found %d Speaker Allocation Data Blocks\n", count);
5462
5463 return count;
5464 }
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478 int drm_edid_to_speaker_allocation(const struct edid *edid, u8 **sadb)
5479 {
5480 struct drm_edid drm_edid;
5481
5482 return _drm_edid_to_speaker_allocation(drm_edid_legacy_init(&drm_edid, edid),
5483 sadb);
5484 }
5485 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495 int drm_av_sync_delay(struct drm_connector *connector,
5496 const struct drm_display_mode *mode)
5497 {
5498 int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
5499 int a, v;
5500
5501 if (!connector->latency_present[0])
5502 return 0;
5503 if (!connector->latency_present[1])
5504 i = 0;
5505
5506 a = connector->audio_latency[i];
5507 v = connector->video_latency[i];
5508
5509
5510
5511
5512 if (a == 255 || v == 255)
5513 return 0;
5514
5515
5516
5517
5518
5519 if (a)
5520 a = min(2 * (a - 1), 500);
5521 if (v)
5522 v = min(2 * (v - 1), 500);
5523
5524 return max(v - a, 0);
5525 }
5526 EXPORT_SYMBOL(drm_av_sync_delay);
5527
5528 static bool _drm_detect_hdmi_monitor(const struct drm_edid *drm_edid)
5529 {
5530 const struct cea_db *db;
5531 struct cea_db_iter iter;
5532 bool hdmi = false;
5533
5534
5535
5536
5537
5538 cea_db_iter_edid_begin(drm_edid, &iter);
5539 cea_db_iter_for_each(db, &iter) {
5540 if (cea_db_is_hdmi_vsdb(db)) {
5541 hdmi = true;
5542 break;
5543 }
5544 }
5545 cea_db_iter_end(&iter);
5546
5547 return hdmi;
5548 }
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561 bool drm_detect_hdmi_monitor(const struct edid *edid)
5562 {
5563 struct drm_edid drm_edid;
5564
5565 return _drm_detect_hdmi_monitor(drm_edid_legacy_init(&drm_edid, edid));
5566 }
5567 EXPORT_SYMBOL(drm_detect_hdmi_monitor);
5568
5569 static bool _drm_detect_monitor_audio(const struct drm_edid *drm_edid)
5570 {
5571 struct drm_edid_iter edid_iter;
5572 const struct cea_db *db;
5573 struct cea_db_iter iter;
5574 const u8 *edid_ext;
5575 bool has_audio = false;
5576
5577 drm_edid_iter_begin(drm_edid, &edid_iter);
5578 drm_edid_iter_for_each(edid_ext, &edid_iter) {
5579 if (edid_ext[0] == CEA_EXT) {
5580 has_audio = edid_ext[3] & EDID_BASIC_AUDIO;
5581 if (has_audio)
5582 break;
5583 }
5584 }
5585 drm_edid_iter_end(&edid_iter);
5586
5587 if (has_audio) {
5588 DRM_DEBUG_KMS("Monitor has basic audio support\n");
5589 goto end;
5590 }
5591
5592 cea_db_iter_edid_begin(drm_edid, &iter);
5593 cea_db_iter_for_each(db, &iter) {
5594 if (cea_db_tag(db) == CTA_DB_AUDIO) {
5595 const u8 *data = cea_db_data(db);
5596 int i;
5597
5598 for (i = 0; i < cea_db_payload_len(db); i += 3)
5599 DRM_DEBUG_KMS("CEA audio format %d\n",
5600 (data[i] >> 3) & 0xf);
5601 has_audio = true;
5602 break;
5603 }
5604 }
5605 cea_db_iter_end(&iter);
5606
5607 end:
5608 return has_audio;
5609 }
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623 bool drm_detect_monitor_audio(const struct edid *edid)
5624 {
5625 struct drm_edid drm_edid;
5626
5627 return _drm_detect_monitor_audio(drm_edid_legacy_init(&drm_edid, edid));
5628 }
5629 EXPORT_SYMBOL(drm_detect_monitor_audio);
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641 enum hdmi_quantization_range
5642 drm_default_rgb_quant_range(const struct drm_display_mode *mode)
5643 {
5644
5645 return drm_match_cea_mode(mode) > 1 ?
5646 HDMI_QUANTIZATION_RANGE_LIMITED :
5647 HDMI_QUANTIZATION_RANGE_FULL;
5648 }
5649 EXPORT_SYMBOL(drm_default_rgb_quant_range);
5650
5651 static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
5652 {
5653 struct drm_display_info *info = &connector->display_info;
5654
5655 DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", db[2]);
5656
5657 if (db[2] & EDID_CEA_VCDB_QS)
5658 info->rgb_quant_range_selectable = true;
5659 }
5660
5661 static
5662 void drm_get_max_frl_rate(int max_frl_rate, u8 *max_lanes, u8 *max_rate_per_lane)
5663 {
5664 switch (max_frl_rate) {
5665 case 1:
5666 *max_lanes = 3;
5667 *max_rate_per_lane = 3;
5668 break;
5669 case 2:
5670 *max_lanes = 3;
5671 *max_rate_per_lane = 6;
5672 break;
5673 case 3:
5674 *max_lanes = 4;
5675 *max_rate_per_lane = 6;
5676 break;
5677 case 4:
5678 *max_lanes = 4;
5679 *max_rate_per_lane = 8;
5680 break;
5681 case 5:
5682 *max_lanes = 4;
5683 *max_rate_per_lane = 10;
5684 break;
5685 case 6:
5686 *max_lanes = 4;
5687 *max_rate_per_lane = 12;
5688 break;
5689 case 0:
5690 default:
5691 *max_lanes = 0;
5692 *max_rate_per_lane = 0;
5693 }
5694 }
5695
5696 static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
5697 const u8 *db)
5698 {
5699 u8 dc_mask;
5700 struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
5701
5702 dc_mask = db[7] & DRM_EDID_YCBCR420_DC_MASK;
5703 hdmi->y420_dc_modes = dc_mask;
5704 }
5705
5706
5707 static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
5708 const u8 *hf_scds)
5709 {
5710 struct drm_display_info *display = &connector->display_info;
5711 struct drm_hdmi_info *hdmi = &display->hdmi;
5712
5713 display->has_hdmi_infoframe = true;
5714
5715 if (hf_scds[6] & 0x80) {
5716 hdmi->scdc.supported = true;
5717 if (hf_scds[6] & 0x40)
5718 hdmi->scdc.read_request = true;
5719 }
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730 if (hf_scds[5]) {
5731
5732 u32 max_tmds_clock = hf_scds[5] * 5000;
5733 struct drm_scdc *scdc = &hdmi->scdc;
5734
5735 if (max_tmds_clock > 340000) {
5736 display->max_tmds_clock = max_tmds_clock;
5737 DRM_DEBUG_KMS("HF-VSDB: max TMDS clock %d kHz\n",
5738 display->max_tmds_clock);
5739 }
5740
5741 if (scdc->supported) {
5742 scdc->scrambling.supported = true;
5743
5744
5745 if ((hf_scds[6] & 0x8))
5746 scdc->scrambling.low_rates = true;
5747 }
5748 }
5749
5750 if (hf_scds[7]) {
5751 u8 max_frl_rate;
5752 u8 dsc_max_frl_rate;
5753 u8 dsc_max_slices;
5754 struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
5755
5756 DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
5757 max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
5758 drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
5759 &hdmi->max_frl_rate_per_lane);
5760 hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
5761
5762 if (hdmi_dsc->v_1p2) {
5763 hdmi_dsc->native_420 = hf_scds[11] & DRM_EDID_DSC_NATIVE_420;
5764 hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
5765
5766 if (hf_scds[11] & DRM_EDID_DSC_16BPC)
5767 hdmi_dsc->bpc_supported = 16;
5768 else if (hf_scds[11] & DRM_EDID_DSC_12BPC)
5769 hdmi_dsc->bpc_supported = 12;
5770 else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
5771 hdmi_dsc->bpc_supported = 10;
5772 else
5773 hdmi_dsc->bpc_supported = 0;
5774
5775 dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
5776 drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
5777 &hdmi_dsc->max_frl_rate_per_lane);
5778 hdmi_dsc->total_chunk_kbytes = hf_scds[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
5779
5780 dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
5781 switch (dsc_max_slices) {
5782 case 1:
5783 hdmi_dsc->max_slices = 1;
5784 hdmi_dsc->clk_per_slice = 340;
5785 break;
5786 case 2:
5787 hdmi_dsc->max_slices = 2;
5788 hdmi_dsc->clk_per_slice = 340;
5789 break;
5790 case 3:
5791 hdmi_dsc->max_slices = 4;
5792 hdmi_dsc->clk_per_slice = 340;
5793 break;
5794 case 4:
5795 hdmi_dsc->max_slices = 8;
5796 hdmi_dsc->clk_per_slice = 340;
5797 break;
5798 case 5:
5799 hdmi_dsc->max_slices = 8;
5800 hdmi_dsc->clk_per_slice = 400;
5801 break;
5802 case 6:
5803 hdmi_dsc->max_slices = 12;
5804 hdmi_dsc->clk_per_slice = 400;
5805 break;
5806 case 7:
5807 hdmi_dsc->max_slices = 16;
5808 hdmi_dsc->clk_per_slice = 400;
5809 break;
5810 case 0:
5811 default:
5812 hdmi_dsc->max_slices = 0;
5813 hdmi_dsc->clk_per_slice = 0;
5814 }
5815 }
5816 }
5817
5818 drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
5819 }
5820
5821 static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
5822 const u8 *hdmi)
5823 {
5824 struct drm_display_info *info = &connector->display_info;
5825 unsigned int dc_bpc = 0;
5826
5827
5828 info->bpc = 8;
5829
5830 if (cea_db_payload_len(hdmi) < 6)
5831 return;
5832
5833 if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
5834 dc_bpc = 10;
5835 info->edid_hdmi_rgb444_dc_modes |= DRM_EDID_HDMI_DC_30;
5836 DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
5837 connector->name);
5838 }
5839
5840 if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
5841 dc_bpc = 12;
5842 info->edid_hdmi_rgb444_dc_modes |= DRM_EDID_HDMI_DC_36;
5843 DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
5844 connector->name);
5845 }
5846
5847 if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
5848 dc_bpc = 16;
5849 info->edid_hdmi_rgb444_dc_modes |= DRM_EDID_HDMI_DC_48;
5850 DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
5851 connector->name);
5852 }
5853
5854 if (dc_bpc == 0) {
5855 DRM_DEBUG("%s: No deep color support on this HDMI sink.\n",
5856 connector->name);
5857 return;
5858 }
5859
5860 DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n",
5861 connector->name, dc_bpc);
5862 info->bpc = dc_bpc;
5863
5864
5865 if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) {
5866 info->edid_hdmi_ycbcr444_dc_modes = info->edid_hdmi_rgb444_dc_modes;
5867 DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n",
5868 connector->name);
5869 }
5870
5871
5872
5873
5874
5875 if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) {
5876 DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n",
5877 connector->name);
5878 }
5879 }
5880
5881 static void
5882 drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
5883 {
5884 struct drm_display_info *info = &connector->display_info;
5885 u8 len = cea_db_payload_len(db);
5886
5887 info->is_hdmi = true;
5888
5889 if (len >= 6)
5890 info->dvi_dual = db[6] & 1;
5891 if (len >= 7)
5892 info->max_tmds_clock = db[7] * 5000;
5893
5894 DRM_DEBUG_KMS("HDMI: DVI dual %d, "
5895 "max TMDS clock %d kHz\n",
5896 info->dvi_dual,
5897 info->max_tmds_clock);
5898
5899 drm_parse_hdmi_deep_color_info(connector, db);
5900 }
5901
5902
5903
5904
5905
5906 static void drm_parse_microsoft_vsdb(struct drm_connector *connector,
5907 const u8 *db)
5908 {
5909 struct drm_display_info *info = &connector->display_info;
5910 u8 version = db[4];
5911 bool desktop_usage = db[5] & BIT(6);
5912
5913
5914 if (version == 1 || version == 2 || (version == 3 && !desktop_usage))
5915 info->non_desktop = true;
5916
5917 drm_dbg_kms(connector->dev, "HMD or specialized display VSDB version %u: 0x%02x\n",
5918 version, db[5]);
5919 }
5920
5921 static void drm_parse_cea_ext(struct drm_connector *connector,
5922 const struct drm_edid *drm_edid)
5923 {
5924 struct drm_display_info *info = &connector->display_info;
5925 struct drm_edid_iter edid_iter;
5926 const struct cea_db *db;
5927 struct cea_db_iter iter;
5928 const u8 *edid_ext;
5929
5930 drm_edid_iter_begin(drm_edid, &edid_iter);
5931 drm_edid_iter_for_each(edid_ext, &edid_iter) {
5932 if (edid_ext[0] != CEA_EXT)
5933 continue;
5934
5935 if (!info->cea_rev)
5936 info->cea_rev = edid_ext[1];
5937
5938 if (info->cea_rev != edid_ext[1])
5939 DRM_DEBUG_KMS("CEA extension version mismatch %u != %u\n",
5940 info->cea_rev, edid_ext[1]);
5941
5942
5943 info->color_formats = DRM_COLOR_FORMAT_RGB444;
5944 if (edid_ext[3] & EDID_CEA_YCRCB444)
5945 info->color_formats |= DRM_COLOR_FORMAT_YCBCR444;
5946 if (edid_ext[3] & EDID_CEA_YCRCB422)
5947 info->color_formats |= DRM_COLOR_FORMAT_YCBCR422;
5948 }
5949 drm_edid_iter_end(&edid_iter);
5950
5951 cea_db_iter_edid_begin(drm_edid, &iter);
5952 cea_db_iter_for_each(db, &iter) {
5953
5954 const u8 *data = (const u8 *)db;
5955
5956 if (cea_db_is_hdmi_vsdb(db))
5957 drm_parse_hdmi_vsdb_video(connector, data);
5958 else if (cea_db_is_hdmi_forum_vsdb(db) ||
5959 cea_db_is_hdmi_forum_scdb(db))
5960 drm_parse_hdmi_forum_scds(connector, data);
5961 else if (cea_db_is_microsoft_vsdb(db))
5962 drm_parse_microsoft_vsdb(connector, data);
5963 else if (cea_db_is_y420cmdb(db))
5964 drm_parse_y420cmdb_bitmap(connector, data);
5965 else if (cea_db_is_vcdb(db))
5966 drm_parse_vcdb(connector, data);
5967 else if (cea_db_is_hdmi_hdr_metadata_block(db))
5968 drm_parse_hdr_metadata_block(connector, data);
5969 }
5970 cea_db_iter_end(&iter);
5971 }
5972
5973 static
5974 void get_monitor_range(const struct detailed_timing *timing, void *c)
5975 {
5976 struct detailed_mode_closure *closure = c;
5977 struct drm_display_info *info = &closure->connector->display_info;
5978 struct drm_monitor_range_info *monitor_range = &info->monitor_range;
5979 const struct detailed_non_pixel *data = &timing->data.other_data;
5980 const struct detailed_data_monitor_range *range = &data->data.range;
5981 const struct edid *edid = closure->drm_edid->edid;
5982
5983 if (!is_display_descriptor(timing, EDID_DETAIL_MONITOR_RANGE))
5984 return;
5985
5986
5987
5988
5989
5990
5991
5992 if (range->flags != DRM_EDID_RANGE_LIMITS_ONLY_FLAG)
5993 return;
5994
5995 monitor_range->min_vfreq = range->min_vfreq;
5996 monitor_range->max_vfreq = range->max_vfreq;
5997
5998 if (edid->revision >= 4) {
5999 if (data->pad2 & DRM_EDID_RANGE_OFFSET_MIN_VFREQ)
6000 monitor_range->min_vfreq += 255;
6001 if (data->pad2 & DRM_EDID_RANGE_OFFSET_MAX_VFREQ)
6002 monitor_range->max_vfreq += 255;
6003 }
6004 }
6005
6006 static void drm_get_monitor_range(struct drm_connector *connector,
6007 const struct drm_edid *drm_edid)
6008 {
6009 const struct drm_display_info *info = &connector->display_info;
6010 struct detailed_mode_closure closure = {
6011 .connector = connector,
6012 .drm_edid = drm_edid,
6013 };
6014
6015 if (!version_greater(drm_edid, 1, 1))
6016 return;
6017
6018 drm_for_each_detailed_block(drm_edid, get_monitor_range, &closure);
6019
6020 DRM_DEBUG_KMS("Supported Monitor Refresh rate range is %d Hz - %d Hz\n",
6021 info->monitor_range.min_vfreq,
6022 info->monitor_range.max_vfreq);
6023 }
6024
6025 static void drm_parse_vesa_mso_data(struct drm_connector *connector,
6026 const struct displayid_block *block)
6027 {
6028 struct displayid_vesa_vendor_specific_block *vesa =
6029 (struct displayid_vesa_vendor_specific_block *)block;
6030 struct drm_display_info *info = &connector->display_info;
6031
6032 if (block->num_bytes < 3) {
6033 drm_dbg_kms(connector->dev, "Unexpected vendor block size %u\n",
6034 block->num_bytes);
6035 return;
6036 }
6037
6038 if (oui(vesa->oui[0], vesa->oui[1], vesa->oui[2]) != VESA_IEEE_OUI)
6039 return;
6040
6041 if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) {
6042 drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n");
6043 return;
6044 }
6045
6046 switch (FIELD_GET(DISPLAYID_VESA_MSO_MODE, vesa->mso)) {
6047 default:
6048 drm_dbg_kms(connector->dev, "Reserved MSO mode value\n");
6049 fallthrough;
6050 case 0:
6051 info->mso_stream_count = 0;
6052 break;
6053 case 1:
6054 info->mso_stream_count = 2;
6055 break;
6056 case 2:
6057 info->mso_stream_count = 4;
6058 break;
6059 }
6060
6061 if (!info->mso_stream_count) {
6062 info->mso_pixel_overlap = 0;
6063 return;
6064 }
6065
6066 info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso);
6067 if (info->mso_pixel_overlap > 8) {
6068 drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n",
6069 info->mso_pixel_overlap);
6070 info->mso_pixel_overlap = 8;
6071 }
6072
6073 drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n",
6074 info->mso_stream_count, info->mso_pixel_overlap);
6075 }
6076
6077 static void drm_update_mso(struct drm_connector *connector,
6078 const struct drm_edid *drm_edid)
6079 {
6080 const struct displayid_block *block;
6081 struct displayid_iter iter;
6082
6083 displayid_iter_edid_begin(drm_edid, &iter);
6084 displayid_iter_for_each(block, &iter) {
6085 if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC)
6086 drm_parse_vesa_mso_data(connector, block);
6087 }
6088 displayid_iter_end(&iter);
6089 }
6090
6091
6092
6093
6094 static void drm_reset_display_info(struct drm_connector *connector)
6095 {
6096 struct drm_display_info *info = &connector->display_info;
6097
6098 info->width_mm = 0;
6099 info->height_mm = 0;
6100
6101 info->bpc = 0;
6102 info->color_formats = 0;
6103 info->cea_rev = 0;
6104 info->max_tmds_clock = 0;
6105 info->dvi_dual = false;
6106 info->is_hdmi = false;
6107 info->has_hdmi_infoframe = false;
6108 info->rgb_quant_range_selectable = false;
6109 memset(&info->hdmi, 0, sizeof(info->hdmi));
6110
6111 info->edid_hdmi_rgb444_dc_modes = 0;
6112 info->edid_hdmi_ycbcr444_dc_modes = 0;
6113
6114 info->non_desktop = 0;
6115 memset(&info->monitor_range, 0, sizeof(info->monitor_range));
6116
6117 info->mso_stream_count = 0;
6118 info->mso_pixel_overlap = 0;
6119 }
6120
6121 static u32 update_display_info(struct drm_connector *connector,
6122 const struct drm_edid *drm_edid)
6123 {
6124 struct drm_display_info *info = &connector->display_info;
6125 const struct edid *edid = drm_edid->edid;
6126
6127 u32 quirks = edid_get_quirks(drm_edid);
6128
6129 drm_reset_display_info(connector);
6130
6131 info->width_mm = edid->width_cm * 10;
6132 info->height_mm = edid->height_cm * 10;
6133
6134 drm_get_monitor_range(connector, drm_edid);
6135
6136 if (edid->revision < 3)
6137 goto out;
6138
6139 if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
6140 goto out;
6141
6142 info->color_formats |= DRM_COLOR_FORMAT_RGB444;
6143 drm_parse_cea_ext(connector, drm_edid);
6144
6145
6146
6147
6148
6149
6150
6151
6152 if (info->bpc == 0 && edid->revision == 3 &&
6153 edid->input & DRM_EDID_DIGITAL_DFP_1_X) {
6154 info->bpc = 8;
6155 DRM_DEBUG("%s: Assigning DFP sink color depth as %d bpc.\n",
6156 connector->name, info->bpc);
6157 }
6158
6159
6160 if (edid->revision < 4)
6161 goto out;
6162
6163 switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
6164 case DRM_EDID_DIGITAL_DEPTH_6:
6165 info->bpc = 6;
6166 break;
6167 case DRM_EDID_DIGITAL_DEPTH_8:
6168 info->bpc = 8;
6169 break;
6170 case DRM_EDID_DIGITAL_DEPTH_10:
6171 info->bpc = 10;
6172 break;
6173 case DRM_EDID_DIGITAL_DEPTH_12:
6174 info->bpc = 12;
6175 break;
6176 case DRM_EDID_DIGITAL_DEPTH_14:
6177 info->bpc = 14;
6178 break;
6179 case DRM_EDID_DIGITAL_DEPTH_16:
6180 info->bpc = 16;
6181 break;
6182 case DRM_EDID_DIGITAL_DEPTH_UNDEF:
6183 default:
6184 info->bpc = 0;
6185 break;
6186 }
6187
6188 DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n",
6189 connector->name, info->bpc);
6190
6191 if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
6192 info->color_formats |= DRM_COLOR_FORMAT_YCBCR444;
6193 if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
6194 info->color_formats |= DRM_COLOR_FORMAT_YCBCR422;
6195
6196 drm_update_mso(connector, drm_edid);
6197
6198 out:
6199 if (quirks & EDID_QUIRK_NON_DESKTOP) {
6200 drm_dbg_kms(connector->dev, "Non-desktop display%s\n",
6201 info->non_desktop ? " (redundant quirk)" : "");
6202 info->non_desktop = true;
6203 }
6204
6205 return quirks;
6206 }
6207
6208 static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
6209 struct displayid_detailed_timings_1 *timings,
6210 bool type_7)
6211 {
6212 struct drm_display_mode *mode;
6213 unsigned pixel_clock = (timings->pixel_clock[0] |
6214 (timings->pixel_clock[1] << 8) |
6215 (timings->pixel_clock[2] << 16)) + 1;
6216 unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
6217 unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
6218 unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
6219 unsigned hsync_width = (timings->hsw[0] | timings->hsw[1] << 8) + 1;
6220 unsigned vactive = (timings->vactive[0] | timings->vactive[1] << 8) + 1;
6221 unsigned vblank = (timings->vblank[0] | timings->vblank[1] << 8) + 1;
6222 unsigned vsync = (timings->vsync[0] | (timings->vsync[1] & 0x7f) << 8) + 1;
6223 unsigned vsync_width = (timings->vsw[0] | timings->vsw[1] << 8) + 1;
6224 bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
6225 bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
6226
6227 mode = drm_mode_create(dev);
6228 if (!mode)
6229 return NULL;
6230
6231
6232 mode->clock = type_7 ? pixel_clock : pixel_clock * 10;
6233 mode->hdisplay = hactive;
6234 mode->hsync_start = mode->hdisplay + hsync;
6235 mode->hsync_end = mode->hsync_start + hsync_width;
6236 mode->htotal = mode->hdisplay + hblank;
6237
6238 mode->vdisplay = vactive;
6239 mode->vsync_start = mode->vdisplay + vsync;
6240 mode->vsync_end = mode->vsync_start + vsync_width;
6241 mode->vtotal = mode->vdisplay + vblank;
6242
6243 mode->flags = 0;
6244 mode->flags |= hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
6245 mode->flags |= vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
6246 mode->type = DRM_MODE_TYPE_DRIVER;
6247
6248 if (timings->flags & 0x80)
6249 mode->type |= DRM_MODE_TYPE_PREFERRED;
6250 drm_mode_set_name(mode);
6251
6252 return mode;
6253 }
6254
6255 static int add_displayid_detailed_1_modes(struct drm_connector *connector,
6256 const struct displayid_block *block)
6257 {
6258 struct displayid_detailed_timing_block *det = (struct displayid_detailed_timing_block *)block;
6259 int i;
6260 int num_timings;
6261 struct drm_display_mode *newmode;
6262 int num_modes = 0;
6263 bool type_7 = block->tag == DATA_BLOCK_2_TYPE_7_DETAILED_TIMING;
6264
6265 if (block->num_bytes % 20)
6266 return 0;
6267
6268 num_timings = block->num_bytes / 20;
6269 for (i = 0; i < num_timings; i++) {
6270 struct displayid_detailed_timings_1 *timings = &det->timings[i];
6271
6272 newmode = drm_mode_displayid_detailed(connector->dev, timings, type_7);
6273 if (!newmode)
6274 continue;
6275
6276 drm_mode_probed_add(connector, newmode);
6277 num_modes++;
6278 }
6279 return num_modes;
6280 }
6281
6282 static int add_displayid_detailed_modes(struct drm_connector *connector,
6283 const struct drm_edid *drm_edid)
6284 {
6285 const struct displayid_block *block;
6286 struct displayid_iter iter;
6287 int num_modes = 0;
6288
6289 displayid_iter_edid_begin(drm_edid, &iter);
6290 displayid_iter_for_each(block, &iter) {
6291 if (block->tag == DATA_BLOCK_TYPE_1_DETAILED_TIMING ||
6292 block->tag == DATA_BLOCK_2_TYPE_7_DETAILED_TIMING)
6293 num_modes += add_displayid_detailed_1_modes(connector, block);
6294 }
6295 displayid_iter_end(&iter);
6296
6297 return num_modes;
6298 }
6299
6300 static int _drm_edid_connector_update(struct drm_connector *connector,
6301 const struct drm_edid *drm_edid)
6302 {
6303 int num_modes = 0;
6304 u32 quirks;
6305
6306 if (!drm_edid) {
6307 drm_reset_display_info(connector);
6308 clear_eld(connector);
6309 return 0;
6310 }
6311
6312
6313
6314
6315
6316
6317 quirks = update_display_info(connector, drm_edid);
6318
6319
6320 drm_edid_to_eld(connector, drm_edid);
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336 num_modes += add_detailed_modes(connector, drm_edid, quirks);
6337 num_modes += add_cvt_modes(connector, drm_edid);
6338 num_modes += add_standard_modes(connector, drm_edid);
6339 num_modes += add_established_modes(connector, drm_edid);
6340 num_modes += add_cea_modes(connector, drm_edid);
6341 num_modes += add_alternate_cea_modes(connector, drm_edid);
6342 num_modes += add_displayid_detailed_modes(connector, drm_edid);
6343 if (drm_edid->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
6344 num_modes += add_inferred_modes(connector, drm_edid);
6345
6346 if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
6347 edid_fixup_preferred(connector, quirks);
6348
6349 if (quirks & EDID_QUIRK_FORCE_6BPC)
6350 connector->display_info.bpc = 6;
6351
6352 if (quirks & EDID_QUIRK_FORCE_8BPC)
6353 connector->display_info.bpc = 8;
6354
6355 if (quirks & EDID_QUIRK_FORCE_10BPC)
6356 connector->display_info.bpc = 10;
6357
6358 if (quirks & EDID_QUIRK_FORCE_12BPC)
6359 connector->display_info.bpc = 12;
6360
6361 return num_modes;
6362 }
6363
6364 static void _drm_update_tile_info(struct drm_connector *connector,
6365 const struct drm_edid *drm_edid);
6366
6367 static int _drm_edid_connector_property_update(struct drm_connector *connector,
6368 const struct drm_edid *drm_edid)
6369 {
6370 struct drm_device *dev = connector->dev;
6371 int ret;
6372
6373 if (connector->edid_blob_ptr) {
6374 const struct edid *old_edid = connector->edid_blob_ptr->data;
6375
6376 if (old_edid) {
6377 if (!drm_edid_are_equal(drm_edid ? drm_edid->edid : NULL, old_edid)) {
6378 connector->epoch_counter++;
6379 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
6380 connector->base.id, connector->name,
6381 connector->epoch_counter);
6382 }
6383 }
6384 }
6385
6386 ret = drm_property_replace_global_blob(dev,
6387 &connector->edid_blob_ptr,
6388 drm_edid ? drm_edid->size : 0,
6389 drm_edid ? drm_edid->edid : NULL,
6390 &connector->base,
6391 dev->mode_config.edid_property);
6392 if (ret) {
6393 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed (%d)\n",
6394 connector->base.id, connector->name, ret);
6395 goto out;
6396 }
6397
6398 ret = drm_object_property_set_value(&connector->base,
6399 dev->mode_config.non_desktop_property,
6400 connector->display_info.non_desktop);
6401 if (ret) {
6402 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update failed (%d)\n",
6403 connector->base.id, connector->name, ret);
6404 goto out;
6405 }
6406
6407 ret = drm_connector_set_tile_property(connector);
6408 if (ret) {
6409 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed (%d)\n",
6410 connector->base.id, connector->name, ret);
6411 goto out;
6412 }
6413
6414 out:
6415 return ret;
6416 }
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430 int drm_edid_connector_update(struct drm_connector *connector,
6431 const struct drm_edid *drm_edid)
6432 {
6433 int count;
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452 count = _drm_edid_connector_update(connector, drm_edid);
6453
6454 _drm_update_tile_info(connector, drm_edid);
6455
6456
6457 _drm_edid_connector_property_update(connector, drm_edid);
6458
6459 return count;
6460 }
6461 EXPORT_SYMBOL(drm_edid_connector_update);
6462
6463 static int _drm_connector_update_edid_property(struct drm_connector *connector,
6464 const struct drm_edid *drm_edid)
6465 {
6466
6467 if (connector->override_edid)
6468 return 0;
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478 if (drm_edid)
6479 update_display_info(connector, drm_edid);
6480 else
6481 drm_reset_display_info(connector);
6482
6483 _drm_update_tile_info(connector, drm_edid);
6484
6485 return _drm_edid_connector_property_update(connector, drm_edid);
6486 }
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504 int drm_connector_update_edid_property(struct drm_connector *connector,
6505 const struct edid *edid)
6506 {
6507 struct drm_edid drm_edid;
6508
6509 return _drm_connector_update_edid_property(connector,
6510 drm_edid_legacy_init(&drm_edid, edid));
6511 }
6512 EXPORT_SYMBOL(drm_connector_update_edid_property);
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527 int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
6528 {
6529 struct drm_edid drm_edid;
6530
6531 if (edid && !drm_edid_is_valid(edid)) {
6532 drm_warn(connector->dev, "%s: EDID invalid.\n",
6533 connector->name);
6534 edid = NULL;
6535 }
6536
6537 return _drm_edid_connector_update(connector,
6538 drm_edid_legacy_init(&drm_edid, edid));
6539 }
6540 EXPORT_SYMBOL(drm_add_edid_modes);
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553 int drm_add_modes_noedid(struct drm_connector *connector,
6554 int hdisplay, int vdisplay)
6555 {
6556 int i, count, num_modes = 0;
6557 struct drm_display_mode *mode;
6558 struct drm_device *dev = connector->dev;
6559
6560 count = ARRAY_SIZE(drm_dmt_modes);
6561 if (hdisplay < 0)
6562 hdisplay = 0;
6563 if (vdisplay < 0)
6564 vdisplay = 0;
6565
6566 for (i = 0; i < count; i++) {
6567 const struct drm_display_mode *ptr = &drm_dmt_modes[i];
6568
6569 if (hdisplay && vdisplay) {
6570
6571
6572
6573
6574
6575 if (ptr->hdisplay > hdisplay ||
6576 ptr->vdisplay > vdisplay)
6577 continue;
6578 }
6579 if (drm_mode_vrefresh(ptr) > 61)
6580 continue;
6581 mode = drm_mode_duplicate(dev, ptr);
6582 if (mode) {
6583 drm_mode_probed_add(connector, mode);
6584 num_modes++;
6585 }
6586 }
6587 return num_modes;
6588 }
6589 EXPORT_SYMBOL(drm_add_modes_noedid);
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600 void drm_set_preferred_mode(struct drm_connector *connector,
6601 int hpref, int vpref)
6602 {
6603 struct drm_display_mode *mode;
6604
6605 list_for_each_entry(mode, &connector->probed_modes, head) {
6606 if (mode->hdisplay == hpref &&
6607 mode->vdisplay == vpref)
6608 mode->type |= DRM_MODE_TYPE_PREFERRED;
6609 }
6610 }
6611 EXPORT_SYMBOL(drm_set_preferred_mode);
6612
6613 static bool is_hdmi2_sink(const struct drm_connector *connector)
6614 {
6615
6616
6617
6618
6619 if (!connector)
6620 return true;
6621
6622 return connector->display_info.hdmi.scdc.supported ||
6623 connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR420;
6624 }
6625
6626 static u8 drm_mode_hdmi_vic(const struct drm_connector *connector,
6627 const struct drm_display_mode *mode)
6628 {
6629 bool has_hdmi_infoframe = connector ?
6630 connector->display_info.has_hdmi_infoframe : false;
6631
6632 if (!has_hdmi_infoframe)
6633 return 0;
6634
6635
6636 if (mode->flags & DRM_MODE_FLAG_3D_MASK)
6637 return 0;
6638
6639 return drm_match_hdmi_mode(mode);
6640 }
6641
6642 static u8 drm_mode_cea_vic(const struct drm_connector *connector,
6643 const struct drm_display_mode *mode)
6644 {
6645 u8 vic;
6646
6647
6648
6649
6650
6651
6652
6653 if (drm_mode_hdmi_vic(connector, mode))
6654 return 0;
6655
6656 vic = drm_match_cea_mode(mode);
6657
6658
6659
6660
6661
6662
6663 if (!is_hdmi2_sink(connector) && vic > 64)
6664 return 0;
6665
6666 return vic;
6667 }
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678 int
6679 drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
6680 const struct drm_connector *connector,
6681 const struct drm_display_mode *mode)
6682 {
6683 enum hdmi_picture_aspect picture_aspect;
6684 u8 vic, hdmi_vic;
6685
6686 if (!frame || !mode)
6687 return -EINVAL;
6688
6689 hdmi_avi_infoframe_init(frame);
6690
6691 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
6692 frame->pixel_repeat = 1;
6693
6694 vic = drm_mode_cea_vic(connector, mode);
6695 hdmi_vic = drm_mode_hdmi_vic(connector, mode);
6696
6697 frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
6698
6699
6700
6701
6702
6703
6704 frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
6705 frame->itc = 0;
6706
6707
6708
6709
6710
6711 picture_aspect = mode->picture_aspect_ratio;
6712 if (picture_aspect == HDMI_PICTURE_ASPECT_NONE) {
6713 if (vic)
6714 picture_aspect = drm_get_cea_aspect_ratio(vic);
6715 else if (hdmi_vic)
6716 picture_aspect = drm_get_hdmi_aspect_ratio(hdmi_vic);
6717 }
6718
6719
6720
6721
6722
6723
6724 if (picture_aspect > HDMI_PICTURE_ASPECT_16_9) {
6725 if (vic) {
6726 if (picture_aspect != drm_get_cea_aspect_ratio(vic))
6727 return -EINVAL;
6728 } else if (hdmi_vic) {
6729 if (picture_aspect != drm_get_hdmi_aspect_ratio(hdmi_vic))
6730 return -EINVAL;
6731 } else {
6732 return -EINVAL;
6733 }
6734
6735 picture_aspect = HDMI_PICTURE_ASPECT_NONE;
6736 }
6737
6738 frame->video_code = vic;
6739 frame->picture_aspect = picture_aspect;
6740 frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
6741 frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
6742
6743 return 0;
6744 }
6745 EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755 void
6756 drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
6757 const struct drm_connector *connector,
6758 const struct drm_display_mode *mode,
6759 enum hdmi_quantization_range rgb_quant_range)
6760 {
6761 const struct drm_display_info *info = &connector->display_info;
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773 if (info->rgb_quant_range_selectable ||
6774 rgb_quant_range == drm_default_rgb_quant_range(mode))
6775 frame->quantization_range = rgb_quant_range;
6776 else
6777 frame->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792 if (!is_hdmi2_sink(connector) ||
6793 rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
6794 frame->ycc_quantization_range =
6795 HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
6796 else
6797 frame->ycc_quantization_range =
6798 HDMI_YCC_QUANTIZATION_RANGE_FULL;
6799 }
6800 EXPORT_SYMBOL(drm_hdmi_avi_infoframe_quant_range);
6801
6802 static enum hdmi_3d_structure
6803 s3d_structure_from_display_mode(const struct drm_display_mode *mode)
6804 {
6805 u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK;
6806
6807 switch (layout) {
6808 case DRM_MODE_FLAG_3D_FRAME_PACKING:
6809 return HDMI_3D_STRUCTURE_FRAME_PACKING;
6810 case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
6811 return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE;
6812 case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
6813 return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE;
6814 case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
6815 return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL;
6816 case DRM_MODE_FLAG_3D_L_DEPTH:
6817 return HDMI_3D_STRUCTURE_L_DEPTH;
6818 case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
6819 return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH;
6820 case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
6821 return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM;
6822 case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
6823 return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF;
6824 default:
6825 return HDMI_3D_STRUCTURE_INVALID;
6826 }
6827 }
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842 int
6843 drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
6844 const struct drm_connector *connector,
6845 const struct drm_display_mode *mode)
6846 {
6847
6848
6849
6850
6851 bool has_hdmi_infoframe = connector ?
6852 connector->display_info.has_hdmi_infoframe : false;
6853 int err;
6854
6855 if (!frame || !mode)
6856 return -EINVAL;
6857
6858 if (!has_hdmi_infoframe)
6859 return -EINVAL;
6860
6861 err = hdmi_vendor_infoframe_init(frame);
6862 if (err < 0)
6863 return err;
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874 frame->vic = drm_mode_hdmi_vic(connector, mode);
6875 frame->s3d_struct = s3d_structure_from_display_mode(mode);
6876
6877 return 0;
6878 }
6879 EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
6880
6881 static void drm_parse_tiled_block(struct drm_connector *connector,
6882 const struct displayid_block *block)
6883 {
6884 const struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
6885 u16 w, h;
6886 u8 tile_v_loc, tile_h_loc;
6887 u8 num_v_tile, num_h_tile;
6888 struct drm_tile_group *tg;
6889
6890 w = tile->tile_size[0] | tile->tile_size[1] << 8;
6891 h = tile->tile_size[2] | tile->tile_size[3] << 8;
6892
6893 num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
6894 num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
6895 tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
6896 tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
6897
6898 connector->has_tile = true;
6899 if (tile->tile_cap & 0x80)
6900 connector->tile_is_single_monitor = true;
6901
6902 connector->num_h_tile = num_h_tile + 1;
6903 connector->num_v_tile = num_v_tile + 1;
6904 connector->tile_h_loc = tile_h_loc;
6905 connector->tile_v_loc = tile_v_loc;
6906 connector->tile_h_size = w + 1;
6907 connector->tile_v_size = h + 1;
6908
6909 DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
6910 DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
6911 DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
6912 num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
6913 DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
6914
6915 tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
6916 if (!tg)
6917 tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
6918 if (!tg)
6919 return;
6920
6921 if (connector->tile_group != tg) {
6922
6923
6924 if (connector->tile_group)
6925 drm_mode_put_tile_group(connector->dev, connector->tile_group);
6926 connector->tile_group = tg;
6927 } else {
6928
6929 drm_mode_put_tile_group(connector->dev, tg);
6930 }
6931 }
6932
6933 static void _drm_update_tile_info(struct drm_connector *connector,
6934 const struct drm_edid *drm_edid)
6935 {
6936 const struct displayid_block *block;
6937 struct displayid_iter iter;
6938
6939 connector->has_tile = false;
6940
6941 displayid_iter_edid_begin(drm_edid, &iter);
6942 displayid_iter_for_each(block, &iter) {
6943 if (block->tag == DATA_BLOCK_TILED_DISPLAY)
6944 drm_parse_tiled_block(connector, block);
6945 }
6946 displayid_iter_end(&iter);
6947
6948 if (!connector->has_tile && connector->tile_group) {
6949 drm_mode_put_tile_group(connector->dev, connector->tile_group);
6950 connector->tile_group = NULL;
6951 }
6952 }