8c1b0ec80539ab957ae4f793a817d92985cb7893
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.15 / 950-0781-drm-vc4-Support-zpos-on-all-planes.patch
1 From 0e096c4f431ccd7f73e9baa930821dd3bbe93e35 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Tue, 25 Jan 2022 17:28:18 +0000
4 Subject: [PATCH] drm/vc4: Support zpos on all planes
5
6 Adds the zpos property to all planes, and creates the dlist
7 by placing the fragments in the correct order based on zpos.
8
9 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
10 ---
11 drivers/gpu/drm/vc4/vc4_hvs.c | 43 +++++++++++++++++++++------------
12 drivers/gpu/drm/vc4/vc4_kms.c | 3 +--
13 drivers/gpu/drm/vc4/vc4_plane.c | 22 ++++++++++++++---
14 3 files changed, 48 insertions(+), 20 deletions(-)
15
16 --- a/drivers/gpu/drm/vc4/vc4_hvs.c
17 +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
18 @@ -854,6 +854,8 @@ void vc4_hvs_atomic_flush(struct drm_crt
19 bool debug_dump_regs = false;
20 bool enable_bg_fill = false;
21 u32 __iomem *dlist_start, *dlist_next;
22 + unsigned int zpos = 0;
23 + bool found = false;
24
25 if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED)
26 return;
27 @@ -867,23 +869,34 @@ void vc4_hvs_atomic_flush(struct drm_crt
28 dlist_next = dlist_start;
29
30 /* Copy all the active planes' dlist contents to the hardware dlist. */
31 - drm_atomic_crtc_for_each_plane(plane, crtc) {
32 - /* Is this the first active plane? */
33 - if (dlist_next == dlist_start) {
34 - /* We need to enable background fill when a plane
35 - * could be alpha blending from the background, i.e.
36 - * where no other plane is underneath. It suffices to
37 - * consider the first active plane here since we set
38 - * needs_bg_fill such that either the first plane
39 - * already needs it or all planes on top blend from
40 - * the first or a lower plane.
41 - */
42 - vc4_plane_state = to_vc4_plane_state(plane->state);
43 - enable_bg_fill = vc4_plane_state->needs_bg_fill;
44 + do {
45 + found = false;
46 +
47 + drm_atomic_crtc_for_each_plane(plane, crtc) {
48 + if (plane->state->normalized_zpos != zpos)
49 + continue;
50 +
51 + /* Is this the first active plane? */
52 + if (dlist_next == dlist_start) {
53 + /* We need to enable background fill when a plane
54 + * could be alpha blending from the background, i.e.
55 + * where no other plane is underneath. It suffices to
56 + * consider the first active plane here since we set
57 + * needs_bg_fill such that either the first plane
58 + * already needs it or all planes on top blend from
59 + * the first or a lower plane.
60 + */
61 + vc4_plane_state = to_vc4_plane_state(plane->state);
62 + enable_bg_fill = vc4_plane_state->needs_bg_fill;
63 + }
64 +
65 + dlist_next += vc4_plane_write_dlist(plane, dlist_next);
66 +
67 + found = true;
68 }
69
70 - dlist_next += vc4_plane_write_dlist(plane, dlist_next);
71 - }
72 + zpos++;
73 + } while (found);
74
75 writel(SCALER_CTL0_END, dlist_next);
76 dlist_next++;
77 --- a/drivers/gpu/drm/vc4/vc4_kms.c
78 +++ b/drivers/gpu/drm/vc4/vc4_kms.c
79 @@ -1042,8 +1042,7 @@ int vc4_kms_load(struct drm_device *dev)
80 dev->mode_config.helper_private = &vc4_mode_config_helpers;
81 dev->mode_config.preferred_depth = 24;
82 dev->mode_config.async_page_flip = true;
83 - if (vc4->firmware_kms)
84 - dev->mode_config.normalize_zpos = true;
85 + dev->mode_config.normalize_zpos = true;
86
87 ret = vc4_ctm_obj_init(vc4);
88 if (ret)
89 --- a/drivers/gpu/drm/vc4/vc4_plane.c
90 +++ b/drivers/gpu/drm/vc4/vc4_plane.c
91 @@ -1573,9 +1573,14 @@ struct drm_plane *vc4_plane_init(struct
92 DRM_COLOR_YCBCR_BT709,
93 DRM_COLOR_YCBCR_LIMITED_RANGE);
94
95 + if (type == DRM_PLANE_TYPE_PRIMARY)
96 + drm_plane_create_zpos_immutable_property(plane, 0);
97 +
98 return plane;
99 }
100
101 +#define VC4_NUM_OVERLAY_PLANES 16
102 +
103 int vc4_plane_create_additional_planes(struct drm_device *drm)
104 {
105 struct drm_plane *cursor_plane;
106 @@ -1591,7 +1596,7 @@ int vc4_plane_create_additional_planes(s
107 * modest number of planes to expose, that should hopefully
108 * still cover any sane usecase.
109 */
110 - for (i = 0; i < 16; i++) {
111 + for (i = 0; i < VC4_NUM_OVERLAY_PLANES; i++) {
112 struct drm_plane *plane =
113 vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY);
114
115 @@ -1600,17 +1605,28 @@ int vc4_plane_create_additional_planes(s
116
117 plane->possible_crtcs =
118 GENMASK(drm->mode_config.num_crtc - 1, 0);
119 +
120 + /* Create zpos property. Max of all the overlays + 1 primary +
121 + * 1 cursor plane on a crtc.
122 + */
123 + drm_plane_create_zpos_property(plane, i + 1, 1,
124 + VC4_NUM_OVERLAY_PLANES + 1);
125 }
126
127 drm_for_each_crtc(crtc, drm) {
128 /* Set up the legacy cursor after overlay initialization,
129 - * since we overlay planes on the CRTC in the order they were
130 - * initialized.
131 + * since the zpos fallback is that planes are rendered by plane
132 + * ID order, and that then puts the cursor on top.
133 */
134 cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
135 if (!IS_ERR(cursor_plane)) {
136 cursor_plane->possible_crtcs = drm_crtc_mask(crtc);
137 crtc->cursor = cursor_plane;
138 +
139 + drm_plane_create_zpos_property(cursor_plane,
140 + VC4_NUM_OVERLAY_PLANES + 1,
141 + 1,
142 + VC4_NUM_OVERLAY_PLANES + 1);
143 }
144 }
145