Rev 4075 | Rev 4539 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4075 | Rev 4104 | ||
---|---|---|---|
Line 123... | Line 123... | ||
123 | { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, |
123 | { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, |
124 | { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, |
124 | { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, |
Line 125... | Line 125... | ||
125 | 125 | ||
126 | /* ViewSonic VA2026w */ |
126 | /* ViewSonic VA2026w */ |
- | 127 | { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, |
|
- | 128 | ||
- | 129 | /* Medion MD 30217 PG */ |
|
127 | { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, |
130 | { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, |
Line 128... | Line 131... | ||
128 | }; |
131 | }; |
129 | 132 | ||
130 | /* |
133 | /* |
Line 929... | Line 932... | ||
929 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
932 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
930 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), |
933 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), |
931 | .vrefresh = 100, }, |
934 | .vrefresh = 100, }, |
932 | }; |
935 | }; |
Line -... | Line 936... | ||
- | 936 | ||
- | 937 | /* |
|
- | 938 | * HDMI 1.4 4k modes. |
|
- | 939 | */ |
|
- | 940 | static const struct drm_display_mode edid_4k_modes[] = { |
|
- | 941 | /* 1 - 3840x2160@30Hz */ |
|
- | 942 | { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, |
|
- | 943 | 3840, 4016, 4104, 4400, 0, |
|
- | 944 | 2160, 2168, 2178, 2250, 0, |
|
- | 945 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), |
|
- | 946 | .vrefresh = 30, }, |
|
- | 947 | /* 2 - 3840x2160@25Hz */ |
|
- | 948 | { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, |
|
- | 949 | 3840, 4896, 4984, 5280, 0, |
|
- | 950 | 2160, 2168, 2178, 2250, 0, |
|
- | 951 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), |
|
- | 952 | .vrefresh = 25, }, |
|
- | 953 | /* 3 - 3840x2160@24Hz */ |
|
- | 954 | { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, |
|
- | 955 | 3840, 5116, 5204, 5500, 0, |
|
- | 956 | 2160, 2168, 2178, 2250, 0, |
|
- | 957 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), |
|
- | 958 | .vrefresh = 24, }, |
|
- | 959 | /* 4 - 4096x2160@24Hz (SMPTE) */ |
|
- | 960 | { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, |
|
- | 961 | 4096, 5116, 5204, 5500, 0, |
|
- | 962 | 2160, 2168, 2178, 2250, 0, |
|
- | 963 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), |
|
- | 964 | .vrefresh = 24, }, |
|
- | 965 | }; |
|
933 | 966 | ||
Line 934... | Line 967... | ||
934 | /*** DDC fetch and block validation ***/ |
967 | /*** DDC fetch and block validation ***/ |
935 | 968 | ||
936 | static const u8 edid_header[] = { |
969 | static const u8 edid_header[] = { |
Line 2285... | Line 2318... | ||
2285 | drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure); |
2318 | drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure); |
Line 2286... | Line 2319... | ||
2286 | 2319 | ||
2287 | return closure.modes; |
2320 | return closure.modes; |
Line 2288... | Line -... | ||
2288 | } |
- | |
2289 | 2321 | } |
|
2290 | #define HDMI_IDENTIFIER 0x000C03 |
2322 | |
2291 | #define AUDIO_BLOCK 0x01 |
2323 | #define AUDIO_BLOCK 0x01 |
2292 | #define VIDEO_BLOCK 0x02 |
2324 | #define VIDEO_BLOCK 0x02 |
2293 | #define VENDOR_BLOCK 0x03 |
2325 | #define VENDOR_BLOCK 0x03 |
2294 | #define SPEAKER_BLOCK 0x04 |
2326 | #define SPEAKER_BLOCK 0x04 |
2295 | #define VIDEO_CAPABILITY_BLOCK 0x07 |
2327 | #define VIDEO_CAPABILITY_BLOCK 0x07 |
2296 | #define EDID_BASIC_AUDIO (1 << 6) |
2328 | #define EDID_BASIC_AUDIO (1 << 6) |
2297 | #define EDID_CEA_YCRCB444 (1 << 5) |
2329 | #define EDID_CEA_YCRCB444 (1 << 5) |
Line 2298... | Line 2330... | ||
2298 | #define EDID_CEA_YCRCB422 (1 << 4) |
2330 | #define EDID_CEA_YCRCB422 (1 << 4) |
2299 | #define EDID_CEA_VCDB_QS (1 << 6) |
2331 | #define EDID_CEA_VCDB_QS (1 << 6) |
2300 | 2332 | ||
2301 | /** |
2333 | /* |
2302 | * Search EDID for CEA extension block. |
2334 | * Search EDID for CEA extension block. |
2303 | */ |
2335 | */ |
2304 | u8 *drm_find_cea_extension(struct edid *edid) |
2336 | static u8 *drm_find_cea_extension(struct edid *edid) |
Line 2305... | Line 2337... | ||
2305 | { |
2337 | { |
Line 2320... | Line 2352... | ||
2320 | if (i == edid->extensions) |
2352 | if (i == edid->extensions) |
2321 | return NULL; |
2353 | return NULL; |
Line 2322... | Line 2354... | ||
2322 | 2354 | ||
2323 | return edid_ext; |
2355 | return edid_ext; |
2324 | } |
- | |
Line 2325... | Line 2356... | ||
2325 | EXPORT_SYMBOL(drm_find_cea_extension); |
2356 | } |
2326 | 2357 | ||
2327 | /* |
2358 | /* |
2328 | * Calculate the alternate clock for the CEA mode |
2359 | * Calculate the alternate clock for the CEA mode |
Line 2378... | Line 2409... | ||
2378 | } |
2409 | } |
2379 | return 0; |
2410 | return 0; |
2380 | } |
2411 | } |
2381 | EXPORT_SYMBOL(drm_match_cea_mode); |
2412 | EXPORT_SYMBOL(drm_match_cea_mode); |
Line -... | Line 2413... | ||
- | 2413 | ||
- | 2414 | /* |
|
- | 2415 | * Calculate the alternate clock for HDMI modes (those from the HDMI vendor |
|
- | 2416 | * specific block). |
|
- | 2417 | * |
|
- | 2418 | * It's almost like cea_mode_alternate_clock(), we just need to add an |
|
- | 2419 | * exception for the VIC 4 mode (4096x2160@24Hz): no alternate clock for this |
|
- | 2420 | * one. |
|
- | 2421 | */ |
|
- | 2422 | static unsigned int |
|
- | 2423 | hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode) |
|
- | 2424 | { |
|
- | 2425 | if (hdmi_mode->vdisplay == 4096 && hdmi_mode->hdisplay == 2160) |
|
- | 2426 | return hdmi_mode->clock; |
|
- | 2427 | ||
- | 2428 | return cea_mode_alternate_clock(hdmi_mode); |
|
- | 2429 | } |
|
- | 2430 | ||
- | 2431 | /* |
|
- | 2432 | * drm_match_hdmi_mode - look for a HDMI mode matching given mode |
|
- | 2433 | * @to_match: display mode |
|
- | 2434 | * |
|
- | 2435 | * An HDMI mode is one defined in the HDMI vendor specific block. |
|
- | 2436 | * |
|
- | 2437 | * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one. |
|
- | 2438 | */ |
|
- | 2439 | static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) |
|
- | 2440 | { |
|
- | 2441 | u8 mode; |
|
- | 2442 | ||
- | 2443 | if (!to_match->clock) |
|
- | 2444 | return 0; |
|
- | 2445 | ||
- | 2446 | for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { |
|
- | 2447 | const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; |
|
- | 2448 | unsigned int clock1, clock2; |
|
- | 2449 | ||
- | 2450 | /* Make sure to also match alternate clocks */ |
|
- | 2451 | clock1 = hdmi_mode->clock; |
|
- | 2452 | clock2 = hdmi_mode_alternate_clock(hdmi_mode); |
|
- | 2453 | ||
- | 2454 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || |
|
- | 2455 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && |
|
- | 2456 | drm_mode_equal_no_clocks(to_match, hdmi_mode)) |
|
- | 2457 | return mode + 1; |
|
- | 2458 | } |
|
- | 2459 | return 0; |
|
- | 2460 | } |
|
2382 | 2461 | ||
2383 | static int |
2462 | static int |
2384 | add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) |
2463 | add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) |
2385 | { |
2464 | { |
2386 | struct drm_device *dev = connector->dev; |
2465 | struct drm_device *dev = connector->dev; |
Line 2395... | Line 2474... | ||
2395 | /* |
2474 | /* |
2396 | * Go through all probed modes and create a new mode |
2475 | * Go through all probed modes and create a new mode |
2397 | * with the alternate clock for certain CEA modes. |
2476 | * with the alternate clock for certain CEA modes. |
2398 | */ |
2477 | */ |
2399 | list_for_each_entry(mode, &connector->probed_modes, head) { |
2478 | list_for_each_entry(mode, &connector->probed_modes, head) { |
2400 | const struct drm_display_mode *cea_mode; |
2479 | const struct drm_display_mode *cea_mode = NULL; |
2401 | struct drm_display_mode *newmode; |
2480 | struct drm_display_mode *newmode; |
2402 | u8 cea_mode_idx = drm_match_cea_mode(mode) - 1; |
2481 | u8 mode_idx = drm_match_cea_mode(mode) - 1; |
2403 | unsigned int clock1, clock2; |
2482 | unsigned int clock1, clock2; |
Line 2404... | Line 2483... | ||
2404 | 2483 | ||
- | 2484 | if (mode_idx < ARRAY_SIZE(edid_cea_modes)) { |
|
- | 2485 | cea_mode = &edid_cea_modes[mode_idx]; |
|
2405 | if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes)) |
2486 | clock2 = cea_mode_alternate_clock(cea_mode); |
- | 2487 | } else { |
|
- | 2488 | mode_idx = drm_match_hdmi_mode(mode) - 1; |
|
- | 2489 | if (mode_idx < ARRAY_SIZE(edid_4k_modes)) { |
|
- | 2490 | cea_mode = &edid_4k_modes[mode_idx]; |
|
- | 2491 | clock2 = hdmi_mode_alternate_clock(cea_mode); |
|
- | 2492 | } |
|
Line 2406... | Line 2493... | ||
2406 | continue; |
2493 | } |
- | 2494 | ||
Line 2407... | Line 2495... | ||
2407 | 2495 | if (!cea_mode) |
|
2408 | cea_mode = &edid_cea_modes[cea_mode_idx]; |
- | |
Line 2409... | Line 2496... | ||
2409 | 2496 | continue; |
|
2410 | clock1 = cea_mode->clock; |
2497 | |
Line 2411... | Line 2498... | ||
2411 | clock2 = cea_mode_alternate_clock(cea_mode); |
2498 | clock1 = cea_mode->clock; |
Line 2440... | Line 2527... | ||
2440 | 2527 | ||
2441 | return modes; |
2528 | return modes; |
Line 2442... | Line 2529... | ||
2442 | } |
2529 | } |
2443 | 2530 | ||
2444 | static int |
2531 | static int |
2445 | do_cea_modes (struct drm_connector *connector, u8 *db, u8 len) |
2532 | do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) |
- | 2533 | { |
|
2446 | { |
2534 | struct drm_device *dev = connector->dev; |
2447 | struct drm_device *dev = connector->dev; |
2535 | const u8 *mode; |
Line 2448... | Line 2536... | ||
2448 | u8 * mode, cea_mode; |
2536 | u8 cea_mode; |
2449 | int modes = 0; |
2537 | int modes = 0; |
2450 | 2538 | ||
Line 2463... | Line 2551... | ||
2463 | } |
2551 | } |
Line 2464... | Line 2552... | ||
2464 | 2552 | ||
2465 | return modes; |
2553 | return modes; |
Line -... | Line 2554... | ||
- | 2554 | } |
|
- | 2555 | ||
- | 2556 | /* |
|
- | 2557 | * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block |
|
- | 2558 | * @connector: connector corresponding to the HDMI sink |
|
- | 2559 | * @db: start of the CEA vendor specific block |
|
- | 2560 | * @len: length of the CEA block payload, ie. one can access up to db[len] |
|
- | 2561 | * |
|
- | 2562 | * Parses the HDMI VSDB looking for modes to add to @connector. |
|
- | 2563 | */ |
|
- | 2564 | static int |
|
- | 2565 | do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len) |
|
- | 2566 | { |
|
- | 2567 | struct drm_device *dev = connector->dev; |
|
- | 2568 | int modes = 0, offset = 0, i; |
|
- | 2569 | u8 vic_len; |
|
- | 2570 | ||
- | 2571 | if (len < 8) |
|
- | 2572 | goto out; |
|
- | 2573 | ||
- | 2574 | /* no HDMI_Video_Present */ |
|
- | 2575 | if (!(db[8] & (1 << 5))) |
|
- | 2576 | goto out; |
|
- | 2577 | ||
- | 2578 | /* Latency_Fields_Present */ |
|
- | 2579 | if (db[8] & (1 << 7)) |
|
- | 2580 | offset += 2; |
|
- | 2581 | ||
- | 2582 | /* I_Latency_Fields_Present */ |
|
- | 2583 | if (db[8] & (1 << 6)) |
|
- | 2584 | offset += 2; |
|
- | 2585 | ||
- | 2586 | /* the declared length is not long enough for the 2 first bytes |
|
- | 2587 | * of additional video format capabilities */ |
|
- | 2588 | offset += 2; |
|
- | 2589 | if (len < (8 + offset)) |
|
- | 2590 | goto out; |
|
- | 2591 | ||
- | 2592 | vic_len = db[8 + offset] >> 5; |
|
- | 2593 | ||
- | 2594 | for (i = 0; i < vic_len && len >= (9 + offset + i); i++) { |
|
- | 2595 | struct drm_display_mode *newmode; |
|
- | 2596 | u8 vic; |
|
- | 2597 | ||
- | 2598 | vic = db[9 + offset + i]; |
|
- | 2599 | ||
- | 2600 | vic--; /* VICs start at 1 */ |
|
- | 2601 | if (vic >= ARRAY_SIZE(edid_4k_modes)) { |
|
- | 2602 | DRM_ERROR("Unknown HDMI VIC: %d\n", vic); |
|
- | 2603 | continue; |
|
- | 2604 | } |
|
- | 2605 | ||
- | 2606 | newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]); |
|
- | 2607 | if (!newmode) |
|
- | 2608 | continue; |
|
- | 2609 | ||
- | 2610 | drm_mode_probed_add(connector, newmode); |
|
- | 2611 | modes++; |
|
- | 2612 | } |
|
- | 2613 | ||
- | 2614 | out: |
|
- | 2615 | return modes; |
|
2466 | } |
2616 | } |
2467 | 2617 | ||
2468 | static int |
2618 | static int |
2469 | cea_db_payload_len(const u8 *db) |
2619 | cea_db_payload_len(const u8 *db) |
2470 | { |
2620 | { |
Line 2494... | Line 2644... | ||
2494 | if (*end < 4 || *end > 127) |
2644 | if (*end < 4 || *end > 127) |
2495 | return -ERANGE; |
2645 | return -ERANGE; |
2496 | return 0; |
2646 | return 0; |
2497 | } |
2647 | } |
Line -... | Line 2648... | ||
- | 2648 | ||
- | 2649 | static bool cea_db_is_hdmi_vsdb(const u8 *db) |
|
- | 2650 | { |
|
- | 2651 | int hdmi_id; |
|
- | 2652 | ||
- | 2653 | if (cea_db_tag(db) != VENDOR_BLOCK) |
|
- | 2654 | return false; |
|
- | 2655 | ||
- | 2656 | if (cea_db_payload_len(db) < 5) |
|
- | 2657 | return false; |
|
- | 2658 | ||
- | 2659 | hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); |
|
- | 2660 | ||
- | 2661 | return hdmi_id == HDMI_IEEE_OUI; |
|
- | 2662 | } |
|
2498 | 2663 | ||
2499 | #define for_each_cea_db(cea, i, start, end) \ |
2664 | #define for_each_cea_db(cea, i, start, end) \ |
Line 2500... | Line 2665... | ||
2500 | for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1) |
2665 | for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1) |
2501 | 2666 | ||
2502 | static int |
2667 | static int |
2503 | add_cea_modes(struct drm_connector *connector, struct edid *edid) |
2668 | add_cea_modes(struct drm_connector *connector, struct edid *edid) |
- | 2669 | { |
|
2504 | { |
2670 | const u8 *cea = drm_find_cea_extension(edid); |
2505 | u8 * cea = drm_find_cea_extension(edid); |
2671 | const u8 *db; |
Line 2506... | Line 2672... | ||
2506 | u8 * db, dbl; |
2672 | u8 dbl; |
2507 | int modes = 0; |
2673 | int modes = 0; |
Line 2516... | Line 2682... | ||
2516 | db = &cea[i]; |
2682 | db = &cea[i]; |
2517 | dbl = cea_db_payload_len(db); |
2683 | dbl = cea_db_payload_len(db); |
Line 2518... | Line 2684... | ||
2518 | 2684 | ||
2519 | if (cea_db_tag(db) == VIDEO_BLOCK) |
2685 | if (cea_db_tag(db) == VIDEO_BLOCK) |
- | 2686 | modes += do_cea_modes (connector, db+1, dbl); |
|
- | 2687 | else if (cea_db_is_hdmi_vsdb(db)) |
|
2520 | modes += do_cea_modes (connector, db+1, dbl); |
2688 | modes += do_hdmi_vsdb_modes(connector, db, dbl); |
2521 | } |
2689 | } |
Line 2522... | Line 2690... | ||
2522 | } |
2690 | } |
2523 | 2691 | ||
Line 2568... | Line 2736... | ||
2568 | { |
2736 | { |
2569 | if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME) |
2737 | if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME) |
2570 | *(u8 **)data = t->data.other_data.data.str.str; |
2738 | *(u8 **)data = t->data.other_data.data.str.str; |
2571 | } |
2739 | } |
Line 2572... | Line -... | ||
2572 | - | ||
2573 | static bool cea_db_is_hdmi_vsdb(const u8 *db) |
- | |
2574 | { |
- | |
2575 | int hdmi_id; |
- | |
2576 | - | ||
2577 | if (cea_db_tag(db) != VENDOR_BLOCK) |
- | |
2578 | return false; |
- | |
2579 | - | ||
2580 | if (cea_db_payload_len(db) < 5) |
- | |
2581 | return false; |
- | |
2582 | - | ||
2583 | hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); |
- | |
2584 | - | ||
2585 | return hdmi_id == HDMI_IDENTIFIER; |
- | |
2586 | } |
- | |
2587 | 2740 | ||
2588 | /** |
2741 | /** |
2589 | * drm_edid_to_eld - build ELD from EDID |
2742 | * drm_edid_to_eld - build ELD from EDID |
2590 | * @connector: connector corresponding to the HDMI/DP sink |
2743 | * @connector: connector corresponding to the HDMI/DP sink |
2591 | * @edid: EDID to parse |
2744 | * @edid: EDID to parse |
Line 2730... | Line 2883... | ||
2730 | return count; |
2883 | return count; |
2731 | } |
2884 | } |
2732 | EXPORT_SYMBOL(drm_edid_to_sad); |
2885 | EXPORT_SYMBOL(drm_edid_to_sad); |
Line 2733... | Line 2886... | ||
2733 | 2886 | ||
- | 2887 | /** |
|
- | 2888 | * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID |
|
- | 2889 | * @edid: EDID to parse |
|
- | 2890 | * @sadb: pointer to the speaker block |
|
- | 2891 | * |
|
- | 2892 | * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it. |
|
- | 2893 | * Note: returned pointer needs to be kfreed |
|
- | 2894 | * |
|
- | 2895 | * Return number of found Speaker Allocation Blocks or negative number on error. |
|
- | 2896 | */ |
|
- | 2897 | int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) |
|
- | 2898 | { |
|
- | 2899 | int count = 0; |
|
- | 2900 | int i, start, end, dbl; |
|
- | 2901 | const u8 *cea; |
|
- | 2902 | ||
- | 2903 | cea = drm_find_cea_extension(edid); |
|
- | 2904 | if (!cea) { |
|
- | 2905 | DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); |
|
- | 2906 | return -ENOENT; |
|
- | 2907 | } |
|
- | 2908 | ||
- | 2909 | if (cea_revision(cea) < 3) { |
|
- | 2910 | DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); |
|
- | 2911 | return -ENOTSUPP; |
|
- | 2912 | } |
|
- | 2913 | ||
- | 2914 | if (cea_db_offsets(cea, &start, &end)) { |
|
- | 2915 | DRM_DEBUG_KMS("SAD: invalid data block offsets\n"); |
|
- | 2916 | return -EPROTO; |
|
- | 2917 | } |
|
- | 2918 | ||
- | 2919 | for_each_cea_db(cea, i, start, end) { |
|
- | 2920 | const u8 *db = &cea[i]; |
|
- | 2921 | ||
- | 2922 | if (cea_db_tag(db) == SPEAKER_BLOCK) { |
|
- | 2923 | dbl = cea_db_payload_len(db); |
|
- | 2924 | ||
- | 2925 | /* Speaker Allocation Data Block */ |
|
- | 2926 | if (dbl == 3) { |
|
- | 2927 | *sadb = kmalloc(dbl, GFP_KERNEL); |
|
- | 2928 | if (!*sadb) |
|
- | 2929 | return -ENOMEM; |
|
- | 2930 | memcpy(*sadb, &db[1], dbl); |
|
- | 2931 | count = dbl; |
|
- | 2932 | break; |
|
- | 2933 | } |
|
- | 2934 | } |
|
- | 2935 | } |
|
- | 2936 | ||
- | 2937 | return count; |
|
- | 2938 | } |
|
- | 2939 | EXPORT_SYMBOL(drm_edid_to_speaker_allocation); |
|
- | 2940 | ||
2734 | /** |
2941 | /** |
2735 | * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond |
2942 | * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond |
2736 | * @connector: connector associated with the HDMI/DP sink |
2943 | * @connector: connector associated with the HDMI/DP sink |
2737 | * @mode: the display mode |
2944 | * @mode: the display mode |
2738 | */ |
2945 | */ |
Line 3100... | Line 3307... | ||
3100 | 3307 | ||
3101 | err = hdmi_avi_infoframe_init(frame); |
3308 | err = hdmi_avi_infoframe_init(frame); |
3102 | if (err < 0) |
3309 | if (err < 0) |
Line -... | Line 3310... | ||
- | 3310 | return err; |
|
- | 3311 | ||
- | 3312 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) |
|
3103 | return err; |
3313 | frame->pixel_repeat = 1; |
3104 | - | ||
3105 | frame->video_code = drm_match_cea_mode(mode); |
- | |
Line 3106... | Line 3314... | ||
3106 | if (!frame->video_code) |
3314 | |
3107 | return 0; |
3315 | frame->video_code = drm_match_cea_mode(mode); |
Line 3108... | Line 3316... | ||
3108 | 3316 | ||
3109 | frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; |
3317 | frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; |
3110 | frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; |
3318 | frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; |
- | 3319 | ||
- | 3320 | return 0; |
|
- | 3321 | } |
|
- | 3322 | EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode); |
|
- | 3323 | ||
- | 3324 | /** |
|
- | 3325 | * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with |
|
- | 3326 | * data from a DRM display mode |
|
- | 3327 | * @frame: HDMI vendor infoframe |
|
- | 3328 | * @mode: DRM display mode |
|
- | 3329 | * |
|
- | 3330 | * Note that there's is a need to send HDMI vendor infoframes only when using a |
|
- | 3331 | * 4k or stereoscopic 3D mode. So when giving any other mode as input this |
|
- | 3332 | * function will return -EINVAL, error that can be safely ignored. |
|
- | 3333 | * |
|
- | 3334 | * Returns 0 on success or a negative error code on failure. |
|
- | 3335 | */ |
|
- | 3336 | int |
|
- | 3337 | drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, |
|
- | 3338 | const struct drm_display_mode *mode) |
|
- | 3339 | { |
|
- | 3340 | int err; |
|
- | 3341 | u8 vic; |
|
- | 3342 | ||
- | 3343 | if (!frame || !mode) |
|
- | 3344 | return -EINVAL; |
|
- | 3345 | ||
- | 3346 | vic = drm_match_hdmi_mode(mode); |
|
- | 3347 | if (!vic) |
|
- | 3348 | return -EINVAL; |
|
- | 3349 | ||
- | 3350 | err = hdmi_vendor_infoframe_init(frame); |
|
- | 3351 | if (err < 0) |
|
- | 3352 | return err; |
|
- | 3353 | ||
- | 3354 | frame->vic = vic; |