forked from Minki/linux
drm/edid: Consider alternate cea timings to be the same VIC
CEA-861 specifies that the vertical front porch may vary by one or two lines for specific VICs. Up to now we've only considered a mode to match the VIC if it matched the shortest possible vertical front porch length (as that is the variant we store in cea_modes[]). Let's allow our VIC matching to work with the other timings variants as well so that that we'll send out the correct VIC if the variant actually used isn't the one with the shortest vertical front porch. Cc: Shashank Sharma <shashank.sharma@intel.com> Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Adam Jackson <ajax@redhat.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1478177609-16762-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
This commit is contained in:
parent
79b9555233
commit
c45a4e4657
@ -2613,6 +2613,41 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
|
||||
return clock;
|
||||
}
|
||||
|
||||
static bool
|
||||
cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
|
||||
{
|
||||
/*
|
||||
* For certain VICs the spec allows the vertical
|
||||
* front porch to vary by one or two lines.
|
||||
*
|
||||
* cea_modes[] stores the variant with the shortest
|
||||
* vertical front porch. We can adjust the mode to
|
||||
* get the other variants by simply increasing the
|
||||
* vertical front porch length.
|
||||
*/
|
||||
BUILD_BUG_ON(edid_cea_modes[8].vtotal != 262 ||
|
||||
edid_cea_modes[9].vtotal != 262 ||
|
||||
edid_cea_modes[12].vtotal != 262 ||
|
||||
edid_cea_modes[13].vtotal != 262 ||
|
||||
edid_cea_modes[23].vtotal != 312 ||
|
||||
edid_cea_modes[24].vtotal != 312 ||
|
||||
edid_cea_modes[27].vtotal != 312 ||
|
||||
edid_cea_modes[28].vtotal != 312);
|
||||
|
||||
if (((vic == 8 || vic == 9 ||
|
||||
vic == 12 || vic == 13) && mode->vtotal < 263) ||
|
||||
((vic == 23 || vic == 24 ||
|
||||
vic == 27 || vic == 28) && mode->vtotal < 314)) {
|
||||
mode->vsync_start++;
|
||||
mode->vsync_end++;
|
||||
mode->vtotal++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
|
||||
unsigned int clock_tolerance)
|
||||
{
|
||||
@ -2622,19 +2657,21 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m
|
||||
return 0;
|
||||
|
||||
for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
|
||||
const struct drm_display_mode *cea_mode = &edid_cea_modes[vic];
|
||||
struct drm_display_mode cea_mode = edid_cea_modes[vic];
|
||||
unsigned int clock1, clock2;
|
||||
|
||||
/* Check both 60Hz and 59.94Hz */
|
||||
clock1 = cea_mode->clock;
|
||||
clock2 = cea_mode_alternate_clock(cea_mode);
|
||||
clock1 = cea_mode.clock;
|
||||
clock2 = cea_mode_alternate_clock(&cea_mode);
|
||||
|
||||
if (abs(to_match->clock - clock1) > clock_tolerance &&
|
||||
abs(to_match->clock - clock2) > clock_tolerance)
|
||||
continue;
|
||||
|
||||
if (drm_mode_equal_no_clocks(to_match, cea_mode))
|
||||
return vic;
|
||||
do {
|
||||
if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode))
|
||||
return vic;
|
||||
} while (cea_mode_alternate_timings(vic, &cea_mode));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2655,18 +2692,23 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
|
||||
return 0;
|
||||
|
||||
for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
|
||||
const struct drm_display_mode *cea_mode = &edid_cea_modes[vic];
|
||||
struct drm_display_mode cea_mode = edid_cea_modes[vic];
|
||||
unsigned int clock1, clock2;
|
||||
|
||||
/* Check both 60Hz and 59.94Hz */
|
||||
clock1 = cea_mode->clock;
|
||||
clock2 = cea_mode_alternate_clock(cea_mode);
|
||||
clock1 = cea_mode.clock;
|
||||
clock2 = cea_mode_alternate_clock(&cea_mode);
|
||||
|
||||
if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
|
||||
KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
|
||||
drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode))
|
||||
return vic;
|
||||
if (KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock1) &&
|
||||
KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock2))
|
||||
continue;
|
||||
|
||||
do {
|
||||
if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode))
|
||||
return vic;
|
||||
} while (cea_mode_alternate_timings(vic, &cea_mode));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_match_cea_mode);
|
||||
|
Loading…
Reference in New Issue
Block a user