brcm2708: update linux 4.4 patches to latest version
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0516-drm-vc4-Fix-handling-of-interlaced-video-modes.patch
1 From fa69b17facd1a2fd3e430b78f65b60b4a087b53d Mon Sep 17 00:00:00 2001
2 From: Mario Kleiner <mario.kleiner.de@gmail.com>
3 Date: Tue, 19 Jul 2016 20:58:58 +0200
4 Subject: [PATCH] drm/vc4: Fix handling of interlaced video modes.
5
6 We must not apply CRTC_INTERLACE_HALVE_V to interlaced modes during
7 mode enumeration, as drm_helper_probe_single_connector_modes
8 does, so wrap it and reset the effect of CRTC_INTERLACE_HALVE_V
9 on affected interlaced modes.
10
11 Also mode_fixup interlaced modes passed in from user space.
12
13 This fixes the vblank timestamping constants and entries in
14 the mode->crtc_xxx fields needed for precise vblank timestamping.
15
16 Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
17 Signed-off-by: Eric Anholt <eric@anholt.net>
18 ---
19 drivers/gpu/drm/vc4/vc4_crtc.c | 18 ++++++++++++++++++
20 drivers/gpu/drm/vc4/vc4_hdmi.c | 29 +++++++++++++++++++++++++++--
21 2 files changed, 45 insertions(+), 2 deletions(-)
22
23 --- a/drivers/gpu/drm/vc4/vc4_crtc.c
24 +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
25 @@ -538,6 +538,23 @@ static void vc4_crtc_enable(struct drm_c
26 CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
27 }
28
29 +static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
30 + const struct drm_display_mode *mode,
31 + struct drm_display_mode *adjusted_mode)
32 +{
33 + /*
34 + * Interlaced video modes got CRTC_INTERLACE_HALVE_V applied when
35 + * coming from user space. We don't want this, as it screws up
36 + * vblank timestamping, so fix it up.
37 + */
38 + drm_mode_set_crtcinfo(adjusted_mode, 0);
39 +
40 + DRM_DEBUG_KMS("[CRTC:%d] adjusted_mode :\n", crtc->base.id);
41 + drm_mode_debug_printmodeline(adjusted_mode);
42 +
43 + return true;
44 +}
45 +
46 static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
47 struct drm_crtc_state *state)
48 {
49 @@ -848,6 +865,7 @@ static const struct drm_crtc_helper_func
50 .mode_set_nofb = vc4_crtc_mode_set_nofb,
51 .disable = vc4_crtc_disable,
52 .enable = vc4_crtc_enable,
53 + .mode_fixup = vc4_crtc_mode_fixup,
54 .atomic_check = vc4_crtc_atomic_check,
55 .atomic_flush = vc4_crtc_atomic_flush,
56 };
57 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
58 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
59 @@ -219,10 +219,35 @@ vc4_hdmi_connector_best_encoder(struct d
60 return hdmi_connector->encoder;
61 }
62
63 +/*
64 + * drm_helper_probe_single_connector_modes() applies drm_mode_set_crtcinfo to
65 + * all modes with flag CRTC_INTERLACE_HALVE_V. We don't want this, as it
66 + * screws up vblank timestamping for interlaced modes, so fix it up.
67 + */
68 +static int vc4_hdmi_connector_probe_modes(struct drm_connector *connector,
69 + uint32_t maxX, uint32_t maxY)
70 +{
71 + struct drm_display_mode *mode;
72 + int count;
73 +
74 + count = drm_helper_probe_single_connector_modes(connector, maxX, maxY);
75 + if (count == 0)
76 + return 0;
77 +
78 + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed adapted modes :\n",
79 + connector->base.id, connector->name);
80 + list_for_each_entry(mode, &connector->modes, head) {
81 + drm_mode_set_crtcinfo(mode, 0);
82 + drm_mode_debug_printmodeline(mode);
83 + }
84 +
85 + return count;
86 +}
87 +
88 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
89 .dpms = drm_atomic_helper_connector_dpms,
90 .detect = vc4_hdmi_connector_detect,
91 - .fill_modes = drm_helper_probe_single_connector_modes,
92 + .fill_modes = vc4_hdmi_connector_probe_modes,
93 .destroy = vc4_hdmi_connector_destroy,
94 .reset = drm_atomic_helper_connector_reset,
95 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
96 @@ -258,7 +283,7 @@ static struct drm_connector *vc4_hdmi_co
97 connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
98 DRM_CONNECTOR_POLL_DISCONNECT);
99
100 - connector->interlace_allowed = 0;
101 + connector->interlace_allowed = 1;
102 connector->doublescan_allowed = 0;
103
104 drm_mode_connector_attach_encoder(connector, encoder);