kernel: bump 5.15 to 5.15.100
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.15 / 950-0898-drm-vc4-Consolidate-Hardware-Revision-Check.patch
1 From def27ddc4bcd560f7e7a53d7aecc4ba4f78921e1 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 21 Apr 2022 14:27:11 +0200
4 Subject: [PATCH] drm/vc4: Consolidate Hardware Revision Check
5
6 A new generation of controller has been introduced with the
7 BCM2711/RaspberryPi4. This generation needs a bunch of quirks, and over
8 time we've piled on a number of checks in most parts of the drivers.
9
10 All these checks are performed several times, and are not always
11 consistent. Let's create a single, global, variable to hold it and use
12 it everywhere.
13
14 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
15 ---
16 drivers/gpu/drm/vc4/vc4_crtc.c | 10 +++++-----
17 drivers/gpu/drm/vc4/vc4_drv.c | 4 ++++
18 drivers/gpu/drm/vc4/vc4_drv.h | 6 +++---
19 drivers/gpu/drm/vc4/vc4_hvs.c | 26 +++++++++++++-------------
20 drivers/gpu/drm/vc4/vc4_kms.c | 12 +++++-------
21 drivers/gpu/drm/vc4/vc4_plane.c | 13 ++++++-------
22 6 files changed, 36 insertions(+), 35 deletions(-)
23
24 --- a/drivers/gpu/drm/vc4/vc4_crtc.c
25 +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
26 @@ -256,7 +256,7 @@ static u32 vc4_get_fifo_full_level(struc
27 * Removing 1 from the FIFO full level however
28 * seems to completely remove that issue.
29 */
30 - if (!vc4->hvs->hvs5)
31 + if (!vc4->is_vc5)
32 return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;
33
34 return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
35 @@ -409,7 +409,7 @@ static void vc4_crtc_config_pv(struct dr
36 if (is_dsi)
37 CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
38
39 - if (vc4->hvs->hvs5)
40 + if (vc4->is_vc5)
41 CRTC_WRITE(PV_MUX_CFG,
42 VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
43 PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
44 @@ -867,7 +867,7 @@ static int vc4_async_set_fence_cb(struct
45 struct vc4_dev *vc4 = to_vc4_dev(dev);
46 struct dma_fence *fence;
47
48 - if (!vc4->hvs->hvs5) {
49 + if (!vc4->is_vc5) {
50 struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
51
52 return vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno,
53 @@ -1209,13 +1209,13 @@ int vc4_crtc_init(struct drm_device *drm
54 crtc_funcs, NULL);
55 drm_crtc_helper_add(crtc, crtc_helper_funcs);
56
57 - if (!vc4->hvs->hvs5) {
58 + if (!vc4->is_vc5) {
59 drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
60 drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
61 }
62
63
64 - if (!vc4->hvs->hvs5) {
65 + if (!vc4->is_vc5) {
66 /* We support CTM, but only for one CRTC at a time. It's therefore
67 * implemented as private driver state in vc4_kms, not here.
68 */
69 --- a/drivers/gpu/drm/vc4/vc4_drv.c
70 +++ b/drivers/gpu/drm/vc4/vc4_drv.c
71 @@ -247,10 +247,13 @@ static int vc4_drm_bind(struct device *d
72 struct vc4_dev *vc4;
73 struct device_node *node;
74 struct drm_crtc *crtc;
75 + bool is_vc5;
76 int ret = 0;
77
78 dev->coherent_dma_mask = DMA_BIT_MASK(32);
79
80 + is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
81 +
82 /* If VC4 V3D is missing, don't advertise render nodes. */
83 node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL);
84 if (!node || !of_device_is_available(node))
85 @@ -270,6 +273,7 @@ static int vc4_drm_bind(struct device *d
86 vc4 = devm_drm_dev_alloc(dev, &vc4_drm_driver, struct vc4_dev, base);
87 if (IS_ERR(vc4))
88 return PTR_ERR(vc4);
89 + vc4->is_vc5 = is_vc5;
90
91 drm = &vc4->base;
92 platform_set_drvdata(pdev, drm);
93 --- a/drivers/gpu/drm/vc4/vc4_drv.h
94 +++ b/drivers/gpu/drm/vc4/vc4_drv.h
95 @@ -75,6 +75,8 @@ struct vc4_perfmon {
96 struct vc4_dev {
97 struct drm_device base;
98
99 + bool is_vc5;
100 +
101 unsigned int irq;
102
103 bool firmware_kms;
104 @@ -321,6 +323,7 @@ struct vc4_v3d {
105 };
106
107 struct vc4_hvs {
108 + struct vc4_dev *vc4;
109 struct platform_device *pdev;
110 void __iomem *regs;
111 u32 __iomem *dlist;
112 @@ -339,9 +342,6 @@ struct vc4_hvs {
113
114 struct debugfs_regset32 regset;
115
116 - /* HVS version 5 flag, therefore requires updated dlist structures */
117 - bool hvs5;
118 -
119 /*
120 * Even if HDMI0 on the RPi4 can output modes requiring a pixel
121 * rate higher than 297MHz, it needs some adjustments in the
122 --- a/drivers/gpu/drm/vc4/vc4_hvs.c
123 +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
124 @@ -413,10 +413,11 @@ static void vc5_hvs_update_gamma_lut(str
125
126 int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output)
127 {
128 + struct vc4_dev *vc4 = hvs->vc4;
129 u32 reg;
130 int ret;
131
132 - if (!hvs->hvs5)
133 + if (!vc4->is_vc5)
134 return output;
135
136 switch (output) {
137 @@ -466,6 +467,7 @@ int vc4_hvs_get_fifo_from_output(struct
138 static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc,
139 struct drm_display_mode *mode, bool oneshot)
140 {
141 + struct vc4_dev *vc4 = hvs->vc4;
142 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
143 struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state);
144 unsigned int chan = vc4_crtc_state->assigned_channel;
145 @@ -484,7 +486,7 @@ static int vc4_hvs_init_channel(struct v
146 */
147 dispctrl = SCALER_DISPCTRLX_ENABLE;
148
149 - if (!hvs->hvs5)
150 + if (!vc4->is_vc5)
151 dispctrl |= VC4_SET_FIELD(mode->hdisplay,
152 SCALER_DISPCTRLX_WIDTH) |
153 VC4_SET_FIELD(mode->vdisplay,
154 @@ -514,7 +516,7 @@ static int vc4_hvs_init_channel(struct v
155 /* Reload the LUT, since the SRAMs would have been disabled if
156 * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
157 */
158 - if (!hvs->hvs5)
159 + if (!vc4->is_vc5)
160 vc4_hvs_lut_load(hvs, vc4_crtc);
161 else
162 vc5_hvs_lut_load(hvs, vc4_crtc);
163 @@ -553,7 +555,7 @@ static int vc4_hvs_gamma_check(struct dr
164 struct drm_device *dev = crtc->dev;
165 struct vc4_dev *vc4 = to_vc4_dev(dev);
166
167 - if (!vc4->hvs->hvs5)
168 + if (!vc4->is_vc5)
169 return 0;
170
171 if (!crtc_state->color_mgmt_changed)
172 @@ -780,7 +782,7 @@ void vc4_hvs_atomic_flush(struct drm_crt
173 u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel));
174
175 if (crtc->state->gamma_lut) {
176 - if (!vc4->hvs->hvs5) {
177 + if (!vc4->is_vc5) {
178 vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
179 dispbkgndx |= SCALER_DISPBKGND_GAMMA;
180 } else {
181 @@ -797,7 +799,7 @@ void vc4_hvs_atomic_flush(struct drm_crt
182 * should already be disabling/enabling the pipeline
183 * when gamma changes.
184 */
185 - if (!vc4->hvs->hvs5)
186 + if (!vc4->is_vc5)
187 dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
188 }
189 HVS_WRITE(SCALER_DISPBKGNDX(channel), dispbkgndx);
190 @@ -883,11 +885,9 @@ static int vc4_hvs_bind(struct device *d
191 if (!hvs)
192 return -ENOMEM;
193
194 + hvs->vc4 = vc4;
195 hvs->pdev = pdev;
196
197 - if (of_device_is_compatible(pdev->dev.of_node, "brcm,bcm2711-hvs"))
198 - hvs->hvs5 = true;
199 -
200 hvs->regs = vc4_ioremap_regs(pdev, 0);
201 if (IS_ERR(hvs->regs))
202 return PTR_ERR(hvs->regs);
203 @@ -896,7 +896,7 @@ static int vc4_hvs_bind(struct device *d
204 hvs->regset.regs = hvs_regs;
205 hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
206
207 - if (hvs->hvs5) {
208 + if (vc4->is_vc5) {
209 unsigned long max_rate;
210
211 hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
212 @@ -916,7 +916,7 @@ static int vc4_hvs_bind(struct device *d
213 }
214 }
215
216 - if (!hvs->hvs5)
217 + if (!vc4->is_vc5)
218 hvs->dlist = hvs->regs + SCALER_DLIST_START;
219 else
220 hvs->dlist = hvs->regs + SCALER5_DLIST_START;
221 @@ -937,7 +937,7 @@ static int vc4_hvs_bind(struct device *d
222 * between planes when they don't overlap on the screen, but
223 * for now we just allocate globally.
224 */
225 - if (!hvs->hvs5)
226 + if (!vc4->is_vc5)
227 /* 48k words of 2x12-bit pixels */
228 drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024);
229 else
230 @@ -1019,7 +1019,7 @@ static int vc4_hvs_bind(struct device *d
231 NULL);
232 vc4_debugfs_add_file(drm, "hvs_dlists", vc4_hvs_debugfs_dlist,
233 NULL);
234 - if (hvs->hvs5)
235 + if (vc4->is_vc5)
236 vc4_debugfs_add_file(drm, "hvs_gamma", vc5_hvs_debugfs_gamma,
237 NULL);
238
239 --- a/drivers/gpu/drm/vc4/vc4_kms.c
240 +++ b/drivers/gpu/drm/vc4/vc4_kms.c
241 @@ -395,7 +395,7 @@ static void vc4_atomic_commit_tail(struc
242 old_hvs_state->fifo_state[channel].pending_commit = NULL;
243 }
244
245 - if (vc4->hvs && vc4->hvs->hvs5) {
246 + if (vc4->is_vc5 && !vc4->firmware_kms) {
247 unsigned long state_rate = max(old_hvs_state->core_clock_rate,
248 new_hvs_state->core_clock_rate);
249 unsigned long core_rate = clamp_t(unsigned long, state_rate,
250 @@ -409,7 +409,7 @@ static void vc4_atomic_commit_tail(struc
251 vc4_ctm_commit(vc4, state);
252
253 if (!vc4->firmware_kms) {
254 - if (vc4->hvs && vc4->hvs->hvs5)
255 + if (vc4->is_vc5)
256 vc5_hvs_pv_muxing_commit(vc4, state);
257 else
258 vc4_hvs_pv_muxing_commit(vc4, state);
259 @@ -427,7 +427,7 @@ static void vc4_atomic_commit_tail(struc
260
261 drm_atomic_helper_cleanup_planes(dev, state);
262
263 - if (vc4->hvs && vc4->hvs->hvs5) {
264 + if (vc4->is_vc5 && !vc4->firmware_kms) {
265 unsigned long core_rate = min_t(unsigned long,
266 max_clock_rate,
267 new_hvs_state->core_clock_rate);
268 @@ -995,8 +995,6 @@ static const struct drm_mode_config_func
269 int vc4_kms_load(struct drm_device *dev)
270 {
271 struct vc4_dev *vc4 = to_vc4_dev(dev);
272 - bool is_vc5 = of_device_is_compatible(dev->dev->of_node,
273 - "brcm,bcm2711-vc5");
274 int ret;
275
276 /*
277 @@ -1004,7 +1002,7 @@ int vc4_kms_load(struct drm_device *dev)
278 * the BCM2711, but the load tracker computations are used for
279 * the core clock rate calculation.
280 */
281 - if (!is_vc5) {
282 + if (!vc4->is_vc5) {
283 /* Start with the load tracker enabled. Can be
284 * disabled through the debugfs load_tracker file.
285 */
286 @@ -1020,7 +1018,7 @@ int vc4_kms_load(struct drm_device *dev)
287 return ret;
288 }
289
290 - if (is_vc5) {
291 + if (vc4->is_vc5) {
292 dev->mode_config.max_width = 7680;
293 dev->mode_config.max_height = 7680;
294 } else {
295 --- a/drivers/gpu/drm/vc4/vc4_plane.c
296 +++ b/drivers/gpu/drm/vc4/vc4_plane.c
297 @@ -544,10 +544,10 @@ static u32 vc4_lbm_size(struct drm_plane
298 }
299
300 /* Align it to 64 or 128 (hvs5) bytes */
301 - lbm = roundup(lbm, vc4->hvs->hvs5 ? 128 : 64);
302 + lbm = roundup(lbm, vc4->is_vc5 ? 128 : 64);
303
304 /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */
305 - lbm /= vc4->hvs->hvs5 ? 4 : 2;
306 + lbm /= vc4->is_vc5 ? 4 : 2;
307
308 return lbm;
309 }
310 @@ -666,7 +666,7 @@ static int vc4_plane_allocate_lbm(struct
311 ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm,
312 &vc4_state->lbm,
313 lbm_size,
314 - vc4->hvs->hvs5 ? 64 : 32,
315 + vc4->is_vc5 ? 64 : 32,
316 0, 0);
317 spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags);
318
319 @@ -1041,7 +1041,7 @@ static int vc4_plane_mode_set(struct drm
320 mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE &&
321 fb->format->has_alpha;
322
323 - if (!vc4->hvs->hvs5) {
324 + if (!vc4->is_vc5) {
325 /* Control word */
326 vc4_dlist_write(vc4_state,
327 SCALER_CTL0_VALID |
328 @@ -1572,14 +1572,13 @@ static const struct drm_plane_funcs vc4_
329 struct drm_plane *vc4_plane_init(struct drm_device *dev,
330 enum drm_plane_type type)
331 {
332 + struct vc4_dev *vc4 = to_vc4_dev(dev);
333 struct drm_plane *plane = NULL;
334 struct vc4_plane *vc4_plane;
335 u32 formats[ARRAY_SIZE(hvs_formats)];
336 int num_formats = 0;
337 int ret = 0;
338 unsigned i;
339 - bool hvs5 = of_device_is_compatible(dev->dev->of_node,
340 - "brcm,bcm2711-vc5");
341 static const uint64_t modifiers[] = {
342 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
343 DRM_FORMAT_MOD_BROADCOM_SAND128,
344 @@ -1595,7 +1594,7 @@ struct drm_plane *vc4_plane_init(struct
345 return ERR_PTR(-ENOMEM);
346
347 for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
348 - if (!hvs_formats[i].hvs5_only || hvs5) {
349 + if (!hvs_formats[i].hvs5_only || vc4->is_vc5) {
350 formats[num_formats] = hvs_formats[i].drm;
351 num_formats++;
352 }