1 /* From Linux kernel: drm_edid.c */ 2 /* 3 * Copyright (c) 2006 Luc Verhaegen (quirks list) 4 * Copyright (c) 2007-2008 Intel Corporation 5 * Jesse Barnes <jesse.barnes@intel.com> 6 * Copyright 2010 Red Hat, Inc. 7 * 8 * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from 9 * FB layer. 10 * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com> 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sub license, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice (including the 20 * next paragraph) shall be included in all copies or substantial portions 21 * of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 26 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 * DEALINGS IN THE SOFTWARE. 30 */ 31 32 #include <kms++/modedb.h> 33 34 #include <xf86drm.h> 35 36 namespace kms 37 { 38 39 #define DIV_ROUND(n, d) (((n) + (d) / 2) / (d)) 40 41 #define DRM_MODE(nm, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \ 42 .name = nm, .clock = (c), \ 43 .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), .htotal = (ht), .hskew = (hsk), \ 44 .vdisplay = (vd), .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), .vscan = (vs), \ 45 .vrefresh = DIV_ROUND(c * 1000, ht * vt) * (((f) & DRM_MODE_FLAG_INTERLACE) ? 2 : 1), \ 46 .flags = (f), .type = 0 47 48 /* 49 * Probably taken from CEA-861 spec. 50 * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. 51 */ 52 const Videomode cea_modes[] = { 53 /* 1 - 640x480@60Hz */ 54 { DRM_MODE("640x480", 25175, 640, 656, 55 752, 800, 0, 480, 490, 492, 525, 0, 56 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 57 }, 58 /* 2 - 720x480@60Hz */ 59 { DRM_MODE("720x480", 27000, 720, 736, 60 798, 858, 0, 480, 489, 495, 525, 0, 61 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 62 }, 63 /* 3 - 720x480@60Hz */ 64 { DRM_MODE("720x480", 27000, 720, 736, 65 798, 858, 0, 480, 489, 495, 525, 0, 66 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 67 }, 68 /* 4 - 1280x720@60Hz */ 69 { DRM_MODE("1280x720", 74250, 1280, 1390, 70 1430, 1650, 0, 720, 725, 730, 750, 0, 71 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 72 }, 73 /* 5 - 1920x1080i@60Hz */ 74 { DRM_MODE("1920x1080i", 74250, 1920, 2008, 75 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, 76 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | 77 DRM_MODE_FLAG_INTERLACE), 78 }, 79 /* 6 - 720(1440)x480i@60Hz */ 80 { DRM_MODE("720x480i", 13500, 720, 739, 81 801, 858, 0, 480, 488, 494, 525, 0, 82 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 83 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 84 }, 85 /* 7 - 720(1440)x480i@60Hz */ 86 { DRM_MODE("720x480i", 13500, 720, 739, 87 801, 858, 0, 480, 488, 494, 525, 0, 88 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 89 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 90 }, 91 /* 8 - 720(1440)x240@60Hz */ 92 { DRM_MODE("720x240", 13500, 720, 739, 93 801, 858, 0, 240, 244, 247, 262, 0, 94 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 95 DRM_MODE_FLAG_DBLCLK), 96 }, 97 /* 9 - 720(1440)x240@60Hz */ 98 { DRM_MODE("720x240", 13500, 720, 739, 99 801, 858, 0, 240, 244, 247, 262, 0, 100 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 101 DRM_MODE_FLAG_DBLCLK), 102 }, 103 /* 10 - 2880x480i@60Hz */ 104 { DRM_MODE("2880x480i", 54000, 2880, 2956, 105 3204, 3432, 0, 480, 488, 494, 525, 0, 106 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 107 DRM_MODE_FLAG_INTERLACE), 108 }, 109 /* 11 - 2880x480i@60Hz */ 110 { DRM_MODE("2880x480i", 54000, 2880, 2956, 111 3204, 3432, 0, 480, 488, 494, 525, 0, 112 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 113 DRM_MODE_FLAG_INTERLACE), 114 }, 115 /* 12 - 2880x240@60Hz */ 116 { DRM_MODE("2880x240", 54000, 2880, 2956, 117 3204, 3432, 0, 240, 244, 247, 262, 0, 118 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 119 }, 120 /* 13 - 2880x240@60Hz */ 121 { DRM_MODE("2880x240", 54000, 2880, 2956, 122 3204, 3432, 0, 240, 244, 247, 262, 0, 123 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 124 }, 125 /* 14 - 1440x480@60Hz */ 126 { DRM_MODE("1440x480", 54000, 1440, 1472, 127 1596, 1716, 0, 480, 489, 495, 525, 0, 128 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 129 }, 130 /* 15 - 1440x480@60Hz */ 131 { DRM_MODE("1440x480", 54000, 1440, 1472, 132 1596, 1716, 0, 480, 489, 495, 525, 0, 133 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 134 }, 135 /* 16 - 1920x1080@60Hz */ 136 { DRM_MODE("1920x1080", 148500, 1920, 2008, 137 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, 138 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 139 }, 140 /* 17 - 720x576@50Hz */ 141 { DRM_MODE("720x576", 27000, 720, 732, 142 796, 864, 0, 576, 581, 586, 625, 0, 143 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 144 }, 145 /* 18 - 720x576@50Hz */ 146 { DRM_MODE("720x576", 27000, 720, 732, 147 796, 864, 0, 576, 581, 586, 625, 0, 148 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 149 }, 150 /* 19 - 1280x720@50Hz */ 151 { DRM_MODE("1280x720", 74250, 1280, 1720, 152 1760, 1980, 0, 720, 725, 730, 750, 0, 153 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 154 }, 155 /* 20 - 1920x1080i@50Hz */ 156 { DRM_MODE("1920x1080i", 74250, 1920, 2448, 157 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, 158 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | 159 DRM_MODE_FLAG_INTERLACE), 160 }, 161 /* 21 - 720(1440)x576i@50Hz */ 162 { DRM_MODE("720x576i", 13500, 720, 732, 163 795, 864, 0, 576, 580, 586, 625, 0, 164 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 165 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 166 }, 167 /* 22 - 720(1440)x576i@50Hz */ 168 { DRM_MODE("720x576i", 13500, 720, 732, 169 795, 864, 0, 576, 580, 586, 625, 0, 170 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 171 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 172 }, 173 /* 23 - 720(1440)x288@50Hz */ 174 { DRM_MODE("720x288", 13500, 720, 732, 175 795, 864, 0, 288, 290, 293, 312, 0, 176 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 177 DRM_MODE_FLAG_DBLCLK), 178 }, 179 /* 24 - 720(1440)x288@50Hz */ 180 { DRM_MODE("720x288", 13500, 720, 732, 181 795, 864, 0, 288, 290, 293, 312, 0, 182 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 183 DRM_MODE_FLAG_DBLCLK), 184 }, 185 /* 25 - 2880x576i@50Hz */ 186 { DRM_MODE("2880x576i", 54000, 2880, 2928, 187 3180, 3456, 0, 576, 580, 586, 625, 0, 188 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 189 DRM_MODE_FLAG_INTERLACE), 190 }, 191 /* 26 - 2880x576i@50Hz */ 192 { DRM_MODE("2880x576i", 54000, 2880, 2928, 193 3180, 3456, 0, 576, 580, 586, 625, 0, 194 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 195 DRM_MODE_FLAG_INTERLACE), 196 }, 197 /* 27 - 2880x288@50Hz */ 198 { DRM_MODE("2880x288", 54000, 2880, 2928, 199 3180, 3456, 0, 288, 290, 293, 312, 0, 200 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 201 }, 202 /* 28 - 2880x288@50Hz */ 203 { DRM_MODE("2880x288", 54000, 2880, 2928, 204 3180, 3456, 0, 288, 290, 293, 312, 0, 205 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 206 }, 207 /* 29 - 1440x576@50Hz */ 208 { DRM_MODE("1440x576", 54000, 1440, 1464, 209 1592, 1728, 0, 576, 581, 586, 625, 0, 210 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 211 }, 212 /* 30 - 1440x576@50Hz */ 213 { DRM_MODE("1440x576", 54000, 1440, 1464, 214 1592, 1728, 0, 576, 581, 586, 625, 0, 215 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 216 }, 217 /* 31 - 1920x1080@50Hz */ 218 { DRM_MODE("1920x1080", 148500, 1920, 2448, 219 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, 220 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 221 }, 222 /* 32 - 1920x1080@24Hz */ 223 { DRM_MODE("1920x1080", 74250, 1920, 2558, 224 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, 225 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 226 }, 227 /* 33 - 1920x1080@25Hz */ 228 { DRM_MODE("1920x1080", 74250, 1920, 2448, 229 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, 230 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 231 }, 232 /* 34 - 1920x1080@30Hz */ 233 { DRM_MODE("1920x1080", 74250, 1920, 2008, 234 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, 235 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 236 }, 237 /* 35 - 2880x480@60Hz */ 238 { DRM_MODE("2880x480", 108000, 2880, 2944, 239 3192, 3432, 0, 480, 489, 495, 525, 0, 240 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 241 }, 242 /* 36 - 2880x480@60Hz */ 243 { DRM_MODE("2880x480", 108000, 2880, 2944, 244 3192, 3432, 0, 480, 489, 495, 525, 0, 245 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 246 }, 247 /* 37 - 2880x576@50Hz */ 248 { DRM_MODE("2880x576", 108000, 2880, 2928, 249 3184, 3456, 0, 576, 581, 586, 625, 0, 250 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 251 }, 252 /* 38 - 2880x576@50Hz */ 253 { DRM_MODE("2880x576", 108000, 2880, 2928, 254 3184, 3456, 0, 576, 581, 586, 625, 0, 255 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 256 }, 257 /* 39 - 1920x1080i@50Hz */ 258 { DRM_MODE("1920x1080i", 72000, 1920, 1952, 259 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, 260 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | 261 DRM_MODE_FLAG_INTERLACE), 262 }, 263 /* 40 - 1920x1080i@100Hz */ 264 { DRM_MODE("1920x1080i", 148500, 1920, 2448, 265 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, 266 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | 267 DRM_MODE_FLAG_INTERLACE), 268 }, 269 /* 41 - 1280x720@100Hz */ 270 { DRM_MODE("1280x720", 148500, 1280, 1720, 271 1760, 1980, 0, 720, 725, 730, 750, 0, 272 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 273 }, 274 /* 42 - 720x576@100Hz */ 275 { DRM_MODE("720x576", 54000, 720, 732, 276 796, 864, 0, 576, 581, 586, 625, 0, 277 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 278 }, 279 /* 43 - 720x576@100Hz */ 280 { DRM_MODE("720x576", 54000, 720, 732, 281 796, 864, 0, 576, 581, 586, 625, 0, 282 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 283 }, 284 /* 44 - 720(1440)x576i@100Hz */ 285 { DRM_MODE("720x576i", 27000, 720, 732, 286 795, 864, 0, 576, 580, 586, 625, 0, 287 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 288 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 289 }, 290 /* 45 - 720(1440)x576i@100Hz */ 291 { DRM_MODE("720x576i", 27000, 720, 732, 292 795, 864, 0, 576, 580, 586, 625, 0, 293 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 294 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 295 }, 296 /* 46 - 1920x1080i@120Hz */ 297 { DRM_MODE("1920x1080i", 148500, 1920, 2008, 298 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, 299 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | 300 DRM_MODE_FLAG_INTERLACE), 301 }, 302 /* 47 - 1280x720@120Hz */ 303 { DRM_MODE("1280x720", 148500, 1280, 1390, 304 1430, 1650, 0, 720, 725, 730, 750, 0, 305 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 306 }, 307 /* 48 - 720x480@120Hz */ 308 { DRM_MODE("720x480", 54000, 720, 736, 309 798, 858, 0, 480, 489, 495, 525, 0, 310 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 311 }, 312 /* 49 - 720x480@120Hz */ 313 { DRM_MODE("720x480", 54000, 720, 736, 314 798, 858, 0, 480, 489, 495, 525, 0, 315 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 316 }, 317 /* 50 - 720(1440)x480i@120Hz */ 318 { DRM_MODE("720x480i", 27000, 720, 739, 319 801, 858, 0, 480, 488, 494, 525, 0, 320 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 321 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 322 }, 323 /* 51 - 720(1440)x480i@120Hz */ 324 { DRM_MODE("720x480i", 27000, 720, 739, 325 801, 858, 0, 480, 488, 494, 525, 0, 326 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 327 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 328 }, 329 /* 52 - 720x576@200Hz */ 330 { DRM_MODE("720x576", 108000, 720, 732, 331 796, 864, 0, 576, 581, 586, 625, 0, 332 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 333 }, 334 /* 53 - 720x576@200Hz */ 335 { DRM_MODE("720x576", 108000, 720, 732, 336 796, 864, 0, 576, 581, 586, 625, 0, 337 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 338 }, 339 /* 54 - 720(1440)x576i@200Hz */ 340 { DRM_MODE("720x576i", 54000, 720, 732, 341 795, 864, 0, 576, 580, 586, 625, 0, 342 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 343 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 344 }, 345 /* 55 - 720(1440)x576i@200Hz */ 346 { DRM_MODE("720x576i", 54000, 720, 732, 347 795, 864, 0, 576, 580, 586, 625, 0, 348 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 349 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 350 }, 351 /* 56 - 720x480@240Hz */ 352 { DRM_MODE("720x480", 108000, 720, 736, 353 798, 858, 0, 480, 489, 495, 525, 0, 354 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 355 }, 356 /* 57 - 720x480@240Hz */ 357 { DRM_MODE("720x480", 108000, 720, 736, 358 798, 858, 0, 480, 489, 495, 525, 0, 359 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 360 }, 361 /* 58 - 720(1440)x480i@240 */ 362 { DRM_MODE("720x480i", 54000, 720, 739, 363 801, 858, 0, 480, 488, 494, 525, 0, 364 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 365 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 366 }, 367 /* 59 - 720(1440)x480i@240 */ 368 { DRM_MODE("720x480i", 54000, 720, 739, 369 801, 858, 0, 480, 488, 494, 525, 0, 370 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 371 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 372 }, 373 /* 60 - 1280x720@24Hz */ 374 { DRM_MODE("1280x720", 59400, 1280, 3040, 375 3080, 3300, 0, 720, 725, 730, 750, 0, 376 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 377 }, 378 /* 61 - 1280x720@25Hz */ 379 { DRM_MODE("1280x720", 74250, 1280, 3700, 380 3740, 3960, 0, 720, 725, 730, 750, 0, 381 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 382 }, 383 /* 62 - 1280x720@30Hz */ 384 { DRM_MODE("1280x720", 74250, 1280, 3040, 385 3080, 3300, 0, 720, 725, 730, 750, 0, 386 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 387 }, 388 /* 63 - 1920x1080@120Hz */ 389 { DRM_MODE("1920x1080", 297000, 1920, 2008, 390 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, 391 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 392 }, 393 /* 64 - 1920x1080@100Hz */ 394 { DRM_MODE("1920x1080", 297000, 1920, 2448, 395 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, 396 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), 397 }, 398 /* TERMINATOR */ 399 { }, 400 }; 401 402 } 403