Rev 3746 | Rev 4104 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3746 | Rev 4075 | ||
---|---|---|---|
Line 966... | Line 966... | ||
966 | { |
966 | { |
967 | int i; |
967 | int i; |
968 | u8 csum = 0; |
968 | u8 csum = 0; |
969 | struct edid *edid = (struct edid *)raw_edid; |
969 | struct edid *edid = (struct edid *)raw_edid; |
Line -... | Line 970... | ||
- | 970 | ||
- | 971 | if (WARN_ON(!raw_edid)) |
|
- | 972 | return false; |
|
970 | 973 | ||
971 | if (edid_fixup > 8 || edid_fixup < 0) |
974 | if (edid_fixup > 8 || edid_fixup < 0) |
Line 972... | Line 975... | ||
972 | edid_fixup = 6; |
975 | edid_fixup = 6; |
973 | 976 | ||
Line 1008... | Line 1011... | ||
1008 | 1011 | ||
1009 | default: |
1012 | default: |
1010 | break; |
1013 | break; |
Line 1011... | Line 1014... | ||
1011 | } |
1014 | } |
Line 1012... | Line 1015... | ||
1012 | 1015 | ||
1013 | return 1; |
1016 | return true; |
1014 | 1017 | ||
1015 | bad: |
1018 | bad: |
1016 | if (raw_edid && print_bad_edid) { |
1019 | if (print_bad_edid) { |
1017 | printk(KERN_ERR "Raw EDID:\n"); |
1020 | printk(KERN_ERR "Raw EDID:\n"); |
1018 | print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, |
1021 | print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, |
1019 | raw_edid, EDID_LENGTH, false); |
1022 | raw_edid, EDID_LENGTH, false); |
1020 | } |
1023 | } |
Line 1021... | Line 1024... | ||
1021 | return 0; |
1024 | return false; |
1022 | } |
1025 | } |
Line 1704... | Line 1707... | ||
1704 | /* ignore tiny modes */ |
1707 | /* ignore tiny modes */ |
1705 | if (hactive < 64 || vactive < 64) |
1708 | if (hactive < 64 || vactive < 64) |
1706 | return NULL; |
1709 | return NULL; |
Line 1707... | Line 1710... | ||
1707 | 1710 | ||
1708 | if (pt->misc & DRM_EDID_PT_STEREO) { |
1711 | if (pt->misc & DRM_EDID_PT_STEREO) { |
1709 | printk(KERN_WARNING "stereo mode not supported\n"); |
1712 | DRM_DEBUG_KMS("stereo mode not supported\n"); |
1710 | return NULL; |
1713 | return NULL; |
1711 | } |
1714 | } |
1712 | if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { |
1715 | if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { |
1713 | printk(KERN_WARNING "composite sync not supported\n"); |
1716 | DRM_DEBUG_KMS("composite sync not supported\n"); |
Line 1714... | Line 1717... | ||
1714 | } |
1717 | } |
1715 | 1718 | ||
1716 | /* it is incorrect if hsync/vsync width is zero */ |
1719 | /* it is incorrect if hsync/vsync width is zero */ |
Line 2319... | Line 2322... | ||
2319 | 2322 | ||
2320 | return edid_ext; |
2323 | return edid_ext; |
2321 | } |
2324 | } |
Line -... | Line 2325... | ||
- | 2325 | EXPORT_SYMBOL(drm_find_cea_extension); |
|
- | 2326 | ||
- | 2327 | /* |
|
- | 2328 | * Calculate the alternate clock for the CEA mode |
|
- | 2329 | * (60Hz vs. 59.94Hz etc.) |
|
- | 2330 | */ |
|
- | 2331 | static unsigned int |
|
- | 2332 | cea_mode_alternate_clock(const struct drm_display_mode *cea_mode) |
|
- | 2333 | { |
|
- | 2334 | unsigned int clock = cea_mode->clock; |
|
- | 2335 | ||
- | 2336 | if (cea_mode->vrefresh % 6 != 0) |
|
- | 2337 | return clock; |
|
- | 2338 | ||
- | 2339 | /* |
|
- | 2340 | * edid_cea_modes contains the 59.94Hz |
|
- | 2341 | * variant for 240 and 480 line modes, |
|
- | 2342 | * and the 60Hz variant otherwise. |
|
- | 2343 | */ |
|
- | 2344 | if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480) |
|
- | 2345 | clock = clock * 1001 / 1000; |
|
- | 2346 | else |
|
- | 2347 | clock = DIV_ROUND_UP(clock * 1000, 1001); |
|
- | 2348 | ||
- | 2349 | return clock; |
|
2322 | EXPORT_SYMBOL(drm_find_cea_extension); |
2350 | } |
2323 | 2351 | ||
2324 | /** |
2352 | /** |
2325 | * drm_match_cea_mode - look for a CEA mode matching given mode |
2353 | * drm_match_cea_mode - look for a CEA mode matching given mode |
2326 | * @to_match: display mode |
2354 | * @to_match: display mode |
Line 2337... | Line 2365... | ||
2337 | 2365 | ||
2338 | for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { |
2366 | for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { |
2339 | const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; |
2367 | const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; |
Line 2340... | Line -... | ||
2340 | unsigned int clock1, clock2; |
- | |
2341 | - | ||
2342 | clock1 = clock2 = cea_mode->clock; |
2368 | unsigned int clock1, clock2; |
2343 | - | ||
2344 | /* Check both 60Hz and 59.94Hz */ |
- | |
2345 | if (cea_mode->vrefresh % 6 == 0) { |
- | |
2346 | /* |
- | |
2347 | * edid_cea_modes contains the 59.94Hz |
- | |
2348 | * variant for 240 and 480 line modes, |
- | |
2349 | * and the 60Hz variant otherwise. |
- | |
2350 | */ |
- | |
2351 | if (cea_mode->vdisplay == 240 || |
2369 | |
2352 | cea_mode->vdisplay == 480) |
- | |
2353 | clock1 = clock1 * 1001 / 1000; |
2370 | /* Check both 60Hz and 59.94Hz */ |
2354 | else |
- | |
Line 2355... | Line 2371... | ||
2355 | clock2 = DIV_ROUND_UP(clock2 * 1000, 1001); |
2371 | clock1 = cea_mode->clock; |
2356 | } |
2372 | clock2 = cea_mode_alternate_clock(cea_mode); |
2357 | 2373 | ||
2358 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || |
2374 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || |
2359 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && |
2375 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && |
2360 | drm_mode_equal_no_clocks(to_match, cea_mode)) |
2376 | drm_mode_equal_no_clocks(to_match, cea_mode)) |
2361 | return mode + 1; |
2377 | return mode + 1; |
2362 | } |
2378 | } |
Line -... | Line 2379... | ||
- | 2379 | return 0; |
|
- | 2380 | } |
|
- | 2381 | EXPORT_SYMBOL(drm_match_cea_mode); |
|
- | 2382 | ||
- | 2383 | static int |
|
- | 2384 | add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) |
|
- | 2385 | { |
|
- | 2386 | struct drm_device *dev = connector->dev; |
|
- | 2387 | struct drm_display_mode *mode, *tmp; |
|
- | 2388 | LIST_HEAD(list); |
|
- | 2389 | int modes = 0; |
|
- | 2390 | ||
- | 2391 | /* Don't add CEA modes if the CEA extension block is missing */ |
|
- | 2392 | if (!drm_find_cea_extension(edid)) |
|
- | 2393 | return 0; |
|
- | 2394 | ||
- | 2395 | /* |
|
- | 2396 | * Go through all probed modes and create a new mode |
|
- | 2397 | * with the alternate clock for certain CEA modes. |
|
- | 2398 | */ |
|
- | 2399 | list_for_each_entry(mode, &connector->probed_modes, head) { |
|
- | 2400 | const struct drm_display_mode *cea_mode; |
|
- | 2401 | struct drm_display_mode *newmode; |
|
- | 2402 | u8 cea_mode_idx = drm_match_cea_mode(mode) - 1; |
|
- | 2403 | unsigned int clock1, clock2; |
|
- | 2404 | ||
- | 2405 | if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes)) |
|
- | 2406 | continue; |
|
- | 2407 | ||
- | 2408 | cea_mode = &edid_cea_modes[cea_mode_idx]; |
|
- | 2409 | ||
- | 2410 | clock1 = cea_mode->clock; |
|
- | 2411 | clock2 = cea_mode_alternate_clock(cea_mode); |
|
- | 2412 | ||
- | 2413 | if (clock1 == clock2) |
|
- | 2414 | continue; |
|
- | 2415 | ||
- | 2416 | if (mode->clock != clock1 && mode->clock != clock2) |
|
- | 2417 | continue; |
|
- | 2418 | ||
- | 2419 | newmode = drm_mode_duplicate(dev, cea_mode); |
|
- | 2420 | if (!newmode) |
|
- | 2421 | continue; |
|
- | 2422 | ||
- | 2423 | /* |
|
- | 2424 | * The current mode could be either variant. Make |
|
- | 2425 | * sure to pick the "other" clock for the new mode. |
|
- | 2426 | */ |
|
- | 2427 | if (mode->clock != clock1) |
|
- | 2428 | newmode->clock = clock1; |
|
- | 2429 | else |
|
- | 2430 | newmode->clock = clock2; |
|
- | 2431 | ||
- | 2432 | list_add_tail(&newmode->head, &list); |
|
- | 2433 | } |
|
- | 2434 | ||
- | 2435 | list_for_each_entry_safe(mode, tmp, &list, head) { |
|
- | 2436 | list_del(&mode->head); |
|
- | 2437 | drm_mode_probed_add(connector, mode); |
|
- | 2438 | modes++; |
|
Line 2363... | Line 2439... | ||
2363 | return 0; |
2439 | } |
2364 | } |
2440 | |
2365 | EXPORT_SYMBOL(drm_match_cea_mode); |
2441 | return modes; |
2366 | 2442 | } |
|
Line 2944... | Line 3020... | ||
2944 | num_modes += add_standard_modes(connector, edid); |
3020 | num_modes += add_standard_modes(connector, edid); |
2945 | num_modes += add_established_modes(connector, edid); |
3021 | num_modes += add_established_modes(connector, edid); |
2946 | if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) |
3022 | if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) |
2947 | num_modes += add_inferred_modes(connector, edid); |
3023 | num_modes += add_inferred_modes(connector, edid); |
2948 | num_modes += add_cea_modes(connector, edid); |
3024 | num_modes += add_cea_modes(connector, edid); |
- | 3025 | num_modes += add_alternate_cea_modes(connector, edid); |
|
Line 2949... | Line 3026... | ||
2949 | 3026 | ||
2950 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
3027 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
Line 2951... | Line 3028... | ||
2951 | edid_fixup_preferred(connector, quirks); |
3028 | edid_fixup_preferred(connector, quirks); |