1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2024 NXP
4 */
5
6 #include <linux/completion.h>
7 #include <linux/container_of.h>
8 #include <linux/interrupt.h>
9 #include <linux/irqreturn.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/spinlock.h>
12
13 #include <drm/drm_atomic.h>
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_atomic_state_helper.h>
16 #include <drm/drm_crtc.h>
17 #include <drm/drm_device.h>
18 #include <drm/drm_drv.h>
19 #include <drm/drm_modes.h>
20 #include <drm/drm_modeset_helper_vtables.h>
21 #include <drm/drm_plane.h>
22 #include <drm/drm_print.h>
23 #include <drm/drm_vblank.h>
24
25 #include "dc-de.h"
26 #include "dc-drv.h"
27 #include "dc-kms.h"
28 #include "dc-pe.h"
29
30 #define dc_crtc_dbg(crtc, fmt, ...) \
31 do { \
32 struct drm_crtc *_crtc = (crtc); \
33 drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt, \
34 _crtc->base.id, _crtc->name, ##__VA_ARGS__); \
35 } while (0)
36
37 #define dc_crtc_err(crtc, fmt, ...) \
38 do { \
39 struct drm_crtc *_crtc = (crtc); \
40 drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt, \
41 _crtc->base.id, _crtc->name, ##__VA_ARGS__); \
42 } while (0)
43
44 #define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c) \
45 do { \
46 unsigned long ret; \
47 ret = wait_for_completion_timeout(&dc_crtc->c, HZ); \
48 if (ret == 0) \
49 dc_crtc_err(crtc, "%s: wait for " #c " timeout\n", \
50 __func__); \
51 } while (0)
52
53 #define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg) \
54 do { \
55 struct dc_fg *_fg = (fg); \
56 if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) { \
57 dc_fg_secondary_clear_channel_status(_fg); \
58 dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n", \
59 __func__); \
60 } \
61 } while (0)
62
63 #define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg) \
64 do { \
65 if (dc_fg_wait_for_secondary_syncup(fg)) \
66 dc_crtc_err(crtc, \
67 "%s: FrameGen secondary channel isn't syncup\n",\
68 __func__); \
69 } while (0)
70
to_dc_crtc(struct drm_crtc * crtc)71 static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
72 {
73 return container_of(crtc, struct dc_crtc, base);
74 }
75
dc_crtc_get_vblank_counter(struct drm_crtc * crtc)76 static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
77 {
78 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
79
80 return dc_fg_get_frame_index(dc_crtc->fg);
81 }
82
dc_crtc_enable_vblank(struct drm_crtc * crtc)83 static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
84 {
85 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
86
87 enable_irq(dc_crtc->irq_dec_framecomplete);
88
89 return 0;
90 }
91
dc_crtc_disable_vblank(struct drm_crtc * crtc)92 static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
93 {
94 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
95
96 /* nosync due to atomic context */
97 disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
98 }
99
100 static const struct drm_crtc_funcs dc_crtc_funcs = {
101 .reset = drm_atomic_helper_crtc_reset,
102 .destroy = drm_crtc_cleanup,
103 .set_config = drm_atomic_helper_set_config,
104 .page_flip = drm_atomic_helper_page_flip,
105 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
106 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
107 .get_vblank_counter = dc_crtc_get_vblank_counter,
108 .enable_vblank = dc_crtc_enable_vblank,
109 .disable_vblank = dc_crtc_disable_vblank,
110 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
111 };
112
dc_crtc_queue_state_event(struct drm_crtc_state * crtc_state)113 static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
114 {
115 struct drm_crtc *crtc = crtc_state->crtc;
116 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
117
118 spin_lock_irq(&crtc->dev->event_lock);
119 if (crtc_state->event) {
120 WARN_ON(drm_crtc_vblank_get(crtc));
121 WARN_ON(dc_crtc->event);
122 dc_crtc->event = crtc_state->event;
123 crtc_state->event = NULL;
124 }
125 spin_unlock_irq(&crtc->dev->event_lock);
126 }
127
128 static inline enum drm_mode_status
dc_crtc_check_clock(struct dc_crtc * dc_crtc,int clk_khz)129 dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
130 {
131 return dc_fg_check_clock(dc_crtc->fg, clk_khz);
132 }
133
134 static enum drm_mode_status
dc_crtc_mode_valid(struct drm_crtc * crtc,const struct drm_display_mode * mode)135 dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
136 {
137 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
138 enum drm_mode_status status;
139
140 status = dc_crtc_check_clock(dc_crtc, mode->clock);
141 if (status != MODE_OK)
142 return status;
143
144 if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
145 return MODE_CLOCK_HIGH;
146
147 return MODE_OK;
148 }
149
150 static int
dc_crtc_atomic_check(struct drm_crtc * crtc,struct drm_atomic_state * state)151 dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
152 {
153 struct drm_crtc_state *new_crtc_state =
154 drm_atomic_get_new_crtc_state(state, crtc);
155 struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
156 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
157 enum drm_mode_status status;
158
159 status = dc_crtc_check_clock(dc_crtc, adj->clock);
160 if (status != MODE_OK)
161 return -EINVAL;
162
163 return 0;
164 }
165
166 static void
dc_crtc_atomic_begin(struct drm_crtc * crtc,struct drm_atomic_state * state)167 dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
168 {
169 struct drm_crtc_state *new_crtc_state =
170 drm_atomic_get_new_crtc_state(state, crtc);
171 struct dc_drm_device *dc_drm = to_dc_drm_device(crtc->dev);
172 int idx, ret;
173
174 if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
175 !new_crtc_state->active)
176 return;
177
178 if (!drm_dev_enter(crtc->dev, &idx))
179 return;
180
181 /* request pixel engine power-on when CRTC starts to be active */
182 ret = pm_runtime_resume_and_get(dc_drm->pe->dev);
183 if (ret)
184 dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
185 ret);
186
187 drm_dev_exit(idx);
188 }
189
190 static void
dc_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_atomic_state * state)191 dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
192 {
193 struct drm_crtc_state *old_crtc_state =
194 drm_atomic_get_old_crtc_state(state, crtc);
195 struct drm_crtc_state *new_crtc_state =
196 drm_atomic_get_new_crtc_state(state, crtc);
197 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
198 int idx;
199
200 if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
201 (!old_crtc_state->active && !new_crtc_state->active))
202 return;
203
204 if (!drm_dev_enter(crtc->dev, &idx))
205 goto out;
206
207 enable_irq(dc_crtc->irq_ed_cont_shdload);
208
209 /* flush plane update out to display */
210 dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
211
212 DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdload_done);
213
214 disable_irq(dc_crtc->irq_ed_cont_shdload);
215
216 DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
217
218 drm_dev_exit(idx);
219
220 out:
221 dc_crtc_queue_state_event(new_crtc_state);
222 }
223
224 static void
dc_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_atomic_state * state)225 dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
226 {
227 struct drm_crtc_state *new_crtc_state =
228 drm_atomic_get_new_crtc_state(state, crtc);
229 struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
230 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
231 enum dc_link_id cf_link;
232 int idx, ret;
233
234 dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
235
236 drm_crtc_vblank_on(crtc);
237
238 if (!drm_dev_enter(crtc->dev, &idx))
239 goto out;
240
241 /* request display engine power-on when CRTC is enabled */
242 ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
243 if (ret < 0)
244 dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
245 ret);
246
247 enable_irq(dc_crtc->irq_dec_shdload);
248 enable_irq(dc_crtc->irq_ed_cont_shdload);
249 enable_irq(dc_crtc->irq_ed_safe_shdload);
250
251 dc_fg_cfg_videomode(dc_crtc->fg, adj);
252
253 dc_cf_framedimensions(dc_crtc->cf_cont,
254 adj->crtc_hdisplay, adj->crtc_vdisplay);
255 dc_cf_framedimensions(dc_crtc->cf_safe,
256 adj->crtc_hdisplay, adj->crtc_vdisplay);
257
258 /* constframe in safety stream shows blue frame */
259 dc_cf_constantcolor_blue(dc_crtc->cf_safe);
260 cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
261 dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
262
263 /* show CRTC background if no plane is enabled */
264 if (new_crtc_state->plane_mask == 0) {
265 /* constframe in content stream shows black frame */
266 dc_cf_constantcolor_black(dc_crtc->cf_cont);
267
268 cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
269 dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
270 }
271
272 dc_fg_enable_clock(dc_crtc->fg);
273 dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
274 dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
275 dc_fg_shdtokgen(dc_crtc->fg);
276 dc_fg_enable(dc_crtc->fg);
277
278 DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdload_done);
279 DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdload_done);
280 DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdload_done);
281
282 disable_irq(dc_crtc->irq_ed_safe_shdload);
283 disable_irq(dc_crtc->irq_ed_cont_shdload);
284 disable_irq(dc_crtc->irq_dec_shdload);
285
286 DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
287
288 DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
289
290 drm_dev_exit(idx);
291
292 out:
293 dc_crtc_queue_state_event(new_crtc_state);
294 }
295
296 static void
dc_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_atomic_state * state)297 dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
298 {
299 struct drm_crtc_state *new_crtc_state =
300 drm_atomic_get_new_crtc_state(state, crtc);
301 struct dc_drm_device *dc_drm = to_dc_drm_device(crtc->dev);
302 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
303 int idx, ret;
304
305 if (!drm_dev_enter(crtc->dev, &idx))
306 goto out;
307
308 enable_irq(dc_crtc->irq_dec_seqcomplete);
309 dc_fg_disable(dc_crtc->fg);
310 DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
311 disable_irq(dc_crtc->irq_dec_seqcomplete);
312
313 dc_fg_disable_clock(dc_crtc->fg);
314
315 /* request pixel engine power-off as plane is off too */
316 ret = pm_runtime_put(dc_drm->pe->dev);
317 if (ret)
318 dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
319 ret);
320
321 /* request display engine power-off when CRTC is disabled */
322 ret = pm_runtime_put(dc_crtc->de->dev);
323 if (ret < 0)
324 dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
325 ret);
326
327 drm_dev_exit(idx);
328
329 out:
330 drm_crtc_vblank_off(crtc);
331
332 spin_lock_irq(&crtc->dev->event_lock);
333 if (new_crtc_state->event && !new_crtc_state->active) {
334 drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
335 new_crtc_state->event = NULL;
336 }
337 spin_unlock_irq(&crtc->dev->event_lock);
338 }
339
dc_crtc_get_scanout_position(struct drm_crtc * crtc,bool in_vblank_irq,int * vpos,int * hpos,ktime_t * stime,ktime_t * etime,const struct drm_display_mode * mode)340 static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
341 bool in_vblank_irq,
342 int *vpos, int *hpos,
343 ktime_t *stime, ktime_t *etime,
344 const struct drm_display_mode *mode)
345 {
346 struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
347 int vdisplay = mode->crtc_vdisplay;
348 int vtotal = mode->crtc_vtotal;
349 bool reliable;
350 int line;
351 int idx;
352
353 if (stime)
354 *stime = ktime_get();
355
356 if (!drm_dev_enter(crtc->dev, &idx)) {
357 reliable = false;
358 *vpos = 0;
359 *hpos = 0;
360 goto out;
361 }
362
363 /* line index starts with 0 for the first active output line */
364 line = dc_fg_get_line_index(dc_crtc->fg);
365
366 if (line < vdisplay)
367 /* active scanout area - positive */
368 *vpos = line + 1;
369 else
370 /* inside vblank - negative */
371 *vpos = line - (vtotal - 1);
372
373 *hpos = 0;
374
375 reliable = true;
376
377 drm_dev_exit(idx);
378 out:
379 if (etime)
380 *etime = ktime_get();
381
382 return reliable;
383 }
384
385 static const struct drm_crtc_helper_funcs dc_helper_funcs = {
386 .mode_valid = dc_crtc_mode_valid,
387 .atomic_check = dc_crtc_atomic_check,
388 .atomic_begin = dc_crtc_atomic_begin,
389 .atomic_flush = dc_crtc_atomic_flush,
390 .atomic_enable = dc_crtc_atomic_enable,
391 .atomic_disable = dc_crtc_atomic_disable,
392 .get_scanout_position = dc_crtc_get_scanout_position,
393 };
394
dc_crtc_irq_handler_dec_framecomplete(int irq,void * dev_id)395 static irqreturn_t dc_crtc_irq_handler_dec_framecomplete(int irq, void *dev_id)
396 {
397 struct dc_crtc *dc_crtc = dev_id;
398 struct drm_crtc *crtc = &dc_crtc->base;
399 unsigned long flags;
400
401 drm_crtc_handle_vblank(crtc);
402
403 spin_lock_irqsave(&crtc->dev->event_lock, flags);
404 if (dc_crtc->event) {
405 drm_crtc_send_vblank_event(crtc, dc_crtc->event);
406 dc_crtc->event = NULL;
407 drm_crtc_vblank_put(crtc);
408 }
409 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
410
411 return IRQ_HANDLED;
412 }
413
414 static irqreturn_t
dc_crtc_irq_handler_dec_seqcomplete_done(int irq,void * dev_id)415 dc_crtc_irq_handler_dec_seqcomplete_done(int irq, void *dev_id)
416 {
417 struct dc_crtc *dc_crtc = dev_id;
418
419 complete(&dc_crtc->dec_seqcomplete_done);
420
421 return IRQ_HANDLED;
422 }
423
dc_crtc_irq_handler_dec_shdload_done(int irq,void * dev_id)424 static irqreturn_t dc_crtc_irq_handler_dec_shdload_done(int irq, void *dev_id)
425 {
426 struct dc_crtc *dc_crtc = dev_id;
427
428 complete(&dc_crtc->dec_shdload_done);
429
430 return IRQ_HANDLED;
431 }
432
433 static irqreturn_t
dc_crtc_irq_handler_ed_cont_shdload_done(int irq,void * dev_id)434 dc_crtc_irq_handler_ed_cont_shdload_done(int irq, void *dev_id)
435 {
436 struct dc_crtc *dc_crtc = dev_id;
437
438 complete(&dc_crtc->ed_cont_shdload_done);
439
440 return IRQ_HANDLED;
441 }
442
443 static irqreturn_t
dc_crtc_irq_handler_ed_safe_shdload_done(int irq,void * dev_id)444 dc_crtc_irq_handler_ed_safe_shdload_done(int irq, void *dev_id)
445 {
446 struct dc_crtc *dc_crtc = dev_id;
447
448 complete(&dc_crtc->ed_safe_shdload_done);
449
450 return IRQ_HANDLED;
451 }
452
dc_crtc_request_irqs(struct drm_device * drm,struct dc_crtc * dc_crtc)453 static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
454 {
455 struct {
456 struct device *dev;
457 unsigned int irq;
458 irqreturn_t (*irq_handler)(int irq, void *dev_id);
459 } irqs[DC_CRTC_IRQS] = {
460 {
461 dc_crtc->de->dev,
462 dc_crtc->irq_dec_framecomplete,
463 dc_crtc_irq_handler_dec_framecomplete,
464 }, {
465 dc_crtc->de->dev,
466 dc_crtc->irq_dec_seqcomplete,
467 dc_crtc_irq_handler_dec_seqcomplete_done,
468 }, {
469 dc_crtc->de->dev,
470 dc_crtc->irq_dec_shdload,
471 dc_crtc_irq_handler_dec_shdload_done,
472 }, {
473 dc_crtc->ed_cont->dev,
474 dc_crtc->irq_ed_cont_shdload,
475 dc_crtc_irq_handler_ed_cont_shdload_done,
476 }, {
477 dc_crtc->ed_safe->dev,
478 dc_crtc->irq_ed_safe_shdload,
479 dc_crtc_irq_handler_ed_safe_shdload_done,
480 },
481 };
482 int i, ret;
483
484 for (i = 0; i < DC_CRTC_IRQS; i++) {
485 struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
486
487 ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
488 irqs[i].irq_handler, IRQF_NO_AUTOEN,
489 dev_name(irqs[i].dev), dc_crtc);
490 if (ret) {
491 dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
492 irqs[i].irq, ret);
493 return ret;
494 }
495
496 irq->dc_crtc = dc_crtc;
497 irq->irq = irqs[i].irq;
498 }
499
500 return 0;
501 }
502
dc_crtc_init(struct dc_drm_device * dc_drm,int crtc_index)503 int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
504 {
505 struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
506 struct drm_device *drm = &dc_drm->base;
507 struct dc_de *de = dc_drm->de[crtc_index];
508 struct dc_pe *pe = dc_drm->pe;
509 struct dc_plane *dc_primary;
510 int ret;
511
512 dc_crtc->de = de;
513
514 init_completion(&dc_crtc->dec_seqcomplete_done);
515 init_completion(&dc_crtc->dec_shdload_done);
516 init_completion(&dc_crtc->ed_cont_shdload_done);
517 init_completion(&dc_crtc->ed_safe_shdload_done);
518
519 dc_crtc->cf_cont = pe->cf_cont[crtc_index];
520 dc_crtc->cf_safe = pe->cf_safe[crtc_index];
521 dc_crtc->ed_cont = pe->ed_cont[crtc_index];
522 dc_crtc->ed_safe = pe->ed_safe[crtc_index];
523 dc_crtc->fg = de->fg;
524
525 dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
526 dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
527 dc_crtc->irq_dec_shdload = de->irq_shdload;
528 dc_crtc->irq_ed_safe_shdload = dc_crtc->ed_safe->irq_shdload;
529 dc_crtc->irq_ed_cont_shdload = dc_crtc->ed_cont->irq_shdload;
530
531 dc_primary = &dc_drm->dc_primary[crtc_index];
532 ret = dc_plane_init(dc_drm, dc_primary);
533 if (ret) {
534 dev_err(de->dev, "failed to initialize primary plane: %d\n",
535 ret);
536 return ret;
537 }
538
539 drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
540
541 ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
542 NULL, &dc_crtc_funcs, NULL);
543 if (ret)
544 dev_err(de->dev, "failed to add CRTC: %d\n", ret);
545
546 return ret;
547 }
548
dc_crtc_post_init(struct dc_drm_device * dc_drm,int crtc_index)549 int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
550 {
551 struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
552 struct drm_device *drm = &dc_drm->base;
553
554 return dc_crtc_request_irqs(drm, dc_crtc);
555 }
556