Rev 1125 | Rev 1221 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1125 | Rev 1179 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | */ |
28 | */ |
29 | //#include |
29 | //#include |
30 | #include |
30 | #include |
31 | #include |
31 | #include |
Line 32... | Line -... | ||
32 | - | ||
33 | #include |
32 | |
34 | #include |
33 | #include |
35 | #include |
34 | #include |
36 | #include "drmP.h" |
35 | #include "drmP.h" |
Line 37... | Line -... | ||
37 | #include "drm_edid.h" |
- | |
38 | - | ||
39 | - | ||
40 | 36 | #include "drm_edid.h" |
|
41 | 37 | ||
42 | /* |
38 | /* |
43 | * TODO: |
39 | * TODO: |
Line 65... | Line 61... | ||
65 | #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4) |
61 | #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4) |
66 | /* Monitor forgot to set the first detailed is preferred bit. */ |
62 | /* Monitor forgot to set the first detailed is preferred bit. */ |
67 | #define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) |
63 | #define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) |
68 | /* use +hsync +vsync for detailed mode */ |
64 | /* use +hsync +vsync for detailed mode */ |
69 | #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) |
65 | #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) |
- | 66 | /* define the number of Extension EDID block */ |
|
- | 67 | #define MAX_EDID_EXT_NUM 4 |
|
- | 68 | ||
- | 69 | #define LEVEL_DMT 0 |
|
- | 70 | #define LEVEL_GTF 1 |
|
- | 71 | #define LEVEL_CVT 2 |
|
Line 70... | Line 72... | ||
70 | 72 | ||
71 | static struct edid_quirk { |
73 | static struct edid_quirk { |
72 | char *vendor; |
74 | char *vendor; |
73 | int product_id; |
75 | int product_id; |
Line 242... | Line 244... | ||
242 | } |
244 | } |
Line 243... | Line 245... | ||
243 | 245 | ||
244 | preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; |
246 | preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; |
Line -... | Line 247... | ||
- | 247 | } |
|
- | 248 | ||
- | 249 | /* |
|
- | 250 | * Add the Autogenerated from the DMT spec. |
|
- | 251 | * This table is copied from xfree86/modes/xf86EdidModes.c. |
|
- | 252 | * But the mode with Reduced blank feature is deleted. |
|
- | 253 | */ |
|
- | 254 | static struct drm_display_mode drm_dmt_modes[] = { |
|
- | 255 | /* 640x350@85Hz */ |
|
- | 256 | { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, |
|
- | 257 | 736, 832, 0, 350, 382, 385, 445, 0, |
|
- | 258 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 259 | /* 640x400@85Hz */ |
|
- | 260 | { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, |
|
- | 261 | 736, 832, 0, 400, 401, 404, 445, 0, |
|
- | 262 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 263 | /* 720x400@85Hz */ |
|
- | 264 | { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756, |
|
- | 265 | 828, 936, 0, 400, 401, 404, 446, 0, |
|
- | 266 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 267 | /* 640x480@60Hz */ |
|
- | 268 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, |
|
- | 269 | 752, 800, 0, 480, 489, 492, 525, 0, |
|
- | 270 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 271 | /* 640x480@72Hz */ |
|
- | 272 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, |
|
- | 273 | 704, 832, 0, 480, 489, 492, 520, 0, |
|
- | 274 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 275 | /* 640x480@75Hz */ |
|
- | 276 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656, |
|
- | 277 | 720, 840, 0, 480, 481, 484, 500, 0, |
|
- | 278 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 279 | /* 640x480@85Hz */ |
|
- | 280 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696, |
|
- | 281 | 752, 832, 0, 480, 481, 484, 509, 0, |
|
- | 282 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 283 | /* 800x600@56Hz */ |
|
- | 284 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824, |
|
- | 285 | 896, 1024, 0, 600, 601, 603, 625, 0, |
|
- | 286 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 287 | /* 800x600@60Hz */ |
|
- | 288 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, |
|
- | 289 | 968, 1056, 0, 600, 601, 605, 628, 0, |
|
- | 290 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 291 | /* 800x600@72Hz */ |
|
- | 292 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856, |
|
- | 293 | 976, 1040, 0, 600, 637, 643, 666, 0, |
|
- | 294 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 295 | /* 800x600@75Hz */ |
|
- | 296 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816, |
|
- | 297 | 896, 1056, 0, 600, 601, 604, 625, 0, |
|
- | 298 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 299 | /* 800x600@85Hz */ |
|
- | 300 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832, |
|
- | 301 | 896, 1048, 0, 600, 601, 604, 631, 0, |
|
- | 302 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 303 | /* 848x480@60Hz */ |
|
- | 304 | { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864, |
|
- | 305 | 976, 1088, 0, 480, 486, 494, 517, 0, |
|
- | 306 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 307 | /* 1024x768@43Hz, interlace */ |
|
- | 308 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, |
|
- | 309 | 1208, 1264, 0, 768, 768, 772, 817, 0, |
|
- | 310 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
|
- | 311 | DRM_MODE_FLAG_INTERLACE) }, |
|
- | 312 | /* 1024x768@60Hz */ |
|
- | 313 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, |
|
- | 314 | 1184, 1344, 0, 768, 771, 777, 806, 0, |
|
- | 315 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 316 | /* 1024x768@70Hz */ |
|
- | 317 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, |
|
- | 318 | 1184, 1328, 0, 768, 771, 777, 806, 0, |
|
- | 319 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 320 | /* 1024x768@75Hz */ |
|
- | 321 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040, |
|
- | 322 | 1136, 1312, 0, 768, 769, 772, 800, 0, |
|
- | 323 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 324 | /* 1024x768@85Hz */ |
|
- | 325 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, |
|
- | 326 | 1072, 1376, 0, 768, 769, 772, 808, 0, |
|
- | 327 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 328 | /* 1152x864@75Hz */ |
|
- | 329 | { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, |
|
- | 330 | 1344, 1600, 0, 864, 865, 868, 900, 0, |
|
- | 331 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 332 | /* 1280x768@60Hz */ |
|
- | 333 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, |
|
- | 334 | 1472, 1664, 0, 768, 771, 778, 798, 0, |
|
- | 335 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 336 | /* 1280x768@75Hz */ |
|
- | 337 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360, |
|
- | 338 | 1488, 1696, 0, 768, 771, 778, 805, 0, |
|
- | 339 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 340 | /* 1280x768@85Hz */ |
|
- | 341 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360, |
|
- | 342 | 1496, 1712, 0, 768, 771, 778, 809, 0, |
|
- | 343 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 344 | /* 1280x800@60Hz */ |
|
- | 345 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, |
|
- | 346 | 1480, 1680, 0, 800, 803, 809, 831, 0, |
|
- | 347 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
|
- | 348 | /* 1280x800@75Hz */ |
|
- | 349 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360, |
|
- | 350 | 1488, 1696, 0, 800, 803, 809, 838, 0, |
|
- | 351 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 352 | /* 1280x800@85Hz */ |
|
- | 353 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360, |
|
- | 354 | 1496, 1712, 0, 800, 803, 809, 843, 0, |
|
- | 355 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 356 | /* 1280x960@60Hz */ |
|
- | 357 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, |
|
- | 358 | 1488, 1800, 0, 960, 961, 964, 1000, 0, |
|
- | 359 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 360 | /* 1280x960@85Hz */ |
|
- | 361 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344, |
|
- | 362 | 1504, 1728, 0, 960, 961, 964, 1011, 0, |
|
- | 363 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 364 | /* 1280x1024@60Hz */ |
|
- | 365 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, |
|
- | 366 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, |
|
- | 367 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 368 | /* 1280x1024@75Hz */ |
|
- | 369 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, |
|
- | 370 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, |
|
- | 371 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 372 | /* 1280x1024@85Hz */ |
|
- | 373 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344, |
|
- | 374 | 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, |
|
- | 375 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 376 | /* 1360x768@60Hz */ |
|
- | 377 | { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, |
|
- | 378 | 1536, 1792, 0, 768, 771, 777, 795, 0, |
|
- | 379 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 380 | /* 1440x1050@60Hz */ |
|
- | 381 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, |
|
- | 382 | 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, |
|
- | 383 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 384 | /* 1440x1050@75Hz */ |
|
- | 385 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504, |
|
- | 386 | 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, |
|
- | 387 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 388 | /* 1440x1050@85Hz */ |
|
- | 389 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504, |
|
- | 390 | 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, |
|
- | 391 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 392 | /* 1440x900@60Hz */ |
|
- | 393 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, |
|
- | 394 | 1672, 1904, 0, 900, 903, 909, 934, 0, |
|
- | 395 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 396 | /* 1440x900@75Hz */ |
|
- | 397 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536, |
|
- | 398 | 1688, 1936, 0, 900, 903, 909, 942, 0, |
|
- | 399 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 400 | /* 1440x900@85Hz */ |
|
- | 401 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544, |
|
- | 402 | 1696, 1952, 0, 900, 903, 909, 948, 0, |
|
- | 403 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 404 | /* 1600x1200@60Hz */ |
|
- | 405 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, |
|
- | 406 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
|
- | 407 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 408 | /* 1600x1200@65Hz */ |
|
- | 409 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664, |
|
- | 410 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
|
- | 411 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 412 | /* 1600x1200@70Hz */ |
|
- | 413 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664, |
|
- | 414 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
|
- | 415 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 416 | /* 1600x1200@75Hz */ |
|
- | 417 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 2025000, 1600, 1664, |
|
- | 418 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
|
- | 419 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 420 | /* 1600x1200@85Hz */ |
|
- | 421 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664, |
|
- | 422 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
|
- | 423 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 424 | /* 1680x1050@60Hz */ |
|
- | 425 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, |
|
- | 426 | 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, |
|
- | 427 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 428 | /* 1680x1050@75Hz */ |
|
- | 429 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800, |
|
- | 430 | 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, |
|
- | 431 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 432 | /* 1680x1050@85Hz */ |
|
- | 433 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808, |
|
- | 434 | 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, |
|
- | 435 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 436 | /* 1792x1344@60Hz */ |
|
- | 437 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, |
|
- | 438 | 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, |
|
- | 439 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 440 | /* 1729x1344@75Hz */ |
|
- | 441 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888, |
|
- | 442 | 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, |
|
- | 443 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 444 | /* 1853x1392@60Hz */ |
|
- | 445 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, |
|
- | 446 | 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, |
|
- | 447 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 448 | /* 1856x1392@75Hz */ |
|
- | 449 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984, |
|
- | 450 | 2208, 2560, 0, 1392, 1395, 1399, 1500, 0, |
|
- | 451 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 452 | /* 1920x1200@60Hz */ |
|
- | 453 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, |
|
- | 454 | 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, |
|
- | 455 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 456 | /* 1920x1200@75Hz */ |
|
- | 457 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056, |
|
- | 458 | 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, |
|
- | 459 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 460 | /* 1920x1200@85Hz */ |
|
- | 461 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064, |
|
- | 462 | 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, |
|
- | 463 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 464 | /* 1920x1440@60Hz */ |
|
- | 465 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, |
|
- | 466 | 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, |
|
- | 467 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 468 | /* 1920x1440@75Hz */ |
|
- | 469 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064, |
|
- | 470 | 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, |
|
- | 471 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 472 | /* 2560x1600@60Hz */ |
|
- | 473 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, |
|
- | 474 | 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, |
|
- | 475 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 476 | /* 2560x1600@75HZ */ |
|
- | 477 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768, |
|
- | 478 | 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, |
|
- | 479 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 480 | /* 2560x1600@85HZ */ |
|
- | 481 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768, |
|
- | 482 | 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, |
|
- | 483 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
|
- | 484 | }; |
|
- | 485 | ||
- | 486 | static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, |
|
- | 487 | int hsize, int vsize, int fresh) |
|
- | 488 | { |
|
- | 489 | int i, count; |
|
- | 490 | struct drm_display_mode *ptr, *mode; |
|
- | 491 | ||
- | 492 | count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); |
|
- | 493 | mode = NULL; |
|
- | 494 | for (i = 0; i < count; i++) { |
|
- | 495 | ptr = &drm_dmt_modes[i]; |
|
- | 496 | if (hsize == ptr->hdisplay && |
|
- | 497 | vsize == ptr->vdisplay && |
|
- | 498 | fresh == drm_mode_vrefresh(ptr)) { |
|
- | 499 | /* get the expected default mode */ |
|
- | 500 | mode = drm_mode_duplicate(dev, ptr); |
|
- | 501 | break; |
|
- | 502 | } |
|
- | 503 | } |
|
245 | } |
504 | return mode; |
246 | 505 | } |
|
247 | /** |
506 | /** |
248 | * drm_mode_std - convert standard mode info (width, height, refresh) into mode |
507 | * drm_mode_std - convert standard mode info (width, height, refresh) into mode |
249 | * @t: standard timing params |
508 | * @t: standard timing params |
Line 253... | Line 512... | ||
253 | * |
512 | * |
254 | * Punts for now, but should eventually use the FB layer's CVT based mode |
513 | * Punts for now, but should eventually use the FB layer's CVT based mode |
255 | * generation code. |
514 | * generation code. |
256 | */ |
515 | */ |
257 | struct drm_display_mode *drm_mode_std(struct drm_device *dev, |
516 | struct drm_display_mode *drm_mode_std(struct drm_device *dev, |
258 | struct std_timing *t) |
517 | struct std_timing *t, |
- | 518 | int timing_level) |
|
259 | { |
519 | { |
260 | struct drm_display_mode *mode; |
520 | struct drm_display_mode *mode; |
261 | int hsize = t->hsize * 8 + 248, vsize; |
521 | int hsize, vsize; |
- | 522 | int vrefresh_rate; |
|
262 | unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) |
523 | unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) |
263 | >> EDID_TIMING_ASPECT_SHIFT; |
524 | >> EDID_TIMING_ASPECT_SHIFT; |
- | 525 | unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) |
|
- | 526 | >> EDID_TIMING_VFREQ_SHIFT; |
|
Line -... | Line 527... | ||
- | 527 | ||
264 | 528 | /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ |
|
265 | mode = drm_mode_create(dev); |
529 | hsize = t->hsize * 8 + 248; |
266 | if (!mode) |
530 | /* vrefresh_rate = vfreq + 60 */ |
- | 531 | vrefresh_rate = vfreq + 60; |
|
Line 267... | Line 532... | ||
267 | return NULL; |
532 | /* the vdisplay is calculated based on the aspect ratio */ |
268 | 533 | ||
269 | if (aspect_ratio == 0) |
534 | if (aspect_ratio == 0) |
270 | vsize = (hsize * 10) / 16; |
535 | vsize = (hsize * 10) / 16; |
271 | else if (aspect_ratio == 1) |
536 | else if (aspect_ratio == 1) |
272 | vsize = (hsize * 3) / 4; |
537 | vsize = (hsize * 3) / 4; |
273 | else if (aspect_ratio == 2) |
538 | else if (aspect_ratio == 2) |
274 | vsize = (hsize * 4) / 5; |
539 | vsize = (hsize * 4) / 5; |
- | 540 | else |
|
- | 541 | vsize = (hsize * 9) / 16; |
|
- | 542 | /* HDTV hack */ |
|
- | 543 | if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { |
|
- | 544 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
|
- | 545 | mode->hdisplay = 1366; |
|
- | 546 | mode->vsync_start = mode->vsync_start - 1; |
|
- | 547 | mode->vsync_end = mode->vsync_end - 1; |
|
- | 548 | return mode; |
|
- | 549 | } |
|
- | 550 | mode = NULL; |
|
- | 551 | /* check whether it can be found in default mode table */ |
|
- | 552 | mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate); |
|
Line 275... | Line 553... | ||
275 | else |
553 | if (mode) |
- | 554 | return mode; |
|
- | 555 | ||
- | 556 | switch (timing_level) { |
|
- | 557 | case LEVEL_DMT: |
|
- | 558 | break; |
|
- | 559 | case LEVEL_GTF: |
|
- | 560 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
|
- | 561 | break; |
|
276 | vsize = (hsize * 9) / 16; |
562 | case LEVEL_CVT: |
277 | 563 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
|
278 | drm_mode_set_name(mode); |
564 | break; |
Line 279... | Line 565... | ||
279 | 565 | } |
|
280 | return mode; |
566 | return mode; |
Line 456... | Line 742... | ||
456 | } |
742 | } |
457 | } |
743 | } |
Line 458... | Line 744... | ||
458 | 744 | ||
459 | return modes; |
745 | return modes; |
- | 746 | } |
|
- | 747 | /** |
|
- | 748 | * stanard_timing_level - get std. timing level(CVT/GTF/DMT) |
|
- | 749 | * @edid: EDID block to scan |
|
- | 750 | */ |
|
- | 751 | static int standard_timing_level(struct edid *edid) |
|
- | 752 | { |
|
- | 753 | if (edid->revision >= 2) { |
|
- | 754 | if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)) |
|
- | 755 | return LEVEL_CVT; |
|
- | 756 | return LEVEL_GTF; |
|
- | 757 | } |
|
- | 758 | return LEVEL_DMT; |
|
Line 460... | Line 759... | ||
460 | } |
759 | } |
461 | 760 | ||
462 | /** |
761 | /** |
463 | * add_standard_modes - get std. modes from EDID and add them |
762 | * add_standard_modes - get std. modes from EDID and add them |
Line 468... | Line 767... | ||
468 | */ |
767 | */ |
469 | static int add_standard_modes(struct drm_connector *connector, struct edid *edid) |
768 | static int add_standard_modes(struct drm_connector *connector, struct edid *edid) |
470 | { |
769 | { |
471 | struct drm_device *dev = connector->dev; |
770 | struct drm_device *dev = connector->dev; |
472 | int i, modes = 0; |
771 | int i, modes = 0; |
- | 772 | int timing_level; |
|
- | 773 | ||
- | 774 | timing_level = standard_timing_level(edid); |
|
Line 473... | Line 775... | ||
473 | 775 | ||
474 | for (i = 0; i < EDID_STD_TIMINGS; i++) { |
776 | for (i = 0; i < EDID_STD_TIMINGS; i++) { |
475 | struct std_timing *t = &edid->standard_timings[i]; |
777 | struct std_timing *t = &edid->standard_timings[i]; |
Line 476... | Line 778... | ||
476 | struct drm_display_mode *newmode; |
778 | struct drm_display_mode *newmode; |
477 | 779 | ||
478 | /* If std timings bytes are 1, 1 it's empty */ |
780 | /* If std timings bytes are 1, 1 it's empty */ |
Line 479... | Line 781... | ||
479 | if (t->hsize == 1 && t->vfreq_aspect == 1) |
781 | if (t->hsize == 1 && t->vfreq_aspect == 1) |
- | 782 | continue; |
|
480 | continue; |
783 | |
481 | 784 | newmode = drm_mode_std(dev, &edid->standard_timings[i], |
|
482 | newmode = drm_mode_std(dev, &edid->standard_timings[i]); |
785 | timing_level); |
483 | if (newmode) { |
786 | if (newmode) { |
484 | drm_mode_probed_add(connector, newmode); |
787 | drm_mode_probed_add(connector, newmode); |
Line 501... | Line 804... | ||
501 | static int add_detailed_info(struct drm_connector *connector, |
804 | static int add_detailed_info(struct drm_connector *connector, |
502 | struct edid *edid, u32 quirks) |
805 | struct edid *edid, u32 quirks) |
503 | { |
806 | { |
504 | struct drm_device *dev = connector->dev; |
807 | struct drm_device *dev = connector->dev; |
505 | int i, j, modes = 0; |
808 | int i, j, modes = 0; |
- | 809 | int timing_level; |
|
- | 810 | ||
- | 811 | timing_level = standard_timing_level(edid); |
|
Line 506... | Line 812... | ||
506 | 812 | ||
507 | for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { |
813 | for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { |
508 | struct detailed_timing *timing = &edid->detailed_timings[i]; |
814 | struct detailed_timing *timing = &edid->detailed_timings[i]; |
509 | struct detailed_non_pixel *data = &timing->data.other_data; |
815 | struct detailed_non_pixel *data = &timing->data.other_data; |
Line 510... | Line 816... | ||
510 | struct drm_display_mode *newmode; |
816 | struct drm_display_mode *newmode; |
511 | 817 | ||
- | 818 | /* X server check is version 1.1 or higher */ |
|
- | 819 | if (edid->version == 1 && edid->revision >= 1 && |
|
- | 820 | !timing->pixel_clock) { |
|
- | 821 | /* Other timing or info */ |
|
- | 822 | switch (data->type) { |
|
- | 823 | case EDID_DETAIL_MONITOR_SERIAL: |
|
- | 824 | break; |
|
- | 825 | case EDID_DETAIL_MONITOR_STRING: |
|
- | 826 | break; |
|
- | 827 | case EDID_DETAIL_MONITOR_RANGE: |
|
- | 828 | /* Get monitor range data */ |
|
- | 829 | break; |
|
- | 830 | case EDID_DETAIL_MONITOR_NAME: |
|
512 | /* EDID up to and including 1.2 may put monitor info here */ |
831 | break; |
- | 832 | case EDID_DETAIL_MONITOR_CPDATA: |
|
- | 833 | break; |
|
- | 834 | case EDID_DETAIL_STD_MODES: |
|
- | 835 | /* Five modes per detailed section */ |
|
- | 836 | for (j = 0; j < 5; i++) { |
|
Line 513... | Line 837... | ||
513 | if (edid->version == 1 && edid->revision < 3) |
837 | struct std_timing *std; |
- | 838 | struct drm_display_mode *newmode; |
|
- | 839 | ||
514 | continue; |
840 | std = &data->data.timings[j]; |
- | 841 | newmode = drm_mode_std(dev, std, |
|
- | 842 | timing_level); |
|
- | 843 | if (newmode) { |
|
- | 844 | drm_mode_probed_add(connector, newmode); |
|
- | 845 | modes++; |
|
- | 846 | } |
|
- | 847 | } |
|
- | 848 | break; |
|
- | 849 | default: |
|
515 | 850 | break; |
|
516 | /* Detailed mode timing */ |
851 | } |
517 | if (timing->pixel_clock) { |
852 | } else { |
Line 518... | Line 853... | ||
518 | newmode = drm_mode_detailed(dev, edid, timing, quirks); |
853 | newmode = drm_mode_detailed(dev, edid, timing, quirks); |
519 | if (!newmode) |
854 | if (!newmode) |
520 | continue; |
855 | continue; |
521 | 856 | ||
Line 522... | Line 857... | ||
522 | /* First detailed mode is preferred */ |
857 | /* First detailed mode is preferred */ |
- | 858 | if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) |
|
- | 859 | newmode->type |= DRM_MODE_TYPE_PREFERRED; |
|
- | 860 | drm_mode_probed_add(connector, newmode); |
|
- | 861 | ||
- | 862 | modes++; |
|
- | 863 | } |
|
- | 864 | } |
|
- | 865 | ||
- | 866 | return modes; |
|
- | 867 | } |
|
- | 868 | /** |
|
- | 869 | * add_detailed_mode_eedid - get detailed mode info from addtional timing |
|
- | 870 | * EDID block |
|
- | 871 | * @connector: attached connector |
|
- | 872 | * @edid: EDID block to scan(It is only to get addtional timing EDID block) |
|
- | 873 | * @quirks: quirks to apply |
|
- | 874 | * |
|
- | 875 | * Some of the detailed timing sections may contain mode information. Grab |
|
- | 876 | * it and add it to the list. |
|
- | 877 | */ |
|
- | 878 | static int add_detailed_info_eedid(struct drm_connector *connector, |
|
- | 879 | struct edid *edid, u32 quirks) |
|
- | 880 | { |
|
- | 881 | struct drm_device *dev = connector->dev; |
|
- | 882 | int i, j, modes = 0; |
|
- | 883 | char *edid_ext = NULL; |
|
- | 884 | struct detailed_timing *timing; |
|
- | 885 | struct detailed_non_pixel *data; |
|
- | 886 | struct drm_display_mode *newmode; |
|
- | 887 | int edid_ext_num; |
|
- | 888 | int start_offset, end_offset; |
|
- | 889 | int timing_level; |
|
- | 890 | ||
- | 891 | if (edid->version == 1 && edid->revision < 3) { |
|
- | 892 | /* If the EDID version is less than 1.3, there is no |
|
- | 893 | * extension EDID. |
|
- | 894 | */ |
|
- | 895 | return 0; |
|
- | 896 | } |
|
- | 897 | if (!edid->extensions) { |
|
- | 898 | /* if there is no extension EDID, it is unnecessary to |
|
- | 899 | * parse the E-EDID to get detailed info |
|
- | 900 | */ |
|
- | 901 | return 0; |
|
- | 902 | } |
|
- | 903 | ||
- | 904 | /* Chose real EDID extension number */ |
|
- | 905 | edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? |
|
- | 906 | MAX_EDID_EXT_NUM : edid->extensions; |
|
- | 907 | ||
- | 908 | /* Find CEA extension */ |
|
- | 909 | for (i = 0; i < edid_ext_num; i++) { |
|
- | 910 | edid_ext = (char *)edid + EDID_LENGTH * (i + 1); |
|
- | 911 | /* This block is CEA extension */ |
|
- | 912 | if (edid_ext[0] == 0x02) |
|
- | 913 | break; |
|
- | 914 | } |
|
- | 915 | ||
- | 916 | if (i == edid_ext_num) { |
|
- | 917 | /* if there is no additional timing EDID block, return */ |
|
- | 918 | return 0; |
|
- | 919 | } |
|
- | 920 | ||
- | 921 | /* Get the start offset of detailed timing block */ |
|
- | 922 | start_offset = edid_ext[2]; |
|
- | 923 | if (start_offset == 0) { |
|
- | 924 | /* If the start_offset is zero, it means that neither detailed |
|
- | 925 | * info nor data block exist. In such case it is also |
|
- | 926 | * unnecessary to parse the detailed timing info. |
|
- | 927 | */ |
|
- | 928 | return 0; |
|
- | 929 | } |
|
- | 930 | ||
- | 931 | timing_level = standard_timing_level(edid); |
|
- | 932 | end_offset = EDID_LENGTH; |
|
- | 933 | end_offset -= sizeof(struct detailed_timing); |
|
- | 934 | for (i = start_offset; i < end_offset; |
|
- | 935 | i += sizeof(struct detailed_timing)) { |
|
- | 936 | timing = (struct detailed_timing *)(edid_ext + i); |
|
- | 937 | data = &timing->data.other_data; |
|
- | 938 | /* Detailed mode timing */ |
|
- | 939 | if (timing->pixel_clock) { |
|
- | 940 | newmode = drm_mode_detailed(dev, edid, timing, quirks); |
|
- | 941 | if (!newmode) |
|
523 | if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) |
942 | continue; |
524 | newmode->type |= DRM_MODE_TYPE_PREFERRED; |
943 | |
Line 525... | Line 944... | ||
525 | drm_mode_probed_add(connector, newmode); |
944 | drm_mode_probed_add(connector, newmode); |
526 | 945 | ||
Line 546... | Line 965... | ||
546 | for (j = 0; j < 5; i++) { |
965 | for (j = 0; j < 5; i++) { |
547 | struct std_timing *std; |
966 | struct std_timing *std; |
548 | struct drm_display_mode *newmode; |
967 | struct drm_display_mode *newmode; |
Line 549... | Line 968... | ||
549 | 968 | ||
550 | std = &data->data.timings[j]; |
969 | std = &data->data.timings[j]; |
551 | newmode = drm_mode_std(dev, std); |
970 | newmode = drm_mode_std(dev, std, timing_level); |
552 | if (newmode) { |
971 | if (newmode) { |
553 | drm_mode_probed_add(connector, newmode); |
972 | drm_mode_probed_add(connector, newmode); |
554 | modes++; |
973 | modes++; |
555 | } |
974 | } |
Line 606... | Line 1025... | ||
606 | { |
1025 | { |
607 | int ret; |
1026 | int ret; |
Line 608... | Line 1027... | ||
608 | 1027 | ||
609 | ret = drm_do_probe_ddc_edid(adapter, buf, len); |
1028 | ret = drm_do_probe_ddc_edid(adapter, buf, len); |
610 | if (ret != 0) { |
- | |
611 | // dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", |
- | |
612 | // drm_get_connector_name(connector)); |
1029 | if (ret != 0) { |
613 | goto end; |
1030 | goto end; |
614 | } |
1031 | } |
615 | if (!edid_is_valid((struct edid *)buf)) { |
1032 | if (!edid_is_valid((struct edid *)buf)) { |
616 | // dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", |
1033 | // dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", |
Line 619... | Line 1036... | ||
619 | } |
1036 | } |
620 | end: |
1037 | end: |
621 | return ret; |
1038 | return ret; |
622 | } |
1039 | } |
Line 623... | Line -... | ||
623 | - | ||
624 | #define MAX_EDID_EXT_NUM 4 |
1040 | |
625 | /** |
1041 | /** |
626 | * drm_get_edid - get EDID data, if available |
1042 | * drm_get_edid - get EDID data, if available |
627 | * @connector: connector we're probing |
1043 | * @connector: connector we're probing |
628 | * @adapter: i2c adapter to use for DDC |
1044 | * @adapter: i2c adapter to use for DDC |
Line 772... | Line 1188... | ||
772 | quirks = edid_get_quirks(edid); |
1188 | quirks = edid_get_quirks(edid); |
Line 773... | Line 1189... | ||
773 | 1189 | ||
774 | num_modes += add_established_modes(connector, edid); |
1190 | num_modes += add_established_modes(connector, edid); |
775 | num_modes += add_standard_modes(connector, edid); |
1191 | num_modes += add_standard_modes(connector, edid); |
- | 1192 | num_modes += add_detailed_info(connector, edid, quirks); |
|
Line 776... | Line 1193... | ||
776 | num_modes += add_detailed_info(connector, edid, quirks); |
1193 | num_modes += add_detailed_info_eedid(connector, edid, quirks); |
777 | 1194 | ||
Line 778... | Line 1195... | ||
778 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
1195 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
Line 797... | Line 1214... | ||
797 | connector->display_info.gamma = edid->gamma; |
1214 | connector->display_info.gamma = edid->gamma; |
Line 798... | Line 1215... | ||
798 | 1215 | ||
799 | return num_modes; |
1216 | return num_modes; |
800 | } |
1217 | } |
- | 1218 | EXPORT_SYMBOL(drm_add_edid_modes); |
|
- | 1219 | ||
- | 1220 | /** |
|
- | 1221 | * drm_add_modes_noedid - add modes for the connectors without EDID |
|
- | 1222 | * @connector: connector we're probing |
|
- | 1223 | * @hdisplay: the horizontal display limit |
|
- | 1224 | * @vdisplay: the vertical display limit |
|
- | 1225 | * |
|
- | 1226 | * Add the specified modes to the connector's mode list. Only when the |
|
- | 1227 | * hdisplay/vdisplay is not beyond the given limit, it will be added. |
|
- | 1228 | * |
|
- | 1229 | * Return number of modes added or 0 if we couldn't find any. |
|
- | 1230 | */ |
|
- | 1231 | int drm_add_modes_noedid(struct drm_connector *connector, |
|
- | 1232 | int hdisplay, int vdisplay) |
|
- | 1233 | { |
|
- | 1234 | int i, count, num_modes = 0; |
|
- | 1235 | struct drm_display_mode *mode, *ptr; |
|
- | 1236 | struct drm_device *dev = connector->dev; |
|
- | 1237 | ||
- | 1238 | count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); |
|
- | 1239 | if (hdisplay < 0) |
|
- | 1240 | hdisplay = 0; |
|
- | 1241 | if (vdisplay < 0) |
|
- | 1242 | vdisplay = 0; |
|
- | 1243 | ||
- | 1244 | for (i = 0; i < count; i++) { |
|
- | 1245 | ptr = &drm_dmt_modes[i]; |
|
- | 1246 | if (hdisplay && vdisplay) { |
|
- | 1247 | /* |
|
- | 1248 | * Only when two are valid, they will be used to check |
|
- | 1249 | * whether the mode should be added to the mode list of |
|
- | 1250 | * the connector. |
|
- | 1251 | */ |
|
- | 1252 | if (ptr->hdisplay > hdisplay || |
|
- | 1253 | ptr->vdisplay > vdisplay) |
|
- | 1254 | continue; |
|
- | 1255 | } |
|
- | 1256 | mode = drm_mode_duplicate(dev, ptr); |
|
- | 1257 | if (mode) { |
|
- | 1258 | drm_mode_probed_add(connector, mode); |
|
- | 1259 | num_modes++; |
|
- | 1260 | } |
|
- | 1261 | } |
|
- | 1262 | return num_modes; |
|
- | 1263 | } |