forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/gpu/drm/vc4/vc4_crtc.c
....@@ -1,9 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2015 Broadcom
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
74 */
85
96 /**
....@@ -32,102 +29,67 @@
3229 * ones that set the clock.
3330 */
3431
35
-#include <drm/drm_atomic.h>
36
-#include <drm/drm_atomic_helper.h>
37
-#include <drm/drm_crtc_helper.h>
3832 #include <linux/clk.h>
39
-#include <drm/drm_fb_cma_helper.h>
4033 #include <linux/component.h>
4134 #include <linux/of_device.h>
35
+
36
+#include <drm/drm_atomic.h>
37
+#include <drm/drm_atomic_helper.h>
38
+#include <drm/drm_atomic_uapi.h>
39
+#include <drm/drm_fb_cma_helper.h>
40
+#include <drm/drm_print.h>
41
+#include <drm/drm_probe_helper.h>
42
+#include <drm/drm_vblank.h>
43
+
4244 #include "vc4_drv.h"
4345 #include "vc4_regs.h"
4446
45
-struct vc4_crtc_state {
46
- struct drm_crtc_state base;
47
- /* Dlist area for this CRTC configuration. */
48
- struct drm_mm_node mm;
49
- bool feed_txp;
50
- bool txp_armed;
51
-};
52
-
53
-static inline struct vc4_crtc_state *
54
-to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
55
-{
56
- return (struct vc4_crtc_state *)crtc_state;
57
-}
47
+#define HVS_FIFO_LATENCY_PIX 6
5848
5949 #define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
6050 #define CRTC_READ(offset) readl(vc4_crtc->regs + (offset))
6151
62
-#define CRTC_REG(reg) { reg, #reg }
63
-static const struct {
64
- u32 reg;
65
- const char *name;
66
-} crtc_regs[] = {
67
- CRTC_REG(PV_CONTROL),
68
- CRTC_REG(PV_V_CONTROL),
69
- CRTC_REG(PV_VSYNCD_EVEN),
70
- CRTC_REG(PV_HORZA),
71
- CRTC_REG(PV_HORZB),
72
- CRTC_REG(PV_VERTA),
73
- CRTC_REG(PV_VERTB),
74
- CRTC_REG(PV_VERTA_EVEN),
75
- CRTC_REG(PV_VERTB_EVEN),
76
- CRTC_REG(PV_INTEN),
77
- CRTC_REG(PV_INTSTAT),
78
- CRTC_REG(PV_STAT),
79
- CRTC_REG(PV_HACT_ACT),
52
+static const struct debugfs_reg32 crtc_regs[] = {
53
+ VC4_REG32(PV_CONTROL),
54
+ VC4_REG32(PV_V_CONTROL),
55
+ VC4_REG32(PV_VSYNCD_EVEN),
56
+ VC4_REG32(PV_HORZA),
57
+ VC4_REG32(PV_HORZB),
58
+ VC4_REG32(PV_VERTA),
59
+ VC4_REG32(PV_VERTB),
60
+ VC4_REG32(PV_VERTA_EVEN),
61
+ VC4_REG32(PV_VERTB_EVEN),
62
+ VC4_REG32(PV_INTEN),
63
+ VC4_REG32(PV_INTSTAT),
64
+ VC4_REG32(PV_STAT),
65
+ VC4_REG32(PV_HACT_ACT),
8066 };
8167
82
-static void vc4_crtc_dump_regs(struct vc4_crtc *vc4_crtc)
68
+static unsigned int
69
+vc4_crtc_get_cob_allocation(struct vc4_dev *vc4, unsigned int channel)
8370 {
84
- int i;
71
+ u32 dispbase = HVS_READ(SCALER_DISPBASEX(channel));
72
+ /* Top/base are supposed to be 4-pixel aligned, but the
73
+ * Raspberry Pi firmware fills the low bits (which are
74
+ * presumably ignored).
75
+ */
76
+ u32 top = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_TOP) & ~3;
77
+ u32 base = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_BASE) & ~3;
8578
86
- for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
87
- DRM_INFO("0x%04x (%s): 0x%08x\n",
88
- crtc_regs[i].reg, crtc_regs[i].name,
89
- CRTC_READ(crtc_regs[i].reg));
90
- }
79
+ return top - base + 4;
9180 }
9281
93
-#ifdef CONFIG_DEBUG_FS
94
-int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused)
82
+static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
83
+ bool in_vblank_irq,
84
+ int *vpos, int *hpos,
85
+ ktime_t *stime, ktime_t *etime,
86
+ const struct drm_display_mode *mode)
9587 {
96
- struct drm_info_node *node = (struct drm_info_node *)m->private;
97
- struct drm_device *dev = node->minor->dev;
98
- int crtc_index = (uintptr_t)node->info_ent->data;
99
- struct drm_crtc *crtc;
100
- struct vc4_crtc *vc4_crtc;
101
- int i;
102
-
103
- i = 0;
104
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
105
- if (i == crtc_index)
106
- break;
107
- i++;
108
- }
109
- if (!crtc)
110
- return 0;
111
- vc4_crtc = to_vc4_crtc(crtc);
112
-
113
- for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
114
- seq_printf(m, "%s (0x%04x): 0x%08x\n",
115
- crtc_regs[i].name, crtc_regs[i].reg,
116
- CRTC_READ(crtc_regs[i].reg));
117
- }
118
-
119
- return 0;
120
-}
121
-#endif
122
-
123
-bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
124
- bool in_vblank_irq, int *vpos, int *hpos,
125
- ktime_t *stime, ktime_t *etime,
126
- const struct drm_display_mode *mode)
127
-{
88
+ struct drm_device *dev = crtc->dev;
12889 struct vc4_dev *vc4 = to_vc4_dev(dev);
129
- struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id);
13090 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
91
+ struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state);
92
+ unsigned int cob_size;
13193 u32 val;
13294 int fifo_lines;
13395 int vblank_lines;
....@@ -143,7 +105,7 @@
143105 * Read vertical scanline which is currently composed for our
144106 * pixelvalve by the HVS, and also the scaler status.
145107 */
146
- val = HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel));
108
+ val = HVS_READ(SCALER_DISPSTATX(vc4_crtc_state->assigned_channel));
147109
148110 /* Get optional system timestamp after query. */
149111 if (etime)
....@@ -163,8 +125,9 @@
163125 *hpos += mode->crtc_htotal / 2;
164126 }
165127
128
+ cob_size = vc4_crtc_get_cob_allocation(vc4, vc4_crtc_state->assigned_channel);
166129 /* This is the offset we need for translating hvs -> pv scanout pos. */
167
- fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay;
130
+ fifo_lines = cob_size / mode->crtc_hdisplay;
168131
169132 if (fifo_lines > 0)
170133 ret = true;
....@@ -238,68 +201,75 @@
238201 return ret;
239202 }
240203
241
-static void vc4_crtc_destroy(struct drm_crtc *crtc)
204
+void vc4_crtc_destroy(struct drm_crtc *crtc)
242205 {
243206 drm_crtc_cleanup(crtc);
244207 }
245208
246
-static void
247
-vc4_crtc_lut_load(struct drm_crtc *crtc)
209
+static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
248210 {
249
- struct drm_device *dev = crtc->dev;
250
- struct vc4_dev *vc4 = to_vc4_dev(dev);
251
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
252
- u32 i;
211
+ const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc);
212
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
213
+ struct vc4_dev *vc4 = to_vc4_dev(vc4_crtc->base.dev);
214
+ u32 fifo_len_bytes = pv_data->fifo_depth;
253215
254
- /* The LUT memory is laid out with each HVS channel in order,
255
- * each of which takes 256 writes for R, 256 for G, then 256
256
- * for B.
216
+ /*
217
+ * Pixels are pulled from the HVS if the number of bytes is
218
+ * lower than the FIFO full level.
219
+ *
220
+ * The latency of the pixel fetch mechanism is 6 pixels, so we
221
+ * need to convert those 6 pixels in bytes, depending on the
222
+ * format, and then subtract that from the length of the FIFO
223
+ * to make sure we never end up in a situation where the FIFO
224
+ * is full.
257225 */
258
- HVS_WRITE(SCALER_GAMADDR,
259
- SCALER_GAMADDR_AUTOINC |
260
- (vc4_crtc->channel * 3 * crtc->gamma_size));
261
-
262
- for (i = 0; i < crtc->gamma_size; i++)
263
- HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_r[i]);
264
- for (i = 0; i < crtc->gamma_size; i++)
265
- HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_g[i]);
266
- for (i = 0; i < crtc->gamma_size; i++)
267
- HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
268
-}
269
-
270
-static void
271
-vc4_crtc_update_gamma_lut(struct drm_crtc *crtc)
272
-{
273
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
274
- struct drm_color_lut *lut = crtc->state->gamma_lut->data;
275
- u32 length = drm_color_lut_size(crtc->state->gamma_lut);
276
- u32 i;
277
-
278
- for (i = 0; i < length; i++) {
279
- vc4_crtc->lut_r[i] = drm_color_lut_extract(lut[i].red, 8);
280
- vc4_crtc->lut_g[i] = drm_color_lut_extract(lut[i].green, 8);
281
- vc4_crtc->lut_b[i] = drm_color_lut_extract(lut[i].blue, 8);
282
- }
283
-
284
- vc4_crtc_lut_load(crtc);
285
-}
286
-
287
-static u32 vc4_get_fifo_full_level(u32 format)
288
-{
289
- static const u32 fifo_len_bytes = 64;
290
- static const u32 hvs_latency_pix = 6;
291
-
292226 switch (format) {
293227 case PV_CONTROL_FORMAT_DSIV_16:
294228 case PV_CONTROL_FORMAT_DSIC_16:
295
- return fifo_len_bytes - 2 * hvs_latency_pix;
229
+ return fifo_len_bytes - 2 * HVS_FIFO_LATENCY_PIX;
296230 case PV_CONTROL_FORMAT_DSIV_18:
297231 return fifo_len_bytes - 14;
298232 case PV_CONTROL_FORMAT_24:
299233 case PV_CONTROL_FORMAT_DSIV_24:
300234 default:
301
- return fifo_len_bytes - 3 * hvs_latency_pix;
235
+ /*
236
+ * For some reason, the pixelvalve4 doesn't work with
237
+ * the usual formula and will only work with 32.
238
+ */
239
+ if (crtc_data->hvs_output == 5)
240
+ return 32;
241
+
242
+ /*
243
+ * It looks like in some situations, we will overflow
244
+ * the PixelValve FIFO (with the bit 10 of PV stat being
245
+ * set) and stall the HVS / PV, eventually resulting in
246
+ * a page flip timeout.
247
+ *
248
+ * Displaying the video overlay during a playback with
249
+ * Kodi on an RPi3 seems to be a great solution with a
250
+ * failure rate around 50%.
251
+ *
252
+ * Removing 1 from the FIFO full level however
253
+ * seems to completely remove that issue.
254
+ */
255
+ if (!vc4->hvs->hvs5)
256
+ return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;
257
+
258
+ return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
302259 }
260
+}
261
+
262
+static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc,
263
+ u32 format)
264
+{
265
+ u32 level = vc4_get_fifo_full_level(vc4_crtc, format);
266
+ u32 ret = 0;
267
+
268
+ ret |= VC4_SET_FIELD((level >> 6),
269
+ PV5_CONTROL_FIFO_LEVEL_HIGH);
270
+
271
+ return ret | VC4_SET_FIELD(level & 0x3f,
272
+ PV_CONTROL_FIFO_LEVEL);
303273 }
304274
305275 /*
....@@ -326,39 +296,58 @@
326296 return NULL;
327297 }
328298
299
+static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
300
+{
301
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
302
+
303
+ /* The PV needs to be disabled before it can be flushed */
304
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
305
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR);
306
+}
307
+
329308 static void vc4_crtc_config_pv(struct drm_crtc *crtc)
330309 {
310
+ struct drm_device *dev = crtc->dev;
311
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
331312 struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
332313 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
333314 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
315
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
334316 struct drm_crtc_state *state = crtc->state;
335317 struct drm_display_mode *mode = &state->adjusted_mode;
336318 bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
337319 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
338320 bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
339321 vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
340
- u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
322
+ bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
323
+ u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
324
+ u8 ppc = pv_data->pixels_per_clock;
325
+ bool debug_dump_regs = false;
341326
342
- /* Reset the PV fifo. */
343
- CRTC_WRITE(PV_CONTROL, 0);
344
- CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
345
- CRTC_WRITE(PV_CONTROL, 0);
327
+ if (debug_dump_regs) {
328
+ struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
329
+ dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs before:\n",
330
+ drm_crtc_index(crtc));
331
+ drm_print_regset32(&p, &vc4_crtc->regset);
332
+ }
333
+
334
+ vc4_crtc_pixelvalve_reset(crtc);
346335
347336 CRTC_WRITE(PV_HORZA,
348
- VC4_SET_FIELD((mode->htotal -
349
- mode->hsync_end) * pixel_rep,
337
+ VC4_SET_FIELD((mode->htotal - mode->hsync_end) * pixel_rep / ppc,
350338 PV_HORZA_HBP) |
351
- VC4_SET_FIELD((mode->hsync_end -
352
- mode->hsync_start) * pixel_rep,
339
+ VC4_SET_FIELD((mode->hsync_end - mode->hsync_start) * pixel_rep / ppc,
353340 PV_HORZA_HSYNC));
341
+
354342 CRTC_WRITE(PV_HORZB,
355
- VC4_SET_FIELD((mode->hsync_start -
356
- mode->hdisplay) * pixel_rep,
343
+ VC4_SET_FIELD((mode->hsync_start - mode->hdisplay) * pixel_rep / ppc,
357344 PV_HORZB_HFP) |
358
- VC4_SET_FIELD(mode->hdisplay * pixel_rep, PV_HORZB_HACTIVE));
345
+ VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc,
346
+ PV_HORZB_HACTIVE));
359347
360348 CRTC_WRITE(PV_VERTA,
361
- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
349
+ VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
350
+ interlace,
362351 PV_VERTA_VBP) |
363352 VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
364353 PV_VERTA_VSYNC));
....@@ -370,7 +359,7 @@
370359 if (interlace) {
371360 CRTC_WRITE(PV_VERTA_EVEN,
372361 VC4_SET_FIELD(mode->crtc_vtotal -
373
- mode->crtc_vsync_end - 1,
362
+ mode->crtc_vsync_end,
374363 PV_VERTA_VBP) |
375364 VC4_SET_FIELD(mode->crtc_vsync_end -
376365 mode->crtc_vsync_start,
....@@ -390,7 +379,7 @@
390379 PV_VCONTROL_CONTINUOUS |
391380 (is_dsi ? PV_VCONTROL_DSI : 0) |
392381 PV_VCONTROL_INTERLACE |
393
- VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
382
+ VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
394383 PV_VCONTROL_ODD_DELAY));
395384 CRTC_WRITE(PV_VSYNCD_EVEN, 0);
396385 } else {
....@@ -399,77 +388,29 @@
399388 (is_dsi ? PV_VCONTROL_DSI : 0));
400389 }
401390
402
- CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
391
+ if (is_dsi)
392
+ CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
403393
404
- CRTC_WRITE(PV_CONTROL,
394
+ if (vc4->hvs->hvs5)
395
+ CRTC_WRITE(PV_MUX_CFG,
396
+ VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
397
+ PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
398
+
399
+ CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR |
400
+ vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
405401 VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
406
- VC4_SET_FIELD(vc4_get_fifo_full_level(format),
407
- PV_CONTROL_FIFO_LEVEL) |
408402 VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
409403 PV_CONTROL_CLR_AT_START |
410404 PV_CONTROL_TRIGGER_UNDERFLOW |
411405 PV_CONTROL_WAIT_HSTART |
412406 VC4_SET_FIELD(vc4_encoder->clock_select,
413
- PV_CONTROL_CLK_SELECT) |
414
- PV_CONTROL_FIFO_CLR |
415
- PV_CONTROL_EN);
416
-}
417
-
418
-static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
419
-{
420
- struct drm_device *dev = crtc->dev;
421
- struct vc4_dev *vc4 = to_vc4_dev(dev);
422
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
423
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
424
- struct drm_display_mode *mode = &crtc->state->adjusted_mode;
425
- bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
426
- bool debug_dump_regs = false;
407
+ PV_CONTROL_CLK_SELECT));
427408
428409 if (debug_dump_regs) {
429
- DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
430
- vc4_crtc_dump_regs(vc4_crtc);
431
- }
432
-
433
- if (vc4_crtc->channel == 2) {
434
- u32 dispctrl;
435
- u32 dsp3_mux;
436
-
437
- /*
438
- * SCALER_DISPCTRL_DSP3 = X, where X < 2 means 'connect DSP3 to
439
- * FIFO X'.
440
- * SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'.
441
- *
442
- * DSP3 is connected to FIFO2 unless the transposer is
443
- * enabled. In this case, FIFO 2 is directly accessed by the
444
- * TXP IP, and we need to disable the FIFO2 -> pixelvalve1
445
- * route.
446
- */
447
- if (vc4_state->feed_txp)
448
- dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
449
- else
450
- dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
451
-
452
- dispctrl = HVS_READ(SCALER_DISPCTRL) &
453
- ~SCALER_DISPCTRL_DSP3_MUX_MASK;
454
- HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux);
455
- }
456
-
457
- if (!vc4_state->feed_txp)
458
- vc4_crtc_config_pv(crtc);
459
-
460
- HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
461
- SCALER_DISPBKGND_AUTOHS |
462
- SCALER_DISPBKGND_GAMMA |
463
- (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
464
-
465
- /* Reload the LUT, since the SRAMs would have been disabled if
466
- * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
467
- */
468
- vc4_crtc_lut_load(crtc);
469
-
470
- if (debug_dump_regs) {
471
- DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
472
- vc4_crtc_dump_regs(vc4_crtc);
410
+ struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
411
+ dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs after:\n",
412
+ drm_crtc_index(crtc));
413
+ drm_print_regset32(&p, &vc4_crtc->regset);
473414 }
474415 }
475416
....@@ -481,46 +422,86 @@
481422 SCALER_DISPCTRL_ENABLE);
482423 }
483424
484
-static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
485
- struct drm_crtc_state *old_state)
425
+static int vc4_crtc_disable(struct drm_crtc *crtc, unsigned int channel)
486426 {
487
- struct drm_device *dev = crtc->dev;
488
- struct vc4_dev *vc4 = to_vc4_dev(dev);
427
+ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
428
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
489429 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
490
- u32 chan = vc4_crtc->channel;
430
+ struct drm_device *dev = crtc->dev;
491431 int ret;
492
- require_hvs_enabled(dev);
493
-
494
- /* Disable vblank irq handling before crtc is disabled. */
495
- drm_crtc_vblank_off(crtc);
496432
497433 CRTC_WRITE(PV_V_CONTROL,
498434 CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
499435 ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
500436 WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
501437
502
- if (HVS_READ(SCALER_DISPCTRLX(chan)) &
503
- SCALER_DISPCTRLX_ENABLE) {
504
- HVS_WRITE(SCALER_DISPCTRLX(chan),
505
- SCALER_DISPCTRLX_RESET);
438
+ /*
439
+ * This delay is needed to avoid to get a pixel stuck in an
440
+ * unflushable FIFO between the pixelvalve and the HDMI
441
+ * controllers on the BCM2711.
442
+ *
443
+ * Timing is fairly sensitive here, so mdelay is the safest
444
+ * approach.
445
+ *
446
+ * If it was to be reworked, the stuck pixel happens on a
447
+ * BCM2711 when changing mode with a good probability, so a
448
+ * script that changes mode on a regular basis should trigger
449
+ * the bug after less than 10 attempts. It manifests itself with
450
+ * every pixels being shifted by one to the right, and thus the
451
+ * last pixel of a line actually being displayed as the first
452
+ * pixel on the next line.
453
+ */
454
+ mdelay(20);
506455
507
- /* While the docs say that reset is self-clearing, it
508
- * seems it doesn't actually.
509
- */
510
- HVS_WRITE(SCALER_DISPCTRLX(chan), 0);
511
- }
456
+ if (vc4_encoder && vc4_encoder->post_crtc_disable)
457
+ vc4_encoder->post_crtc_disable(encoder);
512458
513
- /* Once we leave, the scaler should be disabled and its fifo empty. */
459
+ vc4_crtc_pixelvalve_reset(crtc);
460
+ vc4_hvs_stop_channel(dev, channel);
514461
515
- WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET);
462
+ if (vc4_encoder && vc4_encoder->post_crtc_powerdown)
463
+ vc4_encoder->post_crtc_powerdown(encoder);
516464
517
- WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)),
518
- SCALER_DISPSTATX_MODE) !=
519
- SCALER_DISPSTATX_MODE_DISABLED);
465
+ return 0;
466
+}
520467
521
- WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) &
522
- (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
523
- SCALER_DISPSTATX_EMPTY);
468
+int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
469
+{
470
+ struct drm_device *drm = crtc->dev;
471
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
472
+ int channel;
473
+
474
+ if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
475
+ "brcm,bcm2711-pixelvalve2") ||
476
+ of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
477
+ "brcm,bcm2711-pixelvalve4")))
478
+ return 0;
479
+
480
+ if (!(CRTC_READ(PV_CONTROL) & PV_CONTROL_EN))
481
+ return 0;
482
+
483
+ if (!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN))
484
+ return 0;
485
+
486
+ channel = vc4_hvs_get_fifo_from_output(drm, vc4_crtc->data->hvs_output);
487
+ if (channel < 0)
488
+ return 0;
489
+
490
+ return vc4_crtc_disable(crtc, channel);
491
+}
492
+
493
+static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
494
+ struct drm_crtc_state *old_state)
495
+{
496
+ struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state);
497
+ struct drm_device *dev = crtc->dev;
498
+
499
+ require_hvs_enabled(dev);
500
+
501
+ /* Disable vblank irq handling before crtc is disabled. */
502
+ drm_crtc_vblank_off(crtc);
503
+
504
+ vc4_crtc_disable(crtc, old_vc4_state->assigned_channel);
524505
525506 /*
526507 * Make sure we issue a vblank event after disabling the CRTC if
....@@ -536,52 +517,13 @@
536517 }
537518 }
538519
539
-void vc4_crtc_txp_armed(struct drm_crtc_state *state)
540
-{
541
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
542
-
543
- vc4_state->txp_armed = true;
544
-}
545
-
546
-static void vc4_crtc_update_dlist(struct drm_crtc *crtc)
547
-{
548
- struct drm_device *dev = crtc->dev;
549
- struct vc4_dev *vc4 = to_vc4_dev(dev);
550
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
551
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
552
-
553
- if (crtc->state->event) {
554
- unsigned long flags;
555
-
556
- crtc->state->event->pipe = drm_crtc_index(crtc);
557
-
558
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
559
-
560
- spin_lock_irqsave(&dev->event_lock, flags);
561
-
562
- if (!vc4_state->feed_txp || vc4_state->txp_armed) {
563
- vc4_crtc->event = crtc->state->event;
564
- crtc->state->event = NULL;
565
- }
566
-
567
- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
568
- vc4_state->mm.start);
569
-
570
- spin_unlock_irqrestore(&dev->event_lock, flags);
571
- } else {
572
- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
573
- vc4_state->mm.start);
574
- }
575
-}
576
-
577520 static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
578521 struct drm_crtc_state *old_state)
579522 {
580523 struct drm_device *dev = crtc->dev;
581
- struct vc4_dev *vc4 = to_vc4_dev(dev);
582524 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
583
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
584
- struct drm_display_mode *mode = &crtc->state->adjusted_mode;
525
+ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
526
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
585527
586528 require_hvs_enabled(dev);
587529
....@@ -589,25 +531,27 @@
589531 * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
590532 */
591533 drm_crtc_vblank_on(crtc);
592
- vc4_crtc_update_dlist(crtc);
593534
594
- /* Turn on the scaler, which will wait for vstart to start
595
- * compositing.
596
- * When feeding the transposer, we should operate in oneshot
597
- * mode.
598
- */
599
- HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
600
- VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) |
601
- VC4_SET_FIELD(mode->vdisplay, SCALER_DISPCTRLX_HEIGHT) |
602
- SCALER_DISPCTRLX_ENABLE |
603
- (vc4_state->feed_txp ? SCALER_DISPCTRLX_ONESHOT : 0));
535
+ vc4_hvs_atomic_enable(crtc, old_state);
536
+
537
+ if (vc4_encoder->pre_crtc_configure)
538
+ vc4_encoder->pre_crtc_configure(encoder);
539
+
540
+ vc4_crtc_config_pv(crtc);
541
+
542
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
543
+
544
+ if (vc4_encoder->pre_crtc_enable)
545
+ vc4_encoder->pre_crtc_enable(encoder);
604546
605547 /* When feeding the transposer block the pixelvalve is unneeded and
606548 * should not be enabled.
607549 */
608
- if (!vc4_state->feed_txp)
609
- CRTC_WRITE(PV_V_CONTROL,
610
- CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
550
+ CRTC_WRITE(PV_V_CONTROL,
551
+ CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
552
+
553
+ if (vc4_encoder->post_crtc_enable)
554
+ vc4_encoder->post_crtc_enable(encoder);
611555 }
612556
613557 static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
....@@ -623,35 +567,46 @@
623567 return MODE_OK;
624568 }
625569
570
+void vc4_crtc_get_margins(struct drm_crtc_state *state,
571
+ unsigned int *left, unsigned int *right,
572
+ unsigned int *top, unsigned int *bottom)
573
+{
574
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
575
+ struct drm_connector_state *conn_state;
576
+ struct drm_connector *conn;
577
+ int i;
578
+
579
+ *left = vc4_state->margins.left;
580
+ *right = vc4_state->margins.right;
581
+ *top = vc4_state->margins.top;
582
+ *bottom = vc4_state->margins.bottom;
583
+
584
+ /* We have to interate over all new connector states because
585
+ * vc4_crtc_get_margins() might be called before
586
+ * vc4_crtc_atomic_check() which means margins info in vc4_crtc_state
587
+ * might be outdated.
588
+ */
589
+ for_each_new_connector_in_state(state->state, conn, conn_state, i) {
590
+ if (conn_state->crtc != state->crtc)
591
+ continue;
592
+
593
+ *left = conn_state->tv.margins.left;
594
+ *right = conn_state->tv.margins.right;
595
+ *top = conn_state->tv.margins.top;
596
+ *bottom = conn_state->tv.margins.bottom;
597
+ break;
598
+ }
599
+}
600
+
626601 static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
627602 struct drm_crtc_state *state)
628603 {
629604 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
630
- struct drm_device *dev = crtc->dev;
631
- struct vc4_dev *vc4 = to_vc4_dev(dev);
632
- struct drm_plane *plane;
633
- unsigned long flags;
634
- const struct drm_plane_state *plane_state;
635605 struct drm_connector *conn;
636606 struct drm_connector_state *conn_state;
637
- u32 dlist_count = 0;
638607 int ret, i;
639608
640
- /* The pixelvalve can only feed one encoder (and encoders are
641
- * 1:1 with connectors.)
642
- */
643
- if (hweight32(state->connector_mask) > 1)
644
- return -EINVAL;
645
-
646
- drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state)
647
- dlist_count += vc4_plane_dlist_size(plane_state);
648
-
649
- dlist_count++; /* Account for SCALER_CTL0_END. */
650
-
651
- spin_lock_irqsave(&vc4->hvs->mm_lock, flags);
652
- ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm,
653
- dlist_count);
654
- spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags);
609
+ ret = vc4_hvs_atomic_check(crtc, state);
655610 if (ret)
656611 return ret;
657612
....@@ -659,104 +614,14 @@
659614 if (conn_state->crtc != crtc)
660615 continue;
661616
662
- /* The writeback connector is implemented using the transposer
663
- * block which is directly taking its data from the HVS FIFO.
664
- */
665
- if (conn->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) {
666
- state->no_vblank = true;
667
- vc4_state->feed_txp = true;
668
- } else {
669
- state->no_vblank = false;
670
- vc4_state->feed_txp = false;
671
- }
672
-
617
+ vc4_state->margins.left = conn_state->tv.margins.left;
618
+ vc4_state->margins.right = conn_state->tv.margins.right;
619
+ vc4_state->margins.top = conn_state->tv.margins.top;
620
+ vc4_state->margins.bottom = conn_state->tv.margins.bottom;
673621 break;
674622 }
675623
676624 return 0;
677
-}
678
-
679
-static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
680
- struct drm_crtc_state *old_state)
681
-{
682
- struct drm_device *dev = crtc->dev;
683
- struct vc4_dev *vc4 = to_vc4_dev(dev);
684
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
685
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
686
- struct drm_plane *plane;
687
- struct vc4_plane_state *vc4_plane_state;
688
- bool debug_dump_regs = false;
689
- bool enable_bg_fill = false;
690
- u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
691
- u32 __iomem *dlist_next = dlist_start;
692
-
693
- if (debug_dump_regs) {
694
- DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
695
- vc4_hvs_dump_state(dev);
696
- }
697
-
698
- /* Copy all the active planes' dlist contents to the hardware dlist. */
699
- drm_atomic_crtc_for_each_plane(plane, crtc) {
700
- /* Is this the first active plane? */
701
- if (dlist_next == dlist_start) {
702
- /* We need to enable background fill when a plane
703
- * could be alpha blending from the background, i.e.
704
- * where no other plane is underneath. It suffices to
705
- * consider the first active plane here since we set
706
- * needs_bg_fill such that either the first plane
707
- * already needs it or all planes on top blend from
708
- * the first or a lower plane.
709
- */
710
- vc4_plane_state = to_vc4_plane_state(plane->state);
711
- enable_bg_fill = vc4_plane_state->needs_bg_fill;
712
- }
713
-
714
- dlist_next += vc4_plane_write_dlist(plane, dlist_next);
715
- }
716
-
717
- writel(SCALER_CTL0_END, dlist_next);
718
- dlist_next++;
719
-
720
- WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
721
-
722
- if (enable_bg_fill)
723
- /* This sets a black background color fill, as is the case
724
- * with other DRM drivers.
725
- */
726
- HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
727
- HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)) |
728
- SCALER_DISPBKGND_FILL);
729
-
730
- /* Only update DISPLIST if the CRTC was already running and is not
731
- * being disabled.
732
- * vc4_crtc_enable() takes care of updating the dlist just after
733
- * re-enabling VBLANK interrupts and before enabling the engine.
734
- * If the CRTC is being disabled, there's no point in updating this
735
- * information.
736
- */
737
- if (crtc->state->active && old_state->active)
738
- vc4_crtc_update_dlist(crtc);
739
-
740
- if (crtc->state->color_mgmt_changed) {
741
- u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel));
742
-
743
- if (crtc->state->gamma_lut) {
744
- vc4_crtc_update_gamma_lut(crtc);
745
- dispbkgndx |= SCALER_DISPBKGND_GAMMA;
746
- } else {
747
- /* Unsetting DISPBKGND_GAMMA skips the gamma lut step
748
- * in hardware, which is the same as a linear lut that
749
- * DRM expects us to use in absence of a user lut.
750
- */
751
- dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
752
- }
753
- HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), dispbkgndx);
754
- }
755
-
756
- if (debug_dump_regs) {
757
- DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
758
- vc4_hvs_dump_state(dev);
759
- }
760625 }
761626
762627 static int vc4_enable_vblank(struct drm_crtc *crtc)
....@@ -781,7 +646,7 @@
781646 struct drm_device *dev = crtc->dev;
782647 struct vc4_dev *vc4 = to_vc4_dev(dev);
783648 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
784
- u32 chan = vc4_crtc->channel;
649
+ u32 chan = vc4_state->assigned_channel;
785650 unsigned long flags;
786651
787652 spin_lock_irqsave(&dev->event_lock, flags);
....@@ -791,6 +656,14 @@
791656 drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
792657 vc4_crtc->event = NULL;
793658 drm_crtc_vblank_put(crtc);
659
+
660
+ /* Wait for the page flip to unmask the underrun to ensure that
661
+ * the display list was updated by the hardware. Before that
662
+ * happens, the HVS will be using the previous display list with
663
+ * the CRTC and encoder already reconfigured, leading to
664
+ * underruns. This can be seen when reconfiguring the CRTC.
665
+ */
666
+ vc4_hvs_unmask_underrun(dev, chan);
794667 }
795668 spin_unlock_irqrestore(&dev->event_lock, flags);
796669 }
....@@ -949,11 +822,11 @@
949822 return 0;
950823 }
951824
952
-static int vc4_page_flip(struct drm_crtc *crtc,
953
- struct drm_framebuffer *fb,
954
- struct drm_pending_vblank_event *event,
955
- uint32_t flags,
956
- struct drm_modeset_acquire_ctx *ctx)
825
+int vc4_page_flip(struct drm_crtc *crtc,
826
+ struct drm_framebuffer *fb,
827
+ struct drm_pending_vblank_event *event,
828
+ uint32_t flags,
829
+ struct drm_modeset_acquire_ctx *ctx)
957830 {
958831 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
959832 return vc4_async_page_flip(crtc, fb, event, flags);
....@@ -961,7 +834,7 @@
961834 return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
962835 }
963836
964
-static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
837
+struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
965838 {
966839 struct vc4_crtc_state *vc4_state, *old_vc4_state;
967840
....@@ -971,18 +844,20 @@
971844
972845 old_vc4_state = to_vc4_crtc_state(crtc->state);
973846 vc4_state->feed_txp = old_vc4_state->feed_txp;
847
+ vc4_state->margins = old_vc4_state->margins;
848
+ vc4_state->assigned_channel = old_vc4_state->assigned_channel;
974849
975850 __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
976851 return &vc4_state->base;
977852 }
978853
979
-static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
980
- struct drm_crtc_state *state)
854
+void vc4_crtc_destroy_state(struct drm_crtc *crtc,
855
+ struct drm_crtc_state *state)
981856 {
982857 struct vc4_dev *vc4 = to_vc4_dev(crtc->dev);
983858 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
984859
985
- if (vc4_state->mm.allocated) {
860
+ if (drm_mm_node_allocated(&vc4_state->mm)) {
986861 unsigned long flags;
987862
988863 spin_lock_irqsave(&vc4->hvs->mm_lock, flags);
....@@ -994,15 +869,21 @@
994869 drm_atomic_helper_crtc_destroy_state(crtc, state);
995870 }
996871
997
-static void
998
-vc4_crtc_reset(struct drm_crtc *crtc)
872
+void vc4_crtc_reset(struct drm_crtc *crtc)
999873 {
874
+ struct vc4_crtc_state *vc4_crtc_state;
875
+
1000876 if (crtc->state)
1001877 vc4_crtc_destroy_state(crtc, crtc->state);
1002878
1003
- crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL);
1004
- if (crtc->state)
1005
- crtc->state->crtc = crtc;
879
+ vc4_crtc_state = kzalloc(sizeof(*vc4_crtc_state), GFP_KERNEL);
880
+ if (!vc4_crtc_state) {
881
+ crtc->state = NULL;
882
+ return;
883
+ }
884
+
885
+ vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED;
886
+ __drm_atomic_helper_crtc_reset(crtc, &vc4_crtc_state->base);
1006887 }
1007888
1008889 static const struct drm_crtc_funcs vc4_crtc_funcs = {
....@@ -1018,45 +899,136 @@
1018899 .gamma_set = drm_atomic_helper_legacy_gamma_set,
1019900 .enable_vblank = vc4_enable_vblank,
1020901 .disable_vblank = vc4_disable_vblank,
902
+ .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
1021903 };
1022904
1023905 static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
1024
- .mode_set_nofb = vc4_crtc_mode_set_nofb,
1025906 .mode_valid = vc4_crtc_mode_valid,
1026907 .atomic_check = vc4_crtc_atomic_check,
1027
- .atomic_flush = vc4_crtc_atomic_flush,
908
+ .atomic_flush = vc4_hvs_atomic_flush,
1028909 .atomic_enable = vc4_crtc_atomic_enable,
1029910 .atomic_disable = vc4_crtc_atomic_disable,
911
+ .get_scanout_position = vc4_crtc_get_scanout_position,
1030912 };
1031913
1032
-static const struct vc4_crtc_data pv0_data = {
1033
- .hvs_channel = 0,
914
+static const struct vc4_pv_data bcm2835_pv0_data = {
915
+ .base = {
916
+ .hvs_available_channels = BIT(0),
917
+ .hvs_output = 0,
918
+ },
919
+ .debugfs_name = "crtc0_regs",
920
+ .fifo_depth = 64,
921
+ .pixels_per_clock = 1,
1034922 .encoder_types = {
1035923 [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
1036924 [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
1037925 },
1038926 };
1039927
1040
-static const struct vc4_crtc_data pv1_data = {
1041
- .hvs_channel = 2,
928
+static const struct vc4_pv_data bcm2835_pv1_data = {
929
+ .base = {
930
+ .hvs_available_channels = BIT(2),
931
+ .hvs_output = 2,
932
+ },
933
+ .debugfs_name = "crtc1_regs",
934
+ .fifo_depth = 64,
935
+ .pixels_per_clock = 1,
1042936 .encoder_types = {
1043937 [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
1044938 [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
1045939 },
1046940 };
1047941
1048
-static const struct vc4_crtc_data pv2_data = {
1049
- .hvs_channel = 1,
942
+static const struct vc4_pv_data bcm2835_pv2_data = {
943
+ .base = {
944
+ .hvs_available_channels = BIT(1),
945
+ .hvs_output = 1,
946
+ },
947
+ .debugfs_name = "crtc2_regs",
948
+ .fifo_depth = 64,
949
+ .pixels_per_clock = 1,
1050950 .encoder_types = {
1051
- [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI,
951
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0,
1052952 [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
1053953 },
1054954 };
1055955
956
+static const struct vc4_pv_data bcm2711_pv0_data = {
957
+ .base = {
958
+ .hvs_available_channels = BIT(0),
959
+ .hvs_output = 0,
960
+ },
961
+ .debugfs_name = "crtc0_regs",
962
+ .fifo_depth = 64,
963
+ .pixels_per_clock = 1,
964
+ .encoder_types = {
965
+ [0] = VC4_ENCODER_TYPE_DSI0,
966
+ [1] = VC4_ENCODER_TYPE_DPI,
967
+ },
968
+};
969
+
970
+static const struct vc4_pv_data bcm2711_pv1_data = {
971
+ .base = {
972
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
973
+ .hvs_output = 3,
974
+ },
975
+ .debugfs_name = "crtc1_regs",
976
+ .fifo_depth = 64,
977
+ .pixels_per_clock = 1,
978
+ .encoder_types = {
979
+ [0] = VC4_ENCODER_TYPE_DSI1,
980
+ [1] = VC4_ENCODER_TYPE_SMI,
981
+ },
982
+};
983
+
984
+static const struct vc4_pv_data bcm2711_pv2_data = {
985
+ .base = {
986
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
987
+ .hvs_output = 4,
988
+ },
989
+ .debugfs_name = "crtc2_regs",
990
+ .fifo_depth = 256,
991
+ .pixels_per_clock = 2,
992
+ .encoder_types = {
993
+ [0] = VC4_ENCODER_TYPE_HDMI0,
994
+ },
995
+};
996
+
997
+static const struct vc4_pv_data bcm2711_pv3_data = {
998
+ .base = {
999
+ .hvs_available_channels = BIT(1),
1000
+ .hvs_output = 1,
1001
+ },
1002
+ .debugfs_name = "crtc3_regs",
1003
+ .fifo_depth = 64,
1004
+ .pixels_per_clock = 1,
1005
+ .encoder_types = {
1006
+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
1007
+ },
1008
+};
1009
+
1010
+static const struct vc4_pv_data bcm2711_pv4_data = {
1011
+ .base = {
1012
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
1013
+ .hvs_output = 5,
1014
+ },
1015
+ .debugfs_name = "crtc4_regs",
1016
+ .fifo_depth = 64,
1017
+ .pixels_per_clock = 2,
1018
+ .encoder_types = {
1019
+ [0] = VC4_ENCODER_TYPE_HDMI1,
1020
+ },
1021
+};
1022
+
10561023 static const struct of_device_id vc4_crtc_dt_match[] = {
1057
- { .compatible = "brcm,bcm2835-pixelvalve0", .data = &pv0_data },
1058
- { .compatible = "brcm,bcm2835-pixelvalve1", .data = &pv1_data },
1059
- { .compatible = "brcm,bcm2835-pixelvalve2", .data = &pv2_data },
1024
+ { .compatible = "brcm,bcm2835-pixelvalve0", .data = &bcm2835_pv0_data },
1025
+ { .compatible = "brcm,bcm2835-pixelvalve1", .data = &bcm2835_pv1_data },
1026
+ { .compatible = "brcm,bcm2835-pixelvalve2", .data = &bcm2835_pv2_data },
1027
+ { .compatible = "brcm,bcm2711-pixelvalve0", .data = &bcm2711_pv0_data },
1028
+ { .compatible = "brcm,bcm2711-pixelvalve1", .data = &bcm2711_pv1_data },
1029
+ { .compatible = "brcm,bcm2711-pixelvalve2", .data = &bcm2711_pv2_data },
1030
+ { .compatible = "brcm,bcm2711-pixelvalve3", .data = &bcm2711_pv3_data },
1031
+ { .compatible = "brcm,bcm2711-pixelvalve4", .data = &bcm2711_pv4_data },
10601032 {}
10611033 };
10621034
....@@ -1064,23 +1036,19 @@
10641036 struct drm_crtc *crtc)
10651037 {
10661038 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
1067
- const struct vc4_crtc_data *crtc_data = vc4_crtc->data;
1068
- const enum vc4_encoder_type *encoder_types = crtc_data->encoder_types;
1039
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
1040
+ const enum vc4_encoder_type *encoder_types = pv_data->encoder_types;
10691041 struct drm_encoder *encoder;
10701042
10711043 drm_for_each_encoder(encoder, drm) {
10721044 struct vc4_encoder *vc4_encoder;
10731045 int i;
10741046
1075
- /* HVS FIFO2 can feed the TXP IP. */
1076
- if (crtc_data->hvs_channel == 2 &&
1077
- encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) {
1078
- encoder->possible_crtcs |= drm_crtc_mask(crtc);
1047
+ if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
10791048 continue;
1080
- }
10811049
10821050 vc4_encoder = to_vc4_encoder(encoder);
1083
- for (i = 0; i < ARRAY_SIZE(crtc_data->encoder_types); i++) {
1051
+ for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) {
10841052 if (vc4_encoder->type == encoder_types[i]) {
10851053 vc4_encoder->clock_select = i;
10861054 encoder->possible_crtcs |= drm_crtc_mask(crtc);
....@@ -1090,45 +1058,14 @@
10901058 }
10911059 }
10921060
1093
-static void
1094
-vc4_crtc_get_cob_allocation(struct vc4_crtc *vc4_crtc)
1061
+int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
1062
+ const struct drm_crtc_funcs *crtc_funcs,
1063
+ const struct drm_crtc_helper_funcs *crtc_helper_funcs)
10951064 {
1096
- struct drm_device *drm = vc4_crtc->base.dev;
10971065 struct vc4_dev *vc4 = to_vc4_dev(drm);
1098
- u32 dispbase = HVS_READ(SCALER_DISPBASEX(vc4_crtc->channel));
1099
- /* Top/base are supposed to be 4-pixel aligned, but the
1100
- * Raspberry Pi firmware fills the low bits (which are
1101
- * presumably ignored).
1102
- */
1103
- u32 top = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_TOP) & ~3;
1104
- u32 base = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_BASE) & ~3;
1105
-
1106
- vc4_crtc->cob_size = top - base + 4;
1107
-}
1108
-
1109
-static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
1110
-{
1111
- struct platform_device *pdev = to_platform_device(dev);
1112
- struct drm_device *drm = dev_get_drvdata(master);
1113
- struct vc4_crtc *vc4_crtc;
1114
- struct drm_crtc *crtc;
1115
- struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp;
1116
- const struct of_device_id *match;
1117
- int ret, i;
1118
-
1119
- vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
1120
- if (!vc4_crtc)
1121
- return -ENOMEM;
1122
- crtc = &vc4_crtc->base;
1123
-
1124
- match = of_match_device(vc4_crtc_dt_match, dev);
1125
- if (!match)
1126
- return -ENODEV;
1127
- vc4_crtc->data = match->data;
1128
-
1129
- vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
1130
- if (IS_ERR(vc4_crtc->regs))
1131
- return PTR_ERR(vc4_crtc->regs);
1066
+ struct drm_crtc *crtc = &vc4_crtc->base;
1067
+ struct drm_plane *primary_plane;
1068
+ unsigned int i;
11321069
11331070 /* For now, we create just the primary and the legacy cursor
11341071 * planes. We should be able to stack more planes on easily,
....@@ -1138,62 +1075,24 @@
11381075 */
11391076 primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
11401077 if (IS_ERR(primary_plane)) {
1141
- dev_err(dev, "failed to construct primary plane\n");
1142
- ret = PTR_ERR(primary_plane);
1143
- goto err;
1078
+ dev_err(drm->dev, "failed to construct primary plane\n");
1079
+ return PTR_ERR(primary_plane);
11441080 }
11451081
11461082 drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
1147
- &vc4_crtc_funcs, NULL);
1148
- drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
1149
- vc4_crtc->channel = vc4_crtc->data->hvs_channel;
1150
- drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
1151
- drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
1083
+ crtc_funcs, NULL);
1084
+ drm_crtc_helper_add(crtc, crtc_helper_funcs);
11521085
1153
- /* We support CTM, but only for one CRTC at a time. It's therefore
1154
- * implemented as private driver state in vc4_kms, not here.
1155
- */
1156
- drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
1086
+ if (!vc4->hvs->hvs5) {
1087
+ drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
11571088
1158
- /* Set up some arbitrary number of planes. We're not limited
1159
- * by a set number of physical registers, just the space in
1160
- * the HVS (16k) and how small an plane can be (28 bytes).
1161
- * However, each plane we set up takes up some memory, and
1162
- * increases the cost of looping over planes, which atomic
1163
- * modesetting does quite a bit. As a result, we pick a
1164
- * modest number of planes to expose, that should hopefully
1165
- * still cover any sane usecase.
1166
- */
1167
- for (i = 0; i < 8; i++) {
1168
- struct drm_plane *plane =
1169
- vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY);
1089
+ drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
11701090
1171
- if (IS_ERR(plane))
1172
- continue;
1173
-
1174
- plane->possible_crtcs = drm_crtc_mask(crtc);
1091
+ /* We support CTM, but only for one CRTC at a time. It's therefore
1092
+ * implemented as private driver state in vc4_kms, not here.
1093
+ */
1094
+ drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
11751095 }
1176
-
1177
- /* Set up the legacy cursor after overlay initialization,
1178
- * since we overlay planes on the CRTC in the order they were
1179
- * initialized.
1180
- */
1181
- cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
1182
- if (!IS_ERR(cursor_plane)) {
1183
- cursor_plane->possible_crtcs = drm_crtc_mask(crtc);
1184
- crtc->cursor = cursor_plane;
1185
- }
1186
-
1187
- vc4_crtc_get_cob_allocation(vc4_crtc);
1188
-
1189
- CRTC_WRITE(PV_INTEN, 0);
1190
- CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
1191
- ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
1192
- vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
1193
- if (ret)
1194
- goto err_destroy_planes;
1195
-
1196
- vc4_set_crtc_possible_masks(drm, crtc);
11971096
11981097 for (i = 0; i < crtc->gamma_size; i++) {
11991098 vc4_crtc->lut_r[i] = i;
....@@ -1201,7 +1100,57 @@
12011100 vc4_crtc->lut_b[i] = i;
12021101 }
12031102
1103
+ return 0;
1104
+}
1105
+
1106
+static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
1107
+{
1108
+ struct platform_device *pdev = to_platform_device(dev);
1109
+ struct drm_device *drm = dev_get_drvdata(master);
1110
+ const struct vc4_pv_data *pv_data;
1111
+ struct vc4_crtc *vc4_crtc;
1112
+ struct drm_crtc *crtc;
1113
+ struct drm_plane *destroy_plane, *temp;
1114
+ int ret;
1115
+
1116
+ vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
1117
+ if (!vc4_crtc)
1118
+ return -ENOMEM;
1119
+ crtc = &vc4_crtc->base;
1120
+
1121
+ pv_data = of_device_get_match_data(dev);
1122
+ if (!pv_data)
1123
+ return -ENODEV;
1124
+ vc4_crtc->data = &pv_data->base;
1125
+ vc4_crtc->pdev = pdev;
1126
+
1127
+ vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
1128
+ if (IS_ERR(vc4_crtc->regs))
1129
+ return PTR_ERR(vc4_crtc->regs);
1130
+
1131
+ vc4_crtc->regset.base = vc4_crtc->regs;
1132
+ vc4_crtc->regset.regs = crtc_regs;
1133
+ vc4_crtc->regset.nregs = ARRAY_SIZE(crtc_regs);
1134
+
1135
+ ret = vc4_crtc_init(drm, vc4_crtc,
1136
+ &vc4_crtc_funcs, &vc4_crtc_helper_funcs);
1137
+ if (ret)
1138
+ return ret;
1139
+ vc4_set_crtc_possible_masks(drm, crtc);
1140
+
1141
+ CRTC_WRITE(PV_INTEN, 0);
1142
+ CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
1143
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
1144
+ vc4_crtc_irq_handler,
1145
+ IRQF_SHARED,
1146
+ "vc4 crtc", vc4_crtc);
1147
+ if (ret)
1148
+ goto err_destroy_planes;
1149
+
12041150 platform_set_drvdata(pdev, vc4_crtc);
1151
+
1152
+ vc4_debugfs_add_regset32(drm, pv_data->debugfs_name,
1153
+ &vc4_crtc->regset);
12051154
12061155 return 0;
12071156
....@@ -1211,7 +1160,7 @@
12111160 if (destroy_plane->possible_crtcs == drm_crtc_mask(crtc))
12121161 destroy_plane->funcs->destroy(destroy_plane);
12131162 }
1214
-err:
1163
+
12151164 return ret;
12161165 }
12171166