diff options
author | Dave Airlie <airlied@redhat.com> | 2016-11-30 14:28:20 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-11-30 14:28:20 +1000 |
commit | a90f58311f48f510ea63cd2db2e32f74712c43f3 (patch) | |
tree | a7d64dfe8066585e23ffe88e30ea2ac59eb5322e /drivers/gpu/drm/drm_edid.c | |
parent | 35838b470ab592071087a46804d373c5571dc032 (diff) | |
parent | 389f78b361fcdc52a9dbb5382c3922d80b52ed9f (diff) |
Merge tag 'drm-misc-next-2016-11-29' of git://anongit.freedesktop.org/git/drm-misc into drm-next
Big thing is that drm-misc is now officially a group maintainer/committer
model thing, with MAINTAINERS suitably updated. Otherwise just the usual
pile of misc things all over, nothing that stands out this time around.
* tag 'drm-misc-next-2016-11-29' of git://anongit.freedesktop.org/git/drm-misc: (33 commits)
drm: Introduce drm_framebuffer_assign()
drm/bridge: adv7511: Enable the audio data and clock pads on adv7533
drm/bridge: adv7511: Add Audio support
drm/edid: Consider alternate cea timings to be the same VIC
drm/atomic: Constify drm_atomic_crtc_needs_modeset()
drm: bridge: dw-hdmi: add ASoC dependency
drm: Fix shift operations for drm_fb_helper::drm_target_preferred()
drm: Avoid NULL dereference for DRM_LEGACY debug message
drm: Use u64_to_user_ptr() helper for blob ioctls
drm: Fix conflicting macro parameter in drm_mm_for_each_node_in_range()
drm: Fixup kernel doc for driver->gem_create_object
drm/hisilicon/hibmc: mark PM functions __maybe_unused
drm/hisilicon/hibmc: Checking for NULL instead of IS_ERR()
drm: bridge: add DesignWare HDMI I2S audio support
drm: Check against color expansion in drm_mm_reserve_node()
drm: Define drm_mm_for_each_node_in_range()
drm/doc: Fix links in drm_property.c
MAINTAINERS: Add link to drm-misc documentation
vgaarb: use valid dev pointer in vgaarb_info()
drm/atomic: Unconfuse the old_state mess in commmit_tail
...
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 6798c3ad9d53..336be31ff3de 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -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); |