diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 19 |
2 files changed, 78 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index d5d2c03fd136..c214f1246cb4 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -2545,6 +2545,33 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode) | |||
2545 | return clock; | 2545 | return clock; |
2546 | } | 2546 | } |
2547 | 2547 | ||
2548 | static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match, | ||
2549 | unsigned int clock_tolerance) | ||
2550 | { | ||
2551 | u8 mode; | ||
2552 | |||
2553 | if (!to_match->clock) | ||
2554 | return 0; | ||
2555 | |||
2556 | for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { | ||
2557 | const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; | ||
2558 | unsigned int clock1, clock2; | ||
2559 | |||
2560 | /* Check both 60Hz and 59.94Hz */ | ||
2561 | clock1 = cea_mode->clock; | ||
2562 | clock2 = cea_mode_alternate_clock(cea_mode); | ||
2563 | |||
2564 | if (abs(to_match->clock - clock1) > clock_tolerance && | ||
2565 | abs(to_match->clock - clock2) > clock_tolerance) | ||
2566 | continue; | ||
2567 | |||
2568 | if (drm_mode_equal_no_clocks(to_match, cea_mode)) | ||
2569 | return mode + 1; | ||
2570 | } | ||
2571 | |||
2572 | return 0; | ||
2573 | } | ||
2574 | |||
2548 | /** | 2575 | /** |
2549 | * drm_match_cea_mode - look for a CEA mode matching given mode | 2576 | * drm_match_cea_mode - look for a CEA mode matching given mode |
2550 | * @to_match: display mode | 2577 | * @to_match: display mode |
@@ -2609,6 +2636,33 @@ hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode) | |||
2609 | return cea_mode_alternate_clock(hdmi_mode); | 2636 | return cea_mode_alternate_clock(hdmi_mode); |
2610 | } | 2637 | } |
2611 | 2638 | ||
2639 | static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match, | ||
2640 | unsigned int clock_tolerance) | ||
2641 | { | ||
2642 | u8 mode; | ||
2643 | |||
2644 | if (!to_match->clock) | ||
2645 | return 0; | ||
2646 | |||
2647 | for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { | ||
2648 | const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; | ||
2649 | unsigned int clock1, clock2; | ||
2650 | |||
2651 | /* Make sure to also match alternate clocks */ | ||
2652 | clock1 = hdmi_mode->clock; | ||
2653 | clock2 = hdmi_mode_alternate_clock(hdmi_mode); | ||
2654 | |||
2655 | if (abs(to_match->clock - clock1) > clock_tolerance && | ||
2656 | abs(to_match->clock - clock2) > clock_tolerance) | ||
2657 | continue; | ||
2658 | |||
2659 | if (drm_mode_equal_no_clocks(to_match, hdmi_mode)) | ||
2660 | return mode + 1; | ||
2661 | } | ||
2662 | |||
2663 | return 0; | ||
2664 | } | ||
2665 | |||
2612 | /* | 2666 | /* |
2613 | * drm_match_hdmi_mode - look for a HDMI mode matching given mode | 2667 | * drm_match_hdmi_mode - look for a HDMI mode matching given mode |
2614 | * @to_match: display mode | 2668 | * @to_match: display mode |
@@ -3119,14 +3173,18 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) | |||
3119 | u8 mode_idx; | 3173 | u8 mode_idx; |
3120 | const char *type; | 3174 | const char *type; |
3121 | 3175 | ||
3122 | mode_idx = drm_match_cea_mode(mode) - 1; | 3176 | /* |
3177 | * allow 5kHz clock difference either way to account for | ||
3178 | * the 10kHz clock resolution limit of detailed timings. | ||
3179 | */ | ||
3180 | mode_idx = drm_match_cea_mode_clock_tolerance(mode, 5) - 1; | ||
3123 | if (mode_idx < ARRAY_SIZE(edid_cea_modes)) { | 3181 | if (mode_idx < ARRAY_SIZE(edid_cea_modes)) { |
3124 | type = "CEA"; | 3182 | type = "CEA"; |
3125 | cea_mode = &edid_cea_modes[mode_idx]; | 3183 | cea_mode = &edid_cea_modes[mode_idx]; |
3126 | clock1 = cea_mode->clock; | 3184 | clock1 = cea_mode->clock; |
3127 | clock2 = cea_mode_alternate_clock(cea_mode); | 3185 | clock2 = cea_mode_alternate_clock(cea_mode); |
3128 | } else { | 3186 | } else { |
3129 | mode_idx = drm_match_hdmi_mode(mode) - 1; | 3187 | mode_idx = drm_match_hdmi_mode_clock_tolerance(mode, 5) - 1; |
3130 | if (mode_idx < ARRAY_SIZE(edid_4k_modes)) { | 3188 | if (mode_idx < ARRAY_SIZE(edid_4k_modes)) { |
3131 | type = "HDMI"; | 3189 | type = "HDMI"; |
3132 | cea_mode = &edid_4k_modes[mode_idx]; | 3190 | cea_mode = &edid_4k_modes[mode_idx]; |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index bde9b2911dc2..ef6bd3656548 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -917,13 +917,30 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ | |||
917 | } else if (mode1->clock != mode2->clock) | 917 | } else if (mode1->clock != mode2->clock) |
918 | return false; | 918 | return false; |
919 | 919 | ||
920 | return drm_mode_equal_no_clocks(mode1, mode2); | ||
921 | } | ||
922 | EXPORT_SYMBOL(drm_mode_equal); | ||
923 | |||
924 | /** | ||
925 | * drm_mode_equal_no_clocks - test modes for equality | ||
926 | * @mode1: first mode | ||
927 | * @mode2: second mode | ||
928 | * | ||
929 | * Check to see if @mode1 and @mode2 are equivalent, but | ||
930 | * don't check the pixel clocks. | ||
931 | * | ||
932 | * Returns: | ||
933 | * True if the modes are equal, false otherwise. | ||
934 | */ | ||
935 | bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) | ||
936 | { | ||
920 | if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != | 937 | if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != |
921 | (mode2->flags & DRM_MODE_FLAG_3D_MASK)) | 938 | (mode2->flags & DRM_MODE_FLAG_3D_MASK)) |
922 | return false; | 939 | return false; |
923 | 940 | ||
924 | return drm_mode_equal_no_clocks_no_stereo(mode1, mode2); | 941 | return drm_mode_equal_no_clocks_no_stereo(mode1, mode2); |
925 | } | 942 | } |
926 | EXPORT_SYMBOL(drm_mode_equal); | 943 | EXPORT_SYMBOL(drm_mode_equal_no_clocks); |
927 | 944 | ||
928 | /** | 945 | /** |
929 | * drm_mode_equal_no_clocks_no_stereo - test modes for equality | 946 | * drm_mode_equal_no_clocks_no_stereo - test modes for equality |