1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2015 Broadcom |
4 | */ |
5 | |
6 | /** |
7 | * DOC: VC4 CRTC module |
8 | * |
9 | * In VC4, the Pixel Valve is what most closely corresponds to the |
10 | * DRM's concept of a CRTC. The PV generates video timings from the |
11 | * encoder's clock plus its configuration. It pulls scaled pixels from |
12 | * the HVS at that timing, and feeds it to the encoder. |
13 | * |
14 | * However, the DRM CRTC also collects the configuration of all the |
15 | * DRM planes attached to it. As a result, the CRTC is also |
16 | * responsible for writing the display list for the HVS channel that |
17 | * the CRTC will use. |
18 | * |
19 | * The 2835 has 3 different pixel valves. pv0 in the audio power |
20 | * domain feeds DSI0 or DPI, while pv1 feeds DS1 or SMI. pv2 in the |
21 | * image domain can feed either HDMI or the SDTV controller. The |
22 | * pixel valve chooses from the CPRMAN clocks (HSM for HDMI, VEC for |
23 | * SDTV, etc.) according to which output type is chosen in the mux. |
24 | * |
25 | * For power management, the pixel valve's registers are all clocked |
26 | * by the AXI clock, while the timings and FIFOs make use of the |
27 | * output-specific clock. Since the encoders also directly consume |
28 | * the CPRMAN clocks, and know what timings they need, they are the |
29 | * ones that set the clock. |
30 | */ |
31 | |
32 | #include <linux/clk.h> |
33 | #include <linux/component.h> |
34 | #include <linux/of.h> |
35 | #include <linux/platform_device.h> |
36 | #include <linux/pm_runtime.h> |
37 | |
38 | #include <drm/drm_atomic.h> |
39 | #include <drm/drm_atomic_helper.h> |
40 | #include <drm/drm_atomic_uapi.h> |
41 | #include <drm/drm_fb_dma_helper.h> |
42 | #include <drm/drm_framebuffer.h> |
43 | #include <drm/drm_drv.h> |
44 | #include <drm/drm_print.h> |
45 | #include <drm/drm_probe_helper.h> |
46 | #include <drm/drm_vblank.h> |
47 | |
48 | #include "vc4_drv.h" |
49 | #include "vc4_hdmi.h" |
50 | #include "vc4_regs.h" |
51 | |
52 | #define HVS_FIFO_LATENCY_PIX 6 |
53 | |
54 | #define CRTC_WRITE(offset, val) \ |
55 | do { \ |
56 | kunit_fail_current_test("Accessing a register in a unit test!\n"); \ |
57 | writel(val, vc4_crtc->regs + (offset)); \ |
58 | } while (0) |
59 | |
60 | #define CRTC_READ(offset) \ |
61 | ({ \ |
62 | kunit_fail_current_test("Accessing a register in a unit test!\n"); \ |
63 | readl(vc4_crtc->regs + (offset)); \ |
64 | }) |
65 | |
66 | static const struct debugfs_reg32 crtc_regs[] = { |
67 | VC4_REG32(PV_CONTROL), |
68 | VC4_REG32(PV_V_CONTROL), |
69 | VC4_REG32(PV_VSYNCD_EVEN), |
70 | VC4_REG32(PV_HORZA), |
71 | VC4_REG32(PV_HORZB), |
72 | VC4_REG32(PV_VERTA), |
73 | VC4_REG32(PV_VERTB), |
74 | VC4_REG32(PV_VERTA_EVEN), |
75 | VC4_REG32(PV_VERTB_EVEN), |
76 | VC4_REG32(PV_INTEN), |
77 | VC4_REG32(PV_INTSTAT), |
78 | VC4_REG32(PV_STAT), |
79 | VC4_REG32(PV_HACT_ACT), |
80 | }; |
81 | |
82 | static unsigned int |
83 | vc4_crtc_get_cob_allocation(struct vc4_dev *vc4, unsigned int channel) |
84 | { |
85 | struct vc4_hvs *hvs = vc4->hvs; |
86 | u32 dispbase = HVS_READ(SCALER_DISPBASEX(channel)); |
87 | /* Top/base are supposed to be 4-pixel aligned, but the |
88 | * Raspberry Pi firmware fills the low bits (which are |
89 | * presumably ignored). |
90 | */ |
91 | u32 top = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_TOP) & ~3; |
92 | u32 base = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_BASE) & ~3; |
93 | |
94 | return top - base + 4; |
95 | } |
96 | |
97 | static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc, |
98 | bool in_vblank_irq, |
99 | int *vpos, int *hpos, |
100 | ktime_t *stime, ktime_t *etime, |
101 | const struct drm_display_mode *mode) |
102 | { |
103 | struct drm_device *dev = crtc->dev; |
104 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
105 | struct vc4_hvs *hvs = vc4->hvs; |
106 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
107 | struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); |
108 | unsigned int cob_size; |
109 | u32 val; |
110 | int fifo_lines; |
111 | int vblank_lines; |
112 | bool ret = false; |
113 | |
114 | /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ |
115 | |
116 | /* Get optional system timestamp before query. */ |
117 | if (stime) |
118 | *stime = ktime_get(); |
119 | |
120 | /* |
121 | * Read vertical scanline which is currently composed for our |
122 | * pixelvalve by the HVS, and also the scaler status. |
123 | */ |
124 | val = HVS_READ(SCALER_DISPSTATX(vc4_crtc_state->assigned_channel)); |
125 | |
126 | /* Get optional system timestamp after query. */ |
127 | if (etime) |
128 | *etime = ktime_get(); |
129 | |
130 | /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ |
131 | |
132 | /* Vertical position of hvs composed scanline. */ |
133 | *vpos = VC4_GET_FIELD(val, SCALER_DISPSTATX_LINE); |
134 | *hpos = 0; |
135 | |
136 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { |
137 | *vpos /= 2; |
138 | |
139 | /* Use hpos to correct for field offset in interlaced mode. */ |
140 | if (vc4_hvs_get_fifo_frame_count(hvs, fifo: vc4_crtc_state->assigned_channel) % 2) |
141 | *hpos += mode->crtc_htotal / 2; |
142 | } |
143 | |
144 | cob_size = vc4_crtc_get_cob_allocation(vc4, channel: vc4_crtc_state->assigned_channel); |
145 | /* This is the offset we need for translating hvs -> pv scanout pos. */ |
146 | fifo_lines = cob_size / mode->crtc_hdisplay; |
147 | |
148 | if (fifo_lines > 0) |
149 | ret = true; |
150 | |
151 | /* HVS more than fifo_lines into frame for compositing? */ |
152 | if (*vpos > fifo_lines) { |
153 | /* |
154 | * We are in active scanout and can get some meaningful results |
155 | * from HVS. The actual PV scanout can not trail behind more |
156 | * than fifo_lines as that is the fifo's capacity. Assume that |
157 | * in active scanout the HVS and PV work in lockstep wrt. HVS |
158 | * refilling the fifo and PV consuming from the fifo, ie. |
159 | * whenever the PV consumes and frees up a scanline in the |
160 | * fifo, the HVS will immediately refill it, therefore |
161 | * incrementing vpos. Therefore we choose HVS read position - |
162 | * fifo size in scanlines as a estimate of the real scanout |
163 | * position of the PV. |
164 | */ |
165 | *vpos -= fifo_lines + 1; |
166 | |
167 | return ret; |
168 | } |
169 | |
170 | /* |
171 | * Less: This happens when we are in vblank and the HVS, after getting |
172 | * the VSTART restart signal from the PV, just started refilling its |
173 | * fifo with new lines from the top-most lines of the new framebuffers. |
174 | * The PV does not scan out in vblank, so does not remove lines from |
175 | * the fifo, so the fifo will be full quickly and the HVS has to pause. |
176 | * We can't get meaningful readings wrt. scanline position of the PV |
177 | * and need to make things up in a approximative but consistent way. |
178 | */ |
179 | vblank_lines = mode->vtotal - mode->vdisplay; |
180 | |
181 | if (in_vblank_irq) { |
182 | /* |
183 | * Assume the irq handler got called close to first |
184 | * line of vblank, so PV has about a full vblank |
185 | * scanlines to go, and as a base timestamp use the |
186 | * one taken at entry into vblank irq handler, so it |
187 | * is not affected by random delays due to lock |
188 | * contention on event_lock or vblank_time lock in |
189 | * the core. |
190 | */ |
191 | *vpos = -vblank_lines; |
192 | |
193 | if (stime) |
194 | *stime = vc4_crtc->t_vblank; |
195 | if (etime) |
196 | *etime = vc4_crtc->t_vblank; |
197 | |
198 | /* |
199 | * If the HVS fifo is not yet full then we know for certain |
200 | * we are at the very beginning of vblank, as the hvs just |
201 | * started refilling, and the stime and etime timestamps |
202 | * truly correspond to start of vblank. |
203 | * |
204 | * Unfortunately there's no way to report this to upper levels |
205 | * and make it more useful. |
206 | */ |
207 | } else { |
208 | /* |
209 | * No clue where we are inside vblank. Return a vpos of zero, |
210 | * which will cause calling code to just return the etime |
211 | * timestamp uncorrected. At least this is no worse than the |
212 | * standard fallback. |
213 | */ |
214 | *vpos = 0; |
215 | } |
216 | |
217 | return ret; |
218 | } |
219 | |
220 | static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format) |
221 | { |
222 | const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(crtc: vc4_crtc); |
223 | const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(crtc: vc4_crtc); |
224 | struct vc4_dev *vc4 = to_vc4_dev(vc4_crtc->base.dev); |
225 | u32 fifo_len_bytes = pv_data->fifo_depth; |
226 | |
227 | /* |
228 | * Pixels are pulled from the HVS if the number of bytes is |
229 | * lower than the FIFO full level. |
230 | * |
231 | * The latency of the pixel fetch mechanism is 6 pixels, so we |
232 | * need to convert those 6 pixels in bytes, depending on the |
233 | * format, and then subtract that from the length of the FIFO |
234 | * to make sure we never end up in a situation where the FIFO |
235 | * is full. |
236 | */ |
237 | switch (format) { |
238 | case PV_CONTROL_FORMAT_DSIV_16: |
239 | case PV_CONTROL_FORMAT_DSIC_16: |
240 | return fifo_len_bytes - 2 * HVS_FIFO_LATENCY_PIX; |
241 | case PV_CONTROL_FORMAT_DSIV_18: |
242 | return fifo_len_bytes - 14; |
243 | case PV_CONTROL_FORMAT_24: |
244 | case PV_CONTROL_FORMAT_DSIV_24: |
245 | default: |
246 | /* |
247 | * For some reason, the pixelvalve4 doesn't work with |
248 | * the usual formula and will only work with 32. |
249 | */ |
250 | if (crtc_data->hvs_output == 5) |
251 | return 32; |
252 | |
253 | /* |
254 | * It looks like in some situations, we will overflow |
255 | * the PixelValve FIFO (with the bit 10 of PV stat being |
256 | * set) and stall the HVS / PV, eventually resulting in |
257 | * a page flip timeout. |
258 | * |
259 | * Displaying the video overlay during a playback with |
260 | * Kodi on an RPi3 seems to be a great solution with a |
261 | * failure rate around 50%. |
262 | * |
263 | * Removing 1 from the FIFO full level however |
264 | * seems to completely remove that issue. |
265 | */ |
266 | if (!vc4->is_vc5) |
267 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1; |
268 | |
269 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX; |
270 | } |
271 | } |
272 | |
273 | static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc, |
274 | u32 format) |
275 | { |
276 | u32 level = vc4_get_fifo_full_level(vc4_crtc, format); |
277 | u32 ret = 0; |
278 | |
279 | ret |= VC4_SET_FIELD((level >> 6), |
280 | PV5_CONTROL_FIFO_LEVEL_HIGH); |
281 | |
282 | return ret | VC4_SET_FIELD(level & 0x3f, |
283 | PV_CONTROL_FIFO_LEVEL); |
284 | } |
285 | |
286 | /* |
287 | * Returns the encoder attached to the CRTC. |
288 | * |
289 | * VC4 can only scan out to one encoder at a time, while the DRM core |
290 | * allows drivers to push pixels to more than one encoder from the |
291 | * same CRTC. |
292 | */ |
293 | struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, |
294 | struct drm_crtc_state *state) |
295 | { |
296 | struct drm_encoder *encoder; |
297 | |
298 | WARN_ON(hweight32(state->encoder_mask) > 1); |
299 | |
300 | drm_for_each_encoder_mask(encoder, crtc->dev, state->encoder_mask) |
301 | return encoder; |
302 | |
303 | return NULL; |
304 | } |
305 | |
306 | static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc) |
307 | { |
308 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
309 | struct drm_device *dev = crtc->dev; |
310 | int idx; |
311 | |
312 | if (!drm_dev_enter(dev, idx: &idx)) |
313 | return; |
314 | |
315 | /* The PV needs to be disabled before it can be flushed */ |
316 | CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN); |
317 | CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR); |
318 | |
319 | drm_dev_exit(idx); |
320 | } |
321 | |
322 | static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encoder, |
323 | struct drm_atomic_state *state) |
324 | { |
325 | struct drm_device *dev = crtc->dev; |
326 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
327 | struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); |
328 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
329 | const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(crtc: vc4_crtc); |
330 | struct drm_crtc_state *crtc_state = crtc->state; |
331 | struct drm_display_mode *mode = &crtc_state->adjusted_mode; |
332 | bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; |
333 | bool is_hdmi = vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0 || |
334 | vc4_encoder->type == VC4_ENCODER_TYPE_HDMI1; |
335 | u32 pixel_rep = ((mode->flags & DRM_MODE_FLAG_DBLCLK) && !is_hdmi) ? 2 : 1; |
336 | bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || |
337 | vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); |
338 | bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1; |
339 | bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC; |
340 | u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; |
341 | u8 ppc = pv_data->pixels_per_clock; |
342 | |
343 | u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end; |
344 | u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start; |
345 | u16 vert_fp = mode->crtc_vsync_start - mode->crtc_vdisplay; |
346 | |
347 | bool debug_dump_regs = false; |
348 | int idx; |
349 | |
350 | if (!drm_dev_enter(dev, idx: &idx)) |
351 | return; |
352 | |
353 | if (debug_dump_regs) { |
354 | struct drm_printer p = drm_info_printer(dev: &vc4_crtc->pdev->dev); |
355 | dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs before:\n" , |
356 | drm_crtc_index(crtc)); |
357 | drm_print_regset32(p: &p, regset: &vc4_crtc->regset); |
358 | } |
359 | |
360 | vc4_crtc_pixelvalve_reset(crtc); |
361 | |
362 | CRTC_WRITE(PV_HORZA, |
363 | VC4_SET_FIELD((mode->htotal - mode->hsync_end) * pixel_rep / ppc, |
364 | PV_HORZA_HBP) | |
365 | VC4_SET_FIELD((mode->hsync_end - mode->hsync_start) * pixel_rep / ppc, |
366 | PV_HORZA_HSYNC)); |
367 | |
368 | CRTC_WRITE(PV_HORZB, |
369 | VC4_SET_FIELD((mode->hsync_start - mode->hdisplay) * pixel_rep / ppc, |
370 | PV_HORZB_HFP) | |
371 | VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc, |
372 | PV_HORZB_HACTIVE)); |
373 | |
374 | if (interlace) { |
375 | bool odd_field_first = false; |
376 | u32 field_delay = mode->htotal * pixel_rep / (2 * ppc); |
377 | u16 vert_bp_even = vert_bp; |
378 | u16 vert_fp_even = vert_fp; |
379 | |
380 | if (is_vec) { |
381 | /* VEC (composite output) */ |
382 | ++field_delay; |
383 | if (mode->htotal == 858) { |
384 | /* 525-line mode (NTSC or PAL-M) */ |
385 | odd_field_first = true; |
386 | } |
387 | } |
388 | |
389 | if (odd_field_first) |
390 | ++vert_fp_even; |
391 | else |
392 | ++vert_bp; |
393 | |
394 | CRTC_WRITE(PV_VERTA_EVEN, |
395 | VC4_SET_FIELD(vert_bp_even, PV_VERTA_VBP) | |
396 | VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC)); |
397 | CRTC_WRITE(PV_VERTB_EVEN, |
398 | VC4_SET_FIELD(vert_fp_even, PV_VERTB_VFP) | |
399 | VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE)); |
400 | |
401 | /* We set up first field even mode for HDMI and VEC's PAL. |
402 | * For NTSC, we need first field odd. |
403 | */ |
404 | CRTC_WRITE(PV_V_CONTROL, |
405 | PV_VCONTROL_CONTINUOUS | |
406 | (is_dsi ? PV_VCONTROL_DSI : 0) | |
407 | PV_VCONTROL_INTERLACE | |
408 | (odd_field_first |
409 | ? PV_VCONTROL_ODD_FIRST |
410 | : VC4_SET_FIELD(field_delay, |
411 | PV_VCONTROL_ODD_DELAY))); |
412 | CRTC_WRITE(PV_VSYNCD_EVEN, |
413 | (odd_field_first ? field_delay : 0)); |
414 | } else { |
415 | CRTC_WRITE(PV_V_CONTROL, |
416 | PV_VCONTROL_CONTINUOUS | |
417 | (is_dsi ? PV_VCONTROL_DSI : 0)); |
418 | CRTC_WRITE(PV_VSYNCD_EVEN, 0); |
419 | } |
420 | |
421 | CRTC_WRITE(PV_VERTA, |
422 | VC4_SET_FIELD(vert_bp, PV_VERTA_VBP) | |
423 | VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC)); |
424 | CRTC_WRITE(PV_VERTB, |
425 | VC4_SET_FIELD(vert_fp, PV_VERTB_VFP) | |
426 | VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE)); |
427 | |
428 | if (is_dsi) |
429 | CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); |
430 | |
431 | if (vc4->is_vc5) |
432 | CRTC_WRITE(PV_MUX_CFG, |
433 | VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP, |
434 | PV_MUX_CFG_RGB_PIXEL_MUX_MODE)); |
435 | |
436 | CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | |
437 | vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) | |
438 | VC4_SET_FIELD(format, PV_CONTROL_FORMAT) | |
439 | VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) | |
440 | PV_CONTROL_CLR_AT_START | |
441 | PV_CONTROL_TRIGGER_UNDERFLOW | |
442 | PV_CONTROL_WAIT_HSTART | |
443 | VC4_SET_FIELD(vc4_encoder->clock_select, |
444 | PV_CONTROL_CLK_SELECT)); |
445 | |
446 | if (debug_dump_regs) { |
447 | struct drm_printer p = drm_info_printer(dev: &vc4_crtc->pdev->dev); |
448 | dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs after:\n" , |
449 | drm_crtc_index(crtc)); |
450 | drm_print_regset32(p: &p, regset: &vc4_crtc->regset); |
451 | } |
452 | |
453 | drm_dev_exit(idx); |
454 | } |
455 | |
456 | static void require_hvs_enabled(struct drm_device *dev) |
457 | { |
458 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
459 | struct vc4_hvs *hvs = vc4->hvs; |
460 | |
461 | WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) != |
462 | SCALER_DISPCTRL_ENABLE); |
463 | } |
464 | |
465 | static int vc4_crtc_disable(struct drm_crtc *crtc, |
466 | struct drm_encoder *encoder, |
467 | struct drm_atomic_state *state, |
468 | unsigned int channel) |
469 | { |
470 | struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); |
471 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
472 | struct drm_device *dev = crtc->dev; |
473 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
474 | int idx, ret; |
475 | |
476 | if (!drm_dev_enter(dev, idx: &idx)) |
477 | return -ENODEV; |
478 | |
479 | CRTC_WRITE(PV_V_CONTROL, |
480 | CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN); |
481 | ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1); |
482 | WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n" ); |
483 | |
484 | /* |
485 | * This delay is needed to avoid to get a pixel stuck in an |
486 | * unflushable FIFO between the pixelvalve and the HDMI |
487 | * controllers on the BCM2711. |
488 | * |
489 | * Timing is fairly sensitive here, so mdelay is the safest |
490 | * approach. |
491 | * |
492 | * If it was to be reworked, the stuck pixel happens on a |
493 | * BCM2711 when changing mode with a good probability, so a |
494 | * script that changes mode on a regular basis should trigger |
495 | * the bug after less than 10 attempts. It manifests itself with |
496 | * every pixels being shifted by one to the right, and thus the |
497 | * last pixel of a line actually being displayed as the first |
498 | * pixel on the next line. |
499 | */ |
500 | mdelay(20); |
501 | |
502 | if (vc4_encoder && vc4_encoder->post_crtc_disable) |
503 | vc4_encoder->post_crtc_disable(encoder, state); |
504 | |
505 | vc4_crtc_pixelvalve_reset(crtc); |
506 | vc4_hvs_stop_channel(hvs: vc4->hvs, output: channel); |
507 | |
508 | if (vc4_encoder && vc4_encoder->post_crtc_powerdown) |
509 | vc4_encoder->post_crtc_powerdown(encoder, state); |
510 | |
511 | drm_dev_exit(idx); |
512 | |
513 | return 0; |
514 | } |
515 | |
516 | int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) |
517 | { |
518 | struct drm_device *drm = crtc->dev; |
519 | struct vc4_dev *vc4 = to_vc4_dev(drm); |
520 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
521 | enum vc4_encoder_type encoder_type; |
522 | const struct vc4_pv_data *pv_data; |
523 | struct drm_encoder *encoder; |
524 | struct vc4_hdmi *vc4_hdmi; |
525 | unsigned encoder_sel; |
526 | int channel; |
527 | int ret; |
528 | |
529 | if (!(of_device_is_compatible(device: vc4_crtc->pdev->dev.of_node, |
530 | "brcm,bcm2711-pixelvalve2" ) || |
531 | of_device_is_compatible(device: vc4_crtc->pdev->dev.of_node, |
532 | "brcm,bcm2711-pixelvalve4" ))) |
533 | return 0; |
534 | |
535 | if (!(CRTC_READ(PV_CONTROL) & PV_CONTROL_EN)) |
536 | return 0; |
537 | |
538 | if (!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN)) |
539 | return 0; |
540 | |
541 | channel = vc4_hvs_get_fifo_from_output(hvs: vc4->hvs, output: vc4_crtc->data->hvs_output); |
542 | if (channel < 0) |
543 | return 0; |
544 | |
545 | encoder_sel = VC4_GET_FIELD(CRTC_READ(PV_CONTROL), PV_CONTROL_CLK_SELECT); |
546 | if (WARN_ON(encoder_sel != 0)) |
547 | return 0; |
548 | |
549 | pv_data = vc4_crtc_to_vc4_pv_data(crtc: vc4_crtc); |
550 | encoder_type = pv_data->encoder_types[encoder_sel]; |
551 | encoder = vc4_find_encoder_by_type(drm, type: encoder_type); |
552 | if (WARN_ON(!encoder)) |
553 | return 0; |
554 | |
555 | vc4_hdmi = encoder_to_vc4_hdmi(encoder); |
556 | ret = pm_runtime_resume_and_get(dev: &vc4_hdmi->pdev->dev); |
557 | if (ret) |
558 | return ret; |
559 | |
560 | ret = vc4_crtc_disable(crtc, encoder, NULL, channel); |
561 | if (ret) |
562 | return ret; |
563 | |
564 | /* |
565 | * post_crtc_powerdown will have called pm_runtime_put, so we |
566 | * don't need it here otherwise we'll get the reference counting |
567 | * wrong. |
568 | */ |
569 | |
570 | return 0; |
571 | } |
572 | |
573 | void vc4_crtc_send_vblank(struct drm_crtc *crtc) |
574 | { |
575 | struct drm_device *dev = crtc->dev; |
576 | unsigned long flags; |
577 | |
578 | if (!crtc->state || !crtc->state->event) |
579 | return; |
580 | |
581 | spin_lock_irqsave(&dev->event_lock, flags); |
582 | drm_crtc_send_vblank_event(crtc, e: crtc->state->event); |
583 | crtc->state->event = NULL; |
584 | spin_unlock_irqrestore(lock: &dev->event_lock, flags); |
585 | } |
586 | |
587 | static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, |
588 | struct drm_atomic_state *state) |
589 | { |
590 | struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, |
591 | crtc); |
592 | struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state); |
593 | struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state: old_state); |
594 | struct drm_device *dev = crtc->dev; |
595 | |
596 | drm_dbg(dev, "Disabling CRTC %s (%u) connected to Encoder %s (%u)" , |
597 | crtc->name, crtc->base.id, encoder->name, encoder->base.id); |
598 | |
599 | require_hvs_enabled(dev); |
600 | |
601 | /* Disable vblank irq handling before crtc is disabled. */ |
602 | drm_crtc_vblank_off(crtc); |
603 | |
604 | vc4_crtc_disable(crtc, encoder, state, channel: old_vc4_state->assigned_channel); |
605 | |
606 | /* |
607 | * Make sure we issue a vblank event after disabling the CRTC if |
608 | * someone was waiting it. |
609 | */ |
610 | vc4_crtc_send_vblank(crtc); |
611 | } |
612 | |
613 | static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, |
614 | struct drm_atomic_state *state) |
615 | { |
616 | struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, |
617 | crtc); |
618 | struct drm_device *dev = crtc->dev; |
619 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
620 | struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state: new_state); |
621 | struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); |
622 | int idx; |
623 | |
624 | drm_dbg(dev, "Enabling CRTC %s (%u) connected to Encoder %s (%u)" , |
625 | crtc->name, crtc->base.id, encoder->name, encoder->base.id); |
626 | |
627 | if (!drm_dev_enter(dev, idx: &idx)) |
628 | return; |
629 | |
630 | require_hvs_enabled(dev); |
631 | |
632 | /* Enable vblank irq handling before crtc is started otherwise |
633 | * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist(). |
634 | */ |
635 | drm_crtc_vblank_on(crtc); |
636 | |
637 | vc4_hvs_atomic_enable(crtc, state); |
638 | |
639 | if (vc4_encoder->pre_crtc_configure) |
640 | vc4_encoder->pre_crtc_configure(encoder, state); |
641 | |
642 | vc4_crtc_config_pv(crtc, encoder, state); |
643 | |
644 | CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN); |
645 | |
646 | if (vc4_encoder->pre_crtc_enable) |
647 | vc4_encoder->pre_crtc_enable(encoder, state); |
648 | |
649 | /* When feeding the transposer block the pixelvalve is unneeded and |
650 | * should not be enabled. |
651 | */ |
652 | CRTC_WRITE(PV_V_CONTROL, |
653 | CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN); |
654 | |
655 | if (vc4_encoder->post_crtc_enable) |
656 | vc4_encoder->post_crtc_enable(encoder, state); |
657 | |
658 | drm_dev_exit(idx); |
659 | } |
660 | |
661 | static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc, |
662 | const struct drm_display_mode *mode) |
663 | { |
664 | /* Do not allow doublescan modes from user space */ |
665 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { |
666 | DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n" , |
667 | crtc->base.id); |
668 | return MODE_NO_DBLESCAN; |
669 | } |
670 | |
671 | return MODE_OK; |
672 | } |
673 | |
674 | void vc4_crtc_get_margins(struct drm_crtc_state *state, |
675 | unsigned int *left, unsigned int *right, |
676 | unsigned int *top, unsigned int *bottom) |
677 | { |
678 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); |
679 | struct drm_connector_state *conn_state; |
680 | struct drm_connector *conn; |
681 | int i; |
682 | |
683 | *left = vc4_state->margins.left; |
684 | *right = vc4_state->margins.right; |
685 | *top = vc4_state->margins.top; |
686 | *bottom = vc4_state->margins.bottom; |
687 | |
688 | /* We have to interate over all new connector states because |
689 | * vc4_crtc_get_margins() might be called before |
690 | * vc4_crtc_atomic_check() which means margins info in vc4_crtc_state |
691 | * might be outdated. |
692 | */ |
693 | for_each_new_connector_in_state(state->state, conn, conn_state, i) { |
694 | if (conn_state->crtc != state->crtc) |
695 | continue; |
696 | |
697 | *left = conn_state->tv.margins.left; |
698 | *right = conn_state->tv.margins.right; |
699 | *top = conn_state->tv.margins.top; |
700 | *bottom = conn_state->tv.margins.bottom; |
701 | break; |
702 | } |
703 | } |
704 | |
705 | int vc4_crtc_atomic_check(struct drm_crtc *crtc, |
706 | struct drm_atomic_state *state) |
707 | { |
708 | struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, |
709 | crtc); |
710 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); |
711 | struct drm_connector *conn; |
712 | struct drm_connector_state *conn_state; |
713 | struct drm_encoder *encoder; |
714 | int ret, i; |
715 | |
716 | ret = vc4_hvs_atomic_check(crtc, state); |
717 | if (ret) |
718 | return ret; |
719 | |
720 | encoder = vc4_get_crtc_encoder(crtc, state: crtc_state); |
721 | if (encoder) { |
722 | const struct drm_display_mode *mode = &crtc_state->adjusted_mode; |
723 | struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); |
724 | |
725 | if (vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0) { |
726 | vc4_state->hvs_load = max(mode->clock * mode->hdisplay / mode->htotal + 8000, |
727 | mode->clock * 9 / 10) * 1000; |
728 | } else { |
729 | vc4_state->hvs_load = mode->clock * 1000; |
730 | } |
731 | } |
732 | |
733 | for_each_new_connector_in_state(state, conn, conn_state, |
734 | i) { |
735 | if (conn_state->crtc != crtc) |
736 | continue; |
737 | |
738 | vc4_state->margins.left = conn_state->tv.margins.left; |
739 | vc4_state->margins.right = conn_state->tv.margins.right; |
740 | vc4_state->margins.top = conn_state->tv.margins.top; |
741 | vc4_state->margins.bottom = conn_state->tv.margins.bottom; |
742 | break; |
743 | } |
744 | |
745 | return 0; |
746 | } |
747 | |
748 | static int vc4_enable_vblank(struct drm_crtc *crtc) |
749 | { |
750 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
751 | struct drm_device *dev = crtc->dev; |
752 | int idx; |
753 | |
754 | if (!drm_dev_enter(dev, idx: &idx)) |
755 | return -ENODEV; |
756 | |
757 | CRTC_WRITE(PV_INTEN, PV_INT_VFP_START); |
758 | |
759 | drm_dev_exit(idx); |
760 | |
761 | return 0; |
762 | } |
763 | |
764 | static void vc4_disable_vblank(struct drm_crtc *crtc) |
765 | { |
766 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
767 | struct drm_device *dev = crtc->dev; |
768 | int idx; |
769 | |
770 | if (!drm_dev_enter(dev, idx: &idx)) |
771 | return; |
772 | |
773 | CRTC_WRITE(PV_INTEN, 0); |
774 | |
775 | drm_dev_exit(idx); |
776 | } |
777 | |
778 | static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) |
779 | { |
780 | struct drm_crtc *crtc = &vc4_crtc->base; |
781 | struct drm_device *dev = crtc->dev; |
782 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
783 | struct vc4_hvs *hvs = vc4->hvs; |
784 | u32 chan = vc4_crtc->current_hvs_channel; |
785 | unsigned long flags; |
786 | |
787 | spin_lock_irqsave(&dev->event_lock, flags); |
788 | spin_lock(lock: &vc4_crtc->irq_lock); |
789 | if (vc4_crtc->event && |
790 | (vc4_crtc->current_dlist == HVS_READ(SCALER_DISPLACTX(chan)) || |
791 | vc4_crtc->feeds_txp)) { |
792 | drm_crtc_send_vblank_event(crtc, e: vc4_crtc->event); |
793 | vc4_crtc->event = NULL; |
794 | drm_crtc_vblank_put(crtc); |
795 | |
796 | /* Wait for the page flip to unmask the underrun to ensure that |
797 | * the display list was updated by the hardware. Before that |
798 | * happens, the HVS will be using the previous display list with |
799 | * the CRTC and encoder already reconfigured, leading to |
800 | * underruns. This can be seen when reconfiguring the CRTC. |
801 | */ |
802 | vc4_hvs_unmask_underrun(hvs, channel: chan); |
803 | } |
804 | spin_unlock(lock: &vc4_crtc->irq_lock); |
805 | spin_unlock_irqrestore(lock: &dev->event_lock, flags); |
806 | } |
807 | |
808 | void vc4_crtc_handle_vblank(struct vc4_crtc *crtc) |
809 | { |
810 | crtc->t_vblank = ktime_get(); |
811 | drm_crtc_handle_vblank(crtc: &crtc->base); |
812 | vc4_crtc_handle_page_flip(vc4_crtc: crtc); |
813 | } |
814 | |
815 | static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) |
816 | { |
817 | struct vc4_crtc *vc4_crtc = data; |
818 | u32 stat = CRTC_READ(PV_INTSTAT); |
819 | irqreturn_t ret = IRQ_NONE; |
820 | |
821 | if (stat & PV_INT_VFP_START) { |
822 | CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); |
823 | vc4_crtc_handle_vblank(crtc: vc4_crtc); |
824 | ret = IRQ_HANDLED; |
825 | } |
826 | |
827 | return ret; |
828 | } |
829 | |
830 | struct vc4_async_flip_state { |
831 | struct drm_crtc *crtc; |
832 | struct drm_framebuffer *fb; |
833 | struct drm_framebuffer *old_fb; |
834 | struct drm_pending_vblank_event *event; |
835 | |
836 | union { |
837 | struct dma_fence_cb fence; |
838 | struct vc4_seqno_cb seqno; |
839 | } cb; |
840 | }; |
841 | |
842 | /* Called when the V3D execution for the BO being flipped to is done, so that |
843 | * we can actually update the plane's address to point to it. |
844 | */ |
845 | static void |
846 | vc4_async_page_flip_complete(struct vc4_async_flip_state *flip_state) |
847 | { |
848 | struct drm_crtc *crtc = flip_state->crtc; |
849 | struct drm_device *dev = crtc->dev; |
850 | struct drm_plane *plane = crtc->primary; |
851 | |
852 | vc4_plane_async_set_fb(plane, fb: flip_state->fb); |
853 | if (flip_state->event) { |
854 | unsigned long flags; |
855 | |
856 | spin_lock_irqsave(&dev->event_lock, flags); |
857 | drm_crtc_send_vblank_event(crtc, e: flip_state->event); |
858 | spin_unlock_irqrestore(lock: &dev->event_lock, flags); |
859 | } |
860 | |
861 | drm_crtc_vblank_put(crtc); |
862 | drm_framebuffer_put(fb: flip_state->fb); |
863 | |
864 | if (flip_state->old_fb) |
865 | drm_framebuffer_put(fb: flip_state->old_fb); |
866 | |
867 | kfree(objp: flip_state); |
868 | } |
869 | |
870 | static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb) |
871 | { |
872 | struct vc4_async_flip_state *flip_state = |
873 | container_of(cb, struct vc4_async_flip_state, cb.seqno); |
874 | struct vc4_bo *bo = NULL; |
875 | |
876 | if (flip_state->old_fb) { |
877 | struct drm_gem_dma_object *dma_bo = |
878 | drm_fb_dma_get_gem_obj(fb: flip_state->old_fb, plane: 0); |
879 | bo = to_vc4_bo(&dma_bo->base); |
880 | } |
881 | |
882 | vc4_async_page_flip_complete(flip_state); |
883 | |
884 | /* |
885 | * Decrement the BO usecnt in order to keep the inc/dec |
886 | * calls balanced when the planes are updated through |
887 | * the async update path. |
888 | * |
889 | * FIXME: we should move to generic async-page-flip when |
890 | * it's available, so that we can get rid of this |
891 | * hand-made cleanup_fb() logic. |
892 | */ |
893 | if (bo) |
894 | vc4_bo_dec_usecnt(bo); |
895 | } |
896 | |
897 | static void vc4_async_page_flip_fence_complete(struct dma_fence *fence, |
898 | struct dma_fence_cb *cb) |
899 | { |
900 | struct vc4_async_flip_state *flip_state = |
901 | container_of(cb, struct vc4_async_flip_state, cb.fence); |
902 | |
903 | vc4_async_page_flip_complete(flip_state); |
904 | dma_fence_put(fence); |
905 | } |
906 | |
907 | static int vc4_async_set_fence_cb(struct drm_device *dev, |
908 | struct vc4_async_flip_state *flip_state) |
909 | { |
910 | struct drm_framebuffer *fb = flip_state->fb; |
911 | struct drm_gem_dma_object *dma_bo = drm_fb_dma_get_gem_obj(fb, plane: 0); |
912 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
913 | struct dma_fence *fence; |
914 | int ret; |
915 | |
916 | if (!vc4->is_vc5) { |
917 | struct vc4_bo *bo = to_vc4_bo(&dma_bo->base); |
918 | |
919 | return vc4_queue_seqno_cb(dev, cb: &flip_state->cb.seqno, seqno: bo->seqno, |
920 | func: vc4_async_page_flip_seqno_complete); |
921 | } |
922 | |
923 | ret = dma_resv_get_singleton(obj: dma_bo->base.resv, usage: DMA_RESV_USAGE_READ, fence: &fence); |
924 | if (ret) |
925 | return ret; |
926 | |
927 | /* If there's no fence, complete the page flip immediately */ |
928 | if (!fence) { |
929 | vc4_async_page_flip_fence_complete(fence, cb: &flip_state->cb.fence); |
930 | return 0; |
931 | } |
932 | |
933 | /* If the fence has already been completed, complete the page flip */ |
934 | if (dma_fence_add_callback(fence, cb: &flip_state->cb.fence, |
935 | func: vc4_async_page_flip_fence_complete)) |
936 | vc4_async_page_flip_fence_complete(fence, cb: &flip_state->cb.fence); |
937 | |
938 | return 0; |
939 | } |
940 | |
941 | static int |
942 | vc4_async_page_flip_common(struct drm_crtc *crtc, |
943 | struct drm_framebuffer *fb, |
944 | struct drm_pending_vblank_event *event, |
945 | uint32_t flags) |
946 | { |
947 | struct drm_device *dev = crtc->dev; |
948 | struct drm_plane *plane = crtc->primary; |
949 | struct vc4_async_flip_state *flip_state; |
950 | |
951 | flip_state = kzalloc(size: sizeof(*flip_state), GFP_KERNEL); |
952 | if (!flip_state) |
953 | return -ENOMEM; |
954 | |
955 | drm_framebuffer_get(fb); |
956 | flip_state->fb = fb; |
957 | flip_state->crtc = crtc; |
958 | flip_state->event = event; |
959 | |
960 | /* Save the current FB before it's replaced by the new one in |
961 | * drm_atomic_set_fb_for_plane(). We'll need the old FB in |
962 | * vc4_async_page_flip_complete() to decrement the BO usecnt and keep |
963 | * it consistent. |
964 | * FIXME: we should move to generic async-page-flip when it's |
965 | * available, so that we can get rid of this hand-made cleanup_fb() |
966 | * logic. |
967 | */ |
968 | flip_state->old_fb = plane->state->fb; |
969 | if (flip_state->old_fb) |
970 | drm_framebuffer_get(fb: flip_state->old_fb); |
971 | |
972 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); |
973 | |
974 | /* Immediately update the plane's legacy fb pointer, so that later |
975 | * modeset prep sees the state that will be present when the semaphore |
976 | * is released. |
977 | */ |
978 | drm_atomic_set_fb_for_plane(plane_state: plane->state, fb); |
979 | |
980 | vc4_async_set_fence_cb(dev, flip_state); |
981 | |
982 | /* Driver takes ownership of state on successful async commit. */ |
983 | return 0; |
984 | } |
985 | |
986 | /* Implements async (non-vblank-synced) page flips. |
987 | * |
988 | * The page flip ioctl needs to return immediately, so we grab the |
989 | * modeset semaphore on the pipe, and queue the address update for |
990 | * when V3D is done with the BO being flipped to. |
991 | */ |
992 | static int vc4_async_page_flip(struct drm_crtc *crtc, |
993 | struct drm_framebuffer *fb, |
994 | struct drm_pending_vblank_event *event, |
995 | uint32_t flags) |
996 | { |
997 | struct drm_device *dev = crtc->dev; |
998 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
999 | struct drm_gem_dma_object *dma_bo = drm_fb_dma_get_gem_obj(fb, plane: 0); |
1000 | struct vc4_bo *bo = to_vc4_bo(&dma_bo->base); |
1001 | int ret; |
1002 | |
1003 | if (WARN_ON_ONCE(vc4->is_vc5)) |
1004 | return -ENODEV; |
1005 | |
1006 | /* |
1007 | * Increment the BO usecnt here, so that we never end up with an |
1008 | * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the |
1009 | * plane is later updated through the non-async path. |
1010 | * |
1011 | * FIXME: we should move to generic async-page-flip when |
1012 | * it's available, so that we can get rid of this |
1013 | * hand-made prepare_fb() logic. |
1014 | */ |
1015 | ret = vc4_bo_inc_usecnt(bo); |
1016 | if (ret) |
1017 | return ret; |
1018 | |
1019 | ret = vc4_async_page_flip_common(crtc, fb, event, flags); |
1020 | if (ret) { |
1021 | vc4_bo_dec_usecnt(bo); |
1022 | return ret; |
1023 | } |
1024 | |
1025 | return 0; |
1026 | } |
1027 | |
1028 | static int vc5_async_page_flip(struct drm_crtc *crtc, |
1029 | struct drm_framebuffer *fb, |
1030 | struct drm_pending_vblank_event *event, |
1031 | uint32_t flags) |
1032 | { |
1033 | return vc4_async_page_flip_common(crtc, fb, event, flags); |
1034 | } |
1035 | |
1036 | int vc4_page_flip(struct drm_crtc *crtc, |
1037 | struct drm_framebuffer *fb, |
1038 | struct drm_pending_vblank_event *event, |
1039 | uint32_t flags, |
1040 | struct drm_modeset_acquire_ctx *ctx) |
1041 | { |
1042 | if (flags & DRM_MODE_PAGE_FLIP_ASYNC) { |
1043 | struct drm_device *dev = crtc->dev; |
1044 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
1045 | |
1046 | if (vc4->is_vc5) |
1047 | return vc5_async_page_flip(crtc, fb, event, flags); |
1048 | else |
1049 | return vc4_async_page_flip(crtc, fb, event, flags); |
1050 | } else { |
1051 | return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); |
1052 | } |
1053 | } |
1054 | |
1055 | struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) |
1056 | { |
1057 | struct vc4_crtc_state *vc4_state, *old_vc4_state; |
1058 | |
1059 | vc4_state = kzalloc(size: sizeof(*vc4_state), GFP_KERNEL); |
1060 | if (!vc4_state) |
1061 | return NULL; |
1062 | |
1063 | old_vc4_state = to_vc4_crtc_state(crtc->state); |
1064 | vc4_state->margins = old_vc4_state->margins; |
1065 | vc4_state->assigned_channel = old_vc4_state->assigned_channel; |
1066 | |
1067 | __drm_atomic_helper_crtc_duplicate_state(crtc, state: &vc4_state->base); |
1068 | return &vc4_state->base; |
1069 | } |
1070 | |
1071 | void vc4_crtc_destroy_state(struct drm_crtc *crtc, |
1072 | struct drm_crtc_state *state) |
1073 | { |
1074 | struct vc4_dev *vc4 = to_vc4_dev(crtc->dev); |
1075 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); |
1076 | |
1077 | if (drm_mm_node_allocated(node: &vc4_state->mm)) { |
1078 | unsigned long flags; |
1079 | |
1080 | spin_lock_irqsave(&vc4->hvs->mm_lock, flags); |
1081 | drm_mm_remove_node(node: &vc4_state->mm); |
1082 | spin_unlock_irqrestore(lock: &vc4->hvs->mm_lock, flags); |
1083 | |
1084 | } |
1085 | |
1086 | drm_atomic_helper_crtc_destroy_state(crtc, state); |
1087 | } |
1088 | |
1089 | void vc4_crtc_reset(struct drm_crtc *crtc) |
1090 | { |
1091 | struct vc4_crtc_state *vc4_crtc_state; |
1092 | |
1093 | if (crtc->state) |
1094 | vc4_crtc_destroy_state(crtc, state: crtc->state); |
1095 | |
1096 | vc4_crtc_state = kzalloc(size: sizeof(*vc4_crtc_state), GFP_KERNEL); |
1097 | if (!vc4_crtc_state) { |
1098 | crtc->state = NULL; |
1099 | return; |
1100 | } |
1101 | |
1102 | vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED; |
1103 | __drm_atomic_helper_crtc_reset(crtc, state: &vc4_crtc_state->base); |
1104 | } |
1105 | |
1106 | int vc4_crtc_late_register(struct drm_crtc *crtc) |
1107 | { |
1108 | struct drm_device *drm = crtc->dev; |
1109 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
1110 | const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(crtc: vc4_crtc); |
1111 | |
1112 | vc4_debugfs_add_regset32(drm, filename: crtc_data->debugfs_name, |
1113 | regset: &vc4_crtc->regset); |
1114 | |
1115 | return 0; |
1116 | } |
1117 | |
1118 | static const struct drm_crtc_funcs vc4_crtc_funcs = { |
1119 | .set_config = drm_atomic_helper_set_config, |
1120 | .page_flip = vc4_page_flip, |
1121 | .set_property = NULL, |
1122 | .cursor_set = NULL, /* handled by drm_mode_cursor_universal */ |
1123 | .cursor_move = NULL, /* handled by drm_mode_cursor_universal */ |
1124 | .reset = vc4_crtc_reset, |
1125 | .atomic_duplicate_state = vc4_crtc_duplicate_state, |
1126 | .atomic_destroy_state = vc4_crtc_destroy_state, |
1127 | .enable_vblank = vc4_enable_vblank, |
1128 | .disable_vblank = vc4_disable_vblank, |
1129 | .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, |
1130 | .late_register = vc4_crtc_late_register, |
1131 | }; |
1132 | |
1133 | static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { |
1134 | .mode_valid = vc4_crtc_mode_valid, |
1135 | .atomic_check = vc4_crtc_atomic_check, |
1136 | .atomic_begin = vc4_hvs_atomic_begin, |
1137 | .atomic_flush = vc4_hvs_atomic_flush, |
1138 | .atomic_enable = vc4_crtc_atomic_enable, |
1139 | .atomic_disable = vc4_crtc_atomic_disable, |
1140 | .get_scanout_position = vc4_crtc_get_scanout_position, |
1141 | }; |
1142 | |
1143 | const struct vc4_pv_data bcm2835_pv0_data = { |
1144 | .base = { |
1145 | .name = "pixelvalve-0" , |
1146 | .debugfs_name = "crtc0_regs" , |
1147 | .hvs_available_channels = BIT(0), |
1148 | .hvs_output = 0, |
1149 | }, |
1150 | .fifo_depth = 64, |
1151 | .pixels_per_clock = 1, |
1152 | .encoder_types = { |
1153 | [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0, |
1154 | [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI, |
1155 | }, |
1156 | }; |
1157 | |
1158 | const struct vc4_pv_data bcm2835_pv1_data = { |
1159 | .base = { |
1160 | .name = "pixelvalve-1" , |
1161 | .debugfs_name = "crtc1_regs" , |
1162 | .hvs_available_channels = BIT(2), |
1163 | .hvs_output = 2, |
1164 | }, |
1165 | .fifo_depth = 64, |
1166 | .pixels_per_clock = 1, |
1167 | .encoder_types = { |
1168 | [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1, |
1169 | [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI, |
1170 | }, |
1171 | }; |
1172 | |
1173 | const struct vc4_pv_data bcm2835_pv2_data = { |
1174 | .base = { |
1175 | .name = "pixelvalve-2" , |
1176 | .debugfs_name = "crtc2_regs" , |
1177 | .hvs_available_channels = BIT(1), |
1178 | .hvs_output = 1, |
1179 | }, |
1180 | .fifo_depth = 64, |
1181 | .pixels_per_clock = 1, |
1182 | .encoder_types = { |
1183 | [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0, |
1184 | [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC, |
1185 | }, |
1186 | }; |
1187 | |
1188 | const struct vc4_pv_data bcm2711_pv0_data = { |
1189 | .base = { |
1190 | .name = "pixelvalve-0" , |
1191 | .debugfs_name = "crtc0_regs" , |
1192 | .hvs_available_channels = BIT(0), |
1193 | .hvs_output = 0, |
1194 | }, |
1195 | .fifo_depth = 64, |
1196 | .pixels_per_clock = 1, |
1197 | .encoder_types = { |
1198 | [0] = VC4_ENCODER_TYPE_DSI0, |
1199 | [1] = VC4_ENCODER_TYPE_DPI, |
1200 | }, |
1201 | }; |
1202 | |
1203 | const struct vc4_pv_data bcm2711_pv1_data = { |
1204 | .base = { |
1205 | .name = "pixelvalve-1" , |
1206 | .debugfs_name = "crtc1_regs" , |
1207 | .hvs_available_channels = BIT(0) | BIT(1) | BIT(2), |
1208 | .hvs_output = 3, |
1209 | }, |
1210 | .fifo_depth = 64, |
1211 | .pixels_per_clock = 1, |
1212 | .encoder_types = { |
1213 | [0] = VC4_ENCODER_TYPE_DSI1, |
1214 | [1] = VC4_ENCODER_TYPE_SMI, |
1215 | }, |
1216 | }; |
1217 | |
1218 | const struct vc4_pv_data bcm2711_pv2_data = { |
1219 | .base = { |
1220 | .name = "pixelvalve-2" , |
1221 | .debugfs_name = "crtc2_regs" , |
1222 | .hvs_available_channels = BIT(0) | BIT(1) | BIT(2), |
1223 | .hvs_output = 4, |
1224 | }, |
1225 | .fifo_depth = 256, |
1226 | .pixels_per_clock = 2, |
1227 | .encoder_types = { |
1228 | [0] = VC4_ENCODER_TYPE_HDMI0, |
1229 | }, |
1230 | }; |
1231 | |
1232 | const struct vc4_pv_data bcm2711_pv3_data = { |
1233 | .base = { |
1234 | .name = "pixelvalve-3" , |
1235 | .debugfs_name = "crtc3_regs" , |
1236 | .hvs_available_channels = BIT(1), |
1237 | .hvs_output = 1, |
1238 | }, |
1239 | .fifo_depth = 64, |
1240 | .pixels_per_clock = 1, |
1241 | .encoder_types = { |
1242 | [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC, |
1243 | }, |
1244 | }; |
1245 | |
1246 | const struct vc4_pv_data bcm2711_pv4_data = { |
1247 | .base = { |
1248 | .name = "pixelvalve-4" , |
1249 | .debugfs_name = "crtc4_regs" , |
1250 | .hvs_available_channels = BIT(0) | BIT(1) | BIT(2), |
1251 | .hvs_output = 5, |
1252 | }, |
1253 | .fifo_depth = 64, |
1254 | .pixels_per_clock = 2, |
1255 | .encoder_types = { |
1256 | [0] = VC4_ENCODER_TYPE_HDMI1, |
1257 | }, |
1258 | }; |
1259 | |
1260 | static const struct of_device_id vc4_crtc_dt_match[] = { |
1261 | { .compatible = "brcm,bcm2835-pixelvalve0" , .data = &bcm2835_pv0_data }, |
1262 | { .compatible = "brcm,bcm2835-pixelvalve1" , .data = &bcm2835_pv1_data }, |
1263 | { .compatible = "brcm,bcm2835-pixelvalve2" , .data = &bcm2835_pv2_data }, |
1264 | { .compatible = "brcm,bcm2711-pixelvalve0" , .data = &bcm2711_pv0_data }, |
1265 | { .compatible = "brcm,bcm2711-pixelvalve1" , .data = &bcm2711_pv1_data }, |
1266 | { .compatible = "brcm,bcm2711-pixelvalve2" , .data = &bcm2711_pv2_data }, |
1267 | { .compatible = "brcm,bcm2711-pixelvalve3" , .data = &bcm2711_pv3_data }, |
1268 | { .compatible = "brcm,bcm2711-pixelvalve4" , .data = &bcm2711_pv4_data }, |
1269 | {} |
1270 | }; |
1271 | |
1272 | static void vc4_set_crtc_possible_masks(struct drm_device *drm, |
1273 | struct drm_crtc *crtc) |
1274 | { |
1275 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
1276 | const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(crtc: vc4_crtc); |
1277 | const enum vc4_encoder_type *encoder_types = pv_data->encoder_types; |
1278 | struct drm_encoder *encoder; |
1279 | |
1280 | drm_for_each_encoder(encoder, drm) { |
1281 | struct vc4_encoder *vc4_encoder; |
1282 | int i; |
1283 | |
1284 | if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) |
1285 | continue; |
1286 | |
1287 | vc4_encoder = to_vc4_encoder(encoder); |
1288 | for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) { |
1289 | if (vc4_encoder->type == encoder_types[i]) { |
1290 | vc4_encoder->clock_select = i; |
1291 | encoder->possible_crtcs |= drm_crtc_mask(crtc); |
1292 | break; |
1293 | } |
1294 | } |
1295 | } |
1296 | } |
1297 | |
1298 | /** |
1299 | * __vc4_crtc_init - Initializes a CRTC |
1300 | * @drm: DRM Device |
1301 | * @pdev: CRTC Platform Device |
1302 | * @vc4_crtc: CRTC Object to Initialize |
1303 | * @data: Configuration data associated with this CRTC |
1304 | * @primary_plane: Primary plane for CRTC |
1305 | * @crtc_funcs: Callbacks for the new CRTC |
1306 | * @crtc_helper_funcs: Helper Callbacks for the new CRTC |
1307 | * @feeds_txp: Is this CRTC connected to the TXP? |
1308 | * |
1309 | * Initializes our private CRTC structure. This function is mostly |
1310 | * relevant for KUnit testing, all other users should use |
1311 | * vc4_crtc_init() instead. |
1312 | * |
1313 | * Returns: |
1314 | * 0 on success, a negative error code on failure. |
1315 | */ |
1316 | int __vc4_crtc_init(struct drm_device *drm, |
1317 | struct platform_device *pdev, |
1318 | struct vc4_crtc *vc4_crtc, |
1319 | const struct vc4_crtc_data *data, |
1320 | struct drm_plane *primary_plane, |
1321 | const struct drm_crtc_funcs *crtc_funcs, |
1322 | const struct drm_crtc_helper_funcs *crtc_helper_funcs, |
1323 | bool feeds_txp) |
1324 | { |
1325 | struct vc4_dev *vc4 = to_vc4_dev(drm); |
1326 | struct drm_crtc *crtc = &vc4_crtc->base; |
1327 | unsigned int i; |
1328 | int ret; |
1329 | |
1330 | vc4_crtc->data = data; |
1331 | vc4_crtc->pdev = pdev; |
1332 | vc4_crtc->feeds_txp = feeds_txp; |
1333 | spin_lock_init(&vc4_crtc->irq_lock); |
1334 | ret = drmm_crtc_init_with_planes(dev: drm, crtc, primary: primary_plane, NULL, |
1335 | funcs: crtc_funcs, name: data->name); |
1336 | if (ret) |
1337 | return ret; |
1338 | |
1339 | drm_crtc_helper_add(crtc, funcs: crtc_helper_funcs); |
1340 | |
1341 | if (!vc4->is_vc5) { |
1342 | drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); |
1343 | |
1344 | drm_crtc_enable_color_mgmt(crtc, degamma_lut_size: 0, has_ctm: false, gamma_lut_size: crtc->gamma_size); |
1345 | |
1346 | /* We support CTM, but only for one CRTC at a time. It's therefore |
1347 | * implemented as private driver state in vc4_kms, not here. |
1348 | */ |
1349 | drm_crtc_enable_color_mgmt(crtc, degamma_lut_size: 0, has_ctm: true, gamma_lut_size: crtc->gamma_size); |
1350 | } |
1351 | |
1352 | for (i = 0; i < crtc->gamma_size; i++) { |
1353 | vc4_crtc->lut_r[i] = i; |
1354 | vc4_crtc->lut_g[i] = i; |
1355 | vc4_crtc->lut_b[i] = i; |
1356 | } |
1357 | |
1358 | return 0; |
1359 | } |
1360 | |
1361 | int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, |
1362 | struct vc4_crtc *vc4_crtc, |
1363 | const struct vc4_crtc_data *data, |
1364 | const struct drm_crtc_funcs *crtc_funcs, |
1365 | const struct drm_crtc_helper_funcs *crtc_helper_funcs, |
1366 | bool feeds_txp) |
1367 | { |
1368 | struct drm_plane *primary_plane; |
1369 | |
1370 | /* For now, we create just the primary and the legacy cursor |
1371 | * planes. We should be able to stack more planes on easily, |
1372 | * but to do that we would need to compute the bandwidth |
1373 | * requirement of the plane configuration, and reject ones |
1374 | * that will take too much. |
1375 | */ |
1376 | primary_plane = vc4_plane_init(dev: drm, type: DRM_PLANE_TYPE_PRIMARY, possible_crtcs: 0); |
1377 | if (IS_ERR(ptr: primary_plane)) { |
1378 | dev_err(drm->dev, "failed to construct primary plane\n" ); |
1379 | return PTR_ERR(ptr: primary_plane); |
1380 | } |
1381 | |
1382 | return __vc4_crtc_init(drm, pdev, vc4_crtc, data, primary_plane, |
1383 | crtc_funcs, crtc_helper_funcs, feeds_txp); |
1384 | } |
1385 | |
1386 | static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) |
1387 | { |
1388 | struct platform_device *pdev = to_platform_device(dev); |
1389 | struct drm_device *drm = dev_get_drvdata(dev: master); |
1390 | const struct vc4_pv_data *pv_data; |
1391 | struct vc4_crtc *vc4_crtc; |
1392 | struct drm_crtc *crtc; |
1393 | int ret; |
1394 | |
1395 | vc4_crtc = drmm_kzalloc(dev: drm, size: sizeof(*vc4_crtc), GFP_KERNEL); |
1396 | if (!vc4_crtc) |
1397 | return -ENOMEM; |
1398 | crtc = &vc4_crtc->base; |
1399 | |
1400 | pv_data = of_device_get_match_data(dev); |
1401 | if (!pv_data) |
1402 | return -ENODEV; |
1403 | |
1404 | vc4_crtc->regs = vc4_ioremap_regs(dev: pdev, index: 0); |
1405 | if (IS_ERR(ptr: vc4_crtc->regs)) |
1406 | return PTR_ERR(ptr: vc4_crtc->regs); |
1407 | |
1408 | vc4_crtc->regset.base = vc4_crtc->regs; |
1409 | vc4_crtc->regset.regs = crtc_regs; |
1410 | vc4_crtc->regset.nregs = ARRAY_SIZE(crtc_regs); |
1411 | |
1412 | ret = vc4_crtc_init(drm, pdev, vc4_crtc, data: &pv_data->base, |
1413 | crtc_funcs: &vc4_crtc_funcs, crtc_helper_funcs: &vc4_crtc_helper_funcs, |
1414 | feeds_txp: false); |
1415 | if (ret) |
1416 | return ret; |
1417 | vc4_set_crtc_possible_masks(drm, crtc); |
1418 | |
1419 | CRTC_WRITE(PV_INTEN, 0); |
1420 | CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); |
1421 | ret = devm_request_irq(dev, irq: platform_get_irq(pdev, 0), |
1422 | handler: vc4_crtc_irq_handler, |
1423 | IRQF_SHARED, |
1424 | devname: "vc4 crtc" , dev_id: vc4_crtc); |
1425 | if (ret) |
1426 | return ret; |
1427 | |
1428 | platform_set_drvdata(pdev, data: vc4_crtc); |
1429 | |
1430 | return 0; |
1431 | } |
1432 | |
1433 | static void vc4_crtc_unbind(struct device *dev, struct device *master, |
1434 | void *data) |
1435 | { |
1436 | struct platform_device *pdev = to_platform_device(dev); |
1437 | struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev); |
1438 | |
1439 | CRTC_WRITE(PV_INTEN, 0); |
1440 | |
1441 | platform_set_drvdata(pdev, NULL); |
1442 | } |
1443 | |
1444 | static const struct component_ops vc4_crtc_ops = { |
1445 | .bind = vc4_crtc_bind, |
1446 | .unbind = vc4_crtc_unbind, |
1447 | }; |
1448 | |
1449 | static int vc4_crtc_dev_probe(struct platform_device *pdev) |
1450 | { |
1451 | return component_add(&pdev->dev, &vc4_crtc_ops); |
1452 | } |
1453 | |
1454 | static void vc4_crtc_dev_remove(struct platform_device *pdev) |
1455 | { |
1456 | component_del(&pdev->dev, &vc4_crtc_ops); |
1457 | } |
1458 | |
1459 | struct platform_driver vc4_crtc_driver = { |
1460 | .probe = vc4_crtc_dev_probe, |
1461 | .remove_new = vc4_crtc_dev_remove, |
1462 | .driver = { |
1463 | .name = "vc4_crtc" , |
1464 | .of_match_table = vc4_crtc_dt_match, |
1465 | }, |
1466 | }; |
1467 | |