Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2015 MediaTek Inc.
4 */
5
6#include <linux/clk.h>
7#include <linux/dma-mapping.h>
8#include <linux/mailbox_controller.h>
9#include <linux/of.h>
10#include <linux/pm_runtime.h>
11#include <linux/soc/mediatek/mtk-cmdq.h>
12#include <linux/soc/mediatek/mtk-mmsys.h>
13#include <linux/soc/mediatek/mtk-mutex.h>
14
15#include <asm/barrier.h>
16
17#include <drm/drm_atomic.h>
18#include <drm/drm_atomic_helper.h>
19#include <drm/drm_probe_helper.h>
20#include <drm/drm_vblank.h>
21
22#include "mtk_crtc.h"
23#include "mtk_ddp_comp.h"
24#include "mtk_drm_drv.h"
25#include "mtk_gem.h"
26#include "mtk_plane.h"
27
28/*
29 * struct mtk_crtc - MediaTek specific crtc structure.
30 * @base: crtc object.
31 * @enabled: records whether crtc_enable succeeded
32 * @planes: array of 4 drm_plane structures, one for each overlay plane
33 * @pending_planes: whether any plane has pending changes to be applied
34 * @mmsys_dev: pointer to the mmsys device for configuration registers
35 * @mutex: handle to one of the ten disp_mutex streams
36 * @ddp_comp_nr: number of components in ddp_comp
37 * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
38 *
39 * TODO: Needs update: this header is missing a bunch of member descriptions.
40 */
41struct mtk_crtc {
42 struct drm_crtc base;
43 bool enabled;
44
45 bool pending_needs_vblank;
46 struct drm_pending_vblank_event *event;
47
48 struct drm_plane *planes;
49 unsigned int layer_nr;
50 bool pending_planes;
51 bool pending_async_planes;
52
53#if IS_REACHABLE(CONFIG_MTK_CMDQ)
54 struct cmdq_client cmdq_client;
55 struct cmdq_pkt cmdq_handle;
56 u32 cmdq_event;
57 u32 cmdq_vblank_cnt;
58 wait_queue_head_t cb_blocking_queue;
59#endif
60
61 struct device *mmsys_dev;
62 struct device *dma_dev;
63 struct mtk_mutex *mutex;
64 unsigned int ddp_comp_nr;
65 struct mtk_ddp_comp **ddp_comp;
66 unsigned int num_conn_routes;
67 const struct mtk_drm_route *conn_routes;
68
69 /* lock for display hardware access */
70 struct mutex hw_lock;
71 bool config_updating;
72 /* lock for config_updating to cmd buffer */
73 spinlock_t config_lock;
74};
75
76struct mtk_crtc_state {
77 struct drm_crtc_state base;
78
79 bool pending_config;
80 unsigned int pending_width;
81 unsigned int pending_height;
82 unsigned int pending_vrefresh;
83};
84
85static inline struct mtk_crtc *to_mtk_crtc(struct drm_crtc *c)
86{
87 return container_of(c, struct mtk_crtc, base);
88}
89
90static inline struct mtk_crtc_state *to_mtk_crtc_state(struct drm_crtc_state *s)
91{
92 return container_of(s, struct mtk_crtc_state, base);
93}
94
95static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
96{
97 struct drm_crtc *crtc = &mtk_crtc->base;
98 unsigned long flags;
99
100 if (mtk_crtc->event) {
101 spin_lock_irqsave(&crtc->dev->event_lock, flags);
102 drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
103 drm_crtc_vblank_put(crtc);
104 mtk_crtc->event = NULL;
105 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
106 }
107}
108
109static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
110{
111 unsigned long flags;
112
113 drm_crtc_handle_vblank(&mtk_crtc->base);
114
115 spin_lock_irqsave(&mtk_crtc->config_lock, flags);
116 if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
117 mtk_crtc_finish_page_flip(mtk_crtc);
118 mtk_crtc->pending_needs_vblank = false;
119 }
120 spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
121}
122
123static void mtk_crtc_destroy(struct drm_crtc *crtc)
124{
125 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
126 int i;
127
128 mtk_mutex_put(mtk_crtc->mutex);
129#if IS_REACHABLE(CONFIG_MTK_CMDQ)
130 cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle);
131
132 if (mtk_crtc->cmdq_client.chan) {
133 mbox_free_channel(mtk_crtc->cmdq_client.chan);
134 mtk_crtc->cmdq_client.chan = NULL;
135 }
136#endif
137
138 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
139 struct mtk_ddp_comp *comp;
140
141 comp = mtk_crtc->ddp_comp[i];
142 mtk_ddp_comp_unregister_vblank_cb(comp);
143 }
144
145 drm_crtc_cleanup(crtc);
146}
147
148static void mtk_crtc_reset(struct drm_crtc *crtc)
149{
150 struct mtk_crtc_state *state;
151
152 if (crtc->state)
153 __drm_atomic_helper_crtc_destroy_state(crtc->state);
154
155 kfree(to_mtk_crtc_state(crtc->state));
156 crtc->state = NULL;
157
158 state = kzalloc(sizeof(*state), GFP_KERNEL);
159 if (state)
160 __drm_atomic_helper_crtc_reset(crtc, &state->base);
161}
162
163static struct drm_crtc_state *mtk_crtc_duplicate_state(struct drm_crtc *crtc)
164{
165 struct mtk_crtc_state *state;
166
167 state = kmalloc(sizeof(*state), GFP_KERNEL);
168 if (!state)
169 return NULL;
170
171 __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
172
173 WARN_ON(state->base.crtc != crtc);
174 state->base.crtc = crtc;
175 state->pending_config = false;
176
177 return &state->base;
178}
179
180static void mtk_crtc_destroy_state(struct drm_crtc *crtc,
181 struct drm_crtc_state *state)
182{
183 __drm_atomic_helper_crtc_destroy_state(state);
184 kfree(to_mtk_crtc_state(state));
185}
186
187static enum drm_mode_status
188mtk_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
189{
190 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
191 enum drm_mode_status status = MODE_OK;
192 int i;
193
194 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
195 status = mtk_ddp_comp_mode_valid(mtk_crtc->ddp_comp[i], mode);
196 if (status != MODE_OK)
197 break;
198 }
199 return status;
200}
201
202static bool mtk_crtc_mode_fixup(struct drm_crtc *crtc,
203 const struct drm_display_mode *mode,
204 struct drm_display_mode *adjusted_mode)
205{
206 /* Nothing to do here, but this callback is mandatory. */
207 return true;
208}
209
210static void mtk_crtc_mode_set_nofb(struct drm_crtc *crtc)
211{
212 struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state);
213
214 state->pending_width = crtc->mode.hdisplay;
215 state->pending_height = crtc->mode.vdisplay;
216 state->pending_vrefresh = drm_mode_vrefresh(&crtc->mode);
217 wmb(); /* Make sure the above parameters are set before update */
218 state->pending_config = true;
219}
220
221static int mtk_crtc_ddp_clk_enable(struct mtk_crtc *mtk_crtc)
222{
223 int ret;
224 int i;
225
226 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
227 ret = mtk_ddp_comp_clk_enable(mtk_crtc->ddp_comp[i]);
228 if (ret) {
229 DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
230 goto err;
231 }
232 }
233
234 return 0;
235err:
236 while (--i >= 0)
237 mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
238 return ret;
239}
240
241static void mtk_crtc_ddp_clk_disable(struct mtk_crtc *mtk_crtc)
242{
243 int i;
244
245 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
246 mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
247}
248
249static
250struct mtk_ddp_comp *mtk_ddp_comp_for_plane(struct drm_crtc *crtc,
251 struct drm_plane *plane,
252 unsigned int *local_layer)
253{
254 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
255 struct mtk_ddp_comp *comp;
256 int i, count = 0;
257 unsigned int local_index = plane - mtk_crtc->planes;
258
259 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
260 comp = mtk_crtc->ddp_comp[i];
261 if (local_index < (count + mtk_ddp_comp_layer_nr(comp))) {
262 *local_layer = local_index - count;
263 return comp;
264 }
265 count += mtk_ddp_comp_layer_nr(comp);
266 }
267
268 WARN(1, "Failed to find component for plane %d\n", plane->index);
269 return NULL;
270}
271
272#if IS_REACHABLE(CONFIG_MTK_CMDQ)
273static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
274{
275 struct cmdq_cb_data *data = mssg;
276 struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client);
277 struct mtk_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_crtc, cmdq_client);
278 struct mtk_crtc_state *state;
279 unsigned int i;
280 unsigned long flags;
281
282 if (data->sta < 0)
283 return;
284
285 state = to_mtk_crtc_state(mtk_crtc->base.state);
286
287 spin_lock_irqsave(&mtk_crtc->config_lock, flags);
288 if (mtk_crtc->config_updating) {
289 spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
290 goto ddp_cmdq_cb_out;
291 }
292
293 state->pending_config = false;
294
295 if (mtk_crtc->pending_planes) {
296 for (i = 0; i < mtk_crtc->layer_nr; i++) {
297 struct drm_plane *plane = &mtk_crtc->planes[i];
298 struct mtk_plane_state *plane_state;
299
300 plane_state = to_mtk_plane_state(plane->state);
301
302 plane_state->pending.config = false;
303 }
304 mtk_crtc->pending_planes = false;
305 }
306
307 if (mtk_crtc->pending_async_planes) {
308 for (i = 0; i < mtk_crtc->layer_nr; i++) {
309 struct drm_plane *plane = &mtk_crtc->planes[i];
310 struct mtk_plane_state *plane_state;
311
312 plane_state = to_mtk_plane_state(plane->state);
313
314 plane_state->pending.async_config = false;
315 }
316 mtk_crtc->pending_async_planes = false;
317 }
318
319 spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
320
321ddp_cmdq_cb_out:
322
323 mtk_crtc->cmdq_vblank_cnt = 0;
324 wake_up(&mtk_crtc->cb_blocking_queue);
325}
326#endif
327
328static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)
329{
330 struct drm_crtc *crtc = &mtk_crtc->base;
331 struct drm_connector *connector;
332 struct drm_encoder *encoder;
333 struct drm_connector_list_iter conn_iter;
334 unsigned int width, height, vrefresh, bpc = MTK_MAX_BPC;
335 int ret;
336 int i;
337
338 if (WARN_ON(!crtc->state))
339 return -EINVAL;
340
341 width = crtc->state->adjusted_mode.hdisplay;
342 height = crtc->state->adjusted_mode.vdisplay;
343 vrefresh = drm_mode_vrefresh(&crtc->state->adjusted_mode);
344
345 drm_for_each_encoder(encoder, crtc->dev) {
346 if (encoder->crtc != crtc)
347 continue;
348
349 drm_connector_list_iter_begin(crtc->dev, &conn_iter);
350 drm_for_each_connector_iter(connector, &conn_iter) {
351 if (connector->encoder != encoder)
352 continue;
353 if (connector->display_info.bpc != 0 &&
354 bpc > connector->display_info.bpc)
355 bpc = connector->display_info.bpc;
356 }
357 drm_connector_list_iter_end(&conn_iter);
358 }
359
360 ret = pm_runtime_resume_and_get(crtc->dev->dev);
361 if (ret < 0) {
362 DRM_ERROR("Failed to enable power domain: %d\n", ret);
363 return ret;
364 }
365
366 ret = mtk_mutex_prepare(mtk_crtc->mutex);
367 if (ret < 0) {
368 DRM_ERROR("Failed to enable mutex clock: %d\n", ret);
369 goto err_pm_runtime_put;
370 }
371
372 ret = mtk_crtc_ddp_clk_enable(mtk_crtc);
373 if (ret < 0) {
374 DRM_ERROR("Failed to enable component clocks: %d\n", ret);
375 goto err_mutex_unprepare;
376 }
377
378 for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
379 if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev,
380 mtk_crtc->ddp_comp[i + 1]->id))
381 mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
382 mtk_crtc->ddp_comp[i]->id,
383 mtk_crtc->ddp_comp[i + 1]->id);
384 if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
385 mtk_mutex_add_comp(mtk_crtc->mutex,
386 mtk_crtc->ddp_comp[i]->id);
387 }
388 if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
389 mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
390 mtk_mutex_enable(mtk_crtc->mutex);
391
392 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
393 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
394
395 if (i == 1)
396 mtk_ddp_comp_bgclr_in_on(comp);
397
398 mtk_ddp_comp_config(comp, width, height, vrefresh, bpc, NULL);
399 mtk_ddp_comp_start(comp);
400 }
401
402 /* Initially configure all planes */
403 for (i = 0; i < mtk_crtc->layer_nr; i++) {
404 struct drm_plane *plane = &mtk_crtc->planes[i];
405 struct mtk_plane_state *plane_state;
406 struct mtk_ddp_comp *comp;
407 unsigned int local_layer;
408
409 plane_state = to_mtk_plane_state(plane->state);
410
411 /* should not enable layer before crtc enabled */
412 plane_state->pending.enable = false;
413 comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
414 if (comp)
415 mtk_ddp_comp_layer_config(comp, local_layer,
416 plane_state, NULL);
417 }
418
419 return 0;
420
421err_mutex_unprepare:
422 mtk_mutex_unprepare(mtk_crtc->mutex);
423err_pm_runtime_put:
424 pm_runtime_put(crtc->dev->dev);
425 return ret;
426}
427
428static void mtk_crtc_ddp_hw_fini(struct mtk_crtc *mtk_crtc)
429{
430 struct drm_device *drm = mtk_crtc->base.dev;
431 struct drm_crtc *crtc = &mtk_crtc->base;
432 unsigned long flags;
433 int i;
434
435 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
436 mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]);
437 if (i == 1)
438 mtk_ddp_comp_bgclr_in_off(mtk_crtc->ddp_comp[i]);
439 }
440
441 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
442 if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
443 mtk_mutex_remove_comp(mtk_crtc->mutex,
444 mtk_crtc->ddp_comp[i]->id);
445 mtk_mutex_disable(mtk_crtc->mutex);
446 for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
447 if (!mtk_ddp_comp_disconnect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev,
448 mtk_crtc->ddp_comp[i + 1]->id))
449 mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
450 mtk_crtc->ddp_comp[i]->id,
451 mtk_crtc->ddp_comp[i + 1]->id);
452 if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
453 mtk_mutex_remove_comp(mtk_crtc->mutex,
454 mtk_crtc->ddp_comp[i]->id);
455 }
456 if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
457 mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
458 mtk_crtc_ddp_clk_disable(mtk_crtc);
459 mtk_mutex_unprepare(mtk_crtc->mutex);
460
461 pm_runtime_put(drm->dev);
462
463 if (crtc->state->event && !crtc->state->active) {
464 spin_lock_irqsave(&crtc->dev->event_lock, flags);
465 drm_crtc_send_vblank_event(crtc, crtc->state->event);
466 crtc->state->event = NULL;
467 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
468 }
469}
470
471static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
472 struct cmdq_pkt *cmdq_handle)
473{
474 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
475 struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
476 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
477 unsigned int i;
478 unsigned int local_layer;
479
480 /*
481 * TODO: instead of updating the registers here, we should prepare
482 * working registers in atomic_commit and let the hardware command
483 * queue update module registers on vblank.
484 */
485 if (state->pending_config) {
486 mtk_ddp_comp_config(comp, state->pending_width,
487 state->pending_height,
488 state->pending_vrefresh, 0,
489 cmdq_handle);
490
491 if (!cmdq_handle)
492 state->pending_config = false;
493 }
494
495 if (mtk_crtc->pending_planes) {
496 for (i = 0; i < mtk_crtc->layer_nr; i++) {
497 struct drm_plane *plane = &mtk_crtc->planes[i];
498 struct mtk_plane_state *plane_state;
499
500 plane_state = to_mtk_plane_state(plane->state);
501
502 if (!plane_state->pending.config)
503 continue;
504
505 comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
506
507 if (comp)
508 mtk_ddp_comp_layer_config(comp, local_layer,
509 plane_state,
510 cmdq_handle);
511 if (!cmdq_handle)
512 plane_state->pending.config = false;
513 }
514
515 if (!cmdq_handle)
516 mtk_crtc->pending_planes = false;
517 }
518
519 if (mtk_crtc->pending_async_planes) {
520 for (i = 0; i < mtk_crtc->layer_nr; i++) {
521 struct drm_plane *plane = &mtk_crtc->planes[i];
522 struct mtk_plane_state *plane_state;
523
524 plane_state = to_mtk_plane_state(plane->state);
525
526 if (!plane_state->pending.async_config)
527 continue;
528
529 comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
530
531 if (comp)
532 mtk_ddp_comp_layer_config(comp, local_layer,
533 plane_state,
534 cmdq_handle);
535 if (!cmdq_handle)
536 plane_state->pending.async_config = false;
537 }
538
539 if (!cmdq_handle)
540 mtk_crtc->pending_async_planes = false;
541 }
542}
543
544static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
545{
546#if IS_REACHABLE(CONFIG_MTK_CMDQ)
547 struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
548#endif
549 struct drm_crtc *crtc = &mtk_crtc->base;
550 struct mtk_drm_private *priv = crtc->dev->dev_private;
551 unsigned int pending_planes = 0, pending_async_planes = 0;
552 int i;
553 unsigned long flags;
554
555 mutex_lock(&mtk_crtc->hw_lock);
556
557 spin_lock_irqsave(&mtk_crtc->config_lock, flags);
558 mtk_crtc->config_updating = true;
559 spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
560
561 if (needs_vblank)
562 mtk_crtc->pending_needs_vblank = true;
563
564 for (i = 0; i < mtk_crtc->layer_nr; i++) {
565 struct drm_plane *plane = &mtk_crtc->planes[i];
566 struct mtk_plane_state *plane_state;
567
568 plane_state = to_mtk_plane_state(plane->state);
569 if (plane_state->pending.dirty) {
570 plane_state->pending.config = true;
571 plane_state->pending.dirty = false;
572 pending_planes |= BIT(i);
573 } else if (plane_state->pending.async_dirty) {
574 plane_state->pending.async_config = true;
575 plane_state->pending.async_dirty = false;
576 pending_async_planes |= BIT(i);
577 }
578 }
579 if (pending_planes)
580 mtk_crtc->pending_planes = true;
581 if (pending_async_planes)
582 mtk_crtc->pending_async_planes = true;
583
584 if (priv->data->shadow_register) {
585 mtk_mutex_acquire(mtk_crtc->mutex);
586 mtk_crtc_ddp_config(crtc, NULL);
587 mtk_mutex_release(mtk_crtc->mutex);
588 }
589#if IS_REACHABLE(CONFIG_MTK_CMDQ)
590 if (mtk_crtc->cmdq_client.chan) {
591 mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
592 cmdq_handle->cmd_buf_size = 0;
593 cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
594 cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
595 mtk_crtc_ddp_config(crtc, cmdq_handle);
596 cmdq_pkt_eoc(cmdq_handle);
597 dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
598 cmdq_handle->pa_base,
599 cmdq_handle->cmd_buf_size,
600 DMA_TO_DEVICE);
601 /*
602 * CMDQ command should execute in next 3 vblank.
603 * One vblank interrupt before send message (occasionally)
604 * and one vblank interrupt after cmdq done,
605 * so it's timeout after 3 vblank interrupt.
606 * If it fail to execute in next 3 vblank, timeout happen.
607 */
608 mtk_crtc->cmdq_vblank_cnt = 3;
609
610 mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
611 mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
612 }
613#endif
614 spin_lock_irqsave(&mtk_crtc->config_lock, flags);
615 mtk_crtc->config_updating = false;
616 spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
617
618 mutex_unlock(&mtk_crtc->hw_lock);
619}
620
621static void mtk_crtc_ddp_irq(void *data)
622{
623 struct drm_crtc *crtc = data;
624 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
625 struct mtk_drm_private *priv = crtc->dev->dev_private;
626
627#if IS_REACHABLE(CONFIG_MTK_CMDQ)
628 if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
629 mtk_crtc_ddp_config(crtc, NULL);
630 else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
631 DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
632 drm_crtc_index(&mtk_crtc->base));
633#else
634 if (!priv->data->shadow_register)
635 mtk_crtc_ddp_config(crtc, NULL);
636#endif
637 mtk_drm_finish_page_flip(mtk_crtc);
638}
639
640static int mtk_crtc_enable_vblank(struct drm_crtc *crtc)
641{
642 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
643 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
644
645 mtk_ddp_comp_enable_vblank(comp);
646
647 return 0;
648}
649
650static void mtk_crtc_disable_vblank(struct drm_crtc *crtc)
651{
652 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
653 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
654
655 mtk_ddp_comp_disable_vblank(comp);
656}
657
658static void mtk_crtc_update_output(struct drm_crtc *crtc,
659 struct drm_atomic_state *state)
660{
661 int crtc_index = drm_crtc_index(crtc);
662 int i;
663 struct device *dev;
664 struct drm_crtc_state *crtc_state = state->crtcs[crtc_index].new_state;
665 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
666 struct mtk_drm_private *priv;
667 unsigned int encoder_mask = crtc_state->encoder_mask;
668
669 if (!crtc_state->connectors_changed)
670 return;
671
672 if (!mtk_crtc->num_conn_routes)
673 return;
674
675 priv = ((struct mtk_drm_private *)crtc->dev->dev_private)->all_drm_private[crtc_index];
676 dev = priv->dev;
677
678 dev_dbg(dev, "connector change:%d, encoder mask:0x%x for crtc:%d\n",
679 crtc_state->connectors_changed, encoder_mask, crtc_index);
680
681 for (i = 0; i < mtk_crtc->num_conn_routes; i++) {
682 unsigned int comp_id = mtk_crtc->conn_routes[i].route_ddp;
683 struct mtk_ddp_comp *comp = &priv->ddp_comp[comp_id];
684
685 if (comp->encoder_index >= 0 &&
686 (encoder_mask & BIT(comp->encoder_index))) {
687 mtk_crtc->ddp_comp[mtk_crtc->ddp_comp_nr - 1] = comp;
688 dev_dbg(dev, "Add comp_id: %d at path index %d\n",
689 comp->id, mtk_crtc->ddp_comp_nr - 1);
690 break;
691 }
692 }
693}
694
695int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
696 struct mtk_plane_state *state)
697{
698 unsigned int local_layer;
699 struct mtk_ddp_comp *comp;
700
701 comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
702 if (comp)
703 return mtk_ddp_comp_layer_check(comp, local_layer, state);
704 return 0;
705}
706
707void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
708 struct drm_atomic_state *state)
709{
710 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
711
712 if (!mtk_crtc->enabled)
713 return;
714
715 mtk_crtc_update_config(mtk_crtc, false);
716}
717
718static void mtk_crtc_atomic_enable(struct drm_crtc *crtc,
719 struct drm_atomic_state *state)
720{
721 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
722 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
723 int ret;
724
725 DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
726
727 ret = mtk_ddp_comp_power_on(comp);
728 if (ret < 0) {
729 DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
730 return;
731 }
732
733 mtk_crtc_update_output(crtc, state);
734
735 ret = mtk_crtc_ddp_hw_init(mtk_crtc);
736 if (ret) {
737 mtk_ddp_comp_power_off(comp);
738 return;
739 }
740
741 drm_crtc_vblank_on(crtc);
742 mtk_crtc->enabled = true;
743}
744
745static void mtk_crtc_atomic_disable(struct drm_crtc *crtc,
746 struct drm_atomic_state *state)
747{
748 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
749 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
750 int i;
751
752 DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
753 if (!mtk_crtc->enabled)
754 return;
755
756 /* Set all pending plane state to disabled */
757 for (i = 0; i < mtk_crtc->layer_nr; i++) {
758 struct drm_plane *plane = &mtk_crtc->planes[i];
759 struct mtk_plane_state *plane_state;
760
761 plane_state = to_mtk_plane_state(plane->state);
762 plane_state->pending.enable = false;
763 plane_state->pending.config = true;
764 }
765 mtk_crtc->pending_planes = true;
766
767 mtk_crtc_update_config(mtk_crtc, false);
768#if IS_REACHABLE(CONFIG_MTK_CMDQ)
769 /* Wait for planes to be disabled by cmdq */
770 if (mtk_crtc->cmdq_client.chan)
771 wait_event_timeout(mtk_crtc->cb_blocking_queue,
772 mtk_crtc->cmdq_vblank_cnt == 0,
773 msecs_to_jiffies(500));
774#endif
775 /* Wait for planes to be disabled */
776 drm_crtc_wait_one_vblank(crtc);
777
778 drm_crtc_vblank_off(crtc);
779 mtk_crtc_ddp_hw_fini(mtk_crtc);
780 mtk_ddp_comp_power_off(comp);
781
782 mtk_crtc->enabled = false;
783}
784
785static void mtk_crtc_atomic_begin(struct drm_crtc *crtc,
786 struct drm_atomic_state *state)
787{
788 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
789 crtc);
790 struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state);
791 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
792 unsigned long flags;
793
794 if (mtk_crtc->event && mtk_crtc_state->base.event)
795 DRM_ERROR("new event while there is still a pending event\n");
796
797 if (mtk_crtc_state->base.event) {
798 mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc);
799 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
800
801 spin_lock_irqsave(&crtc->dev->event_lock, flags);
802 mtk_crtc->event = mtk_crtc_state->base.event;
803 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
804
805 mtk_crtc_state->base.event = NULL;
806 }
807}
808
809static void mtk_crtc_atomic_flush(struct drm_crtc *crtc,
810 struct drm_atomic_state *state)
811{
812 struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
813 int i;
814
815 if (crtc->state->color_mgmt_changed)
816 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
817 mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
818 mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);
819 }
820 mtk_crtc_update_config(mtk_crtc, !!mtk_crtc->event);
821}
822
823static const struct drm_crtc_funcs mtk_crtc_funcs = {
824 .set_config = drm_atomic_helper_set_config,
825 .page_flip = drm_atomic_helper_page_flip,
826 .destroy = mtk_crtc_destroy,
827 .reset = mtk_crtc_reset,
828 .atomic_duplicate_state = mtk_crtc_duplicate_state,
829 .atomic_destroy_state = mtk_crtc_destroy_state,
830 .enable_vblank = mtk_crtc_enable_vblank,
831 .disable_vblank = mtk_crtc_disable_vblank,
832};
833
834static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
835 .mode_fixup = mtk_crtc_mode_fixup,
836 .mode_set_nofb = mtk_crtc_mode_set_nofb,
837 .mode_valid = mtk_crtc_mode_valid,
838 .atomic_begin = mtk_crtc_atomic_begin,
839 .atomic_flush = mtk_crtc_atomic_flush,
840 .atomic_enable = mtk_crtc_atomic_enable,
841 .atomic_disable = mtk_crtc_atomic_disable,
842};
843
844static int mtk_crtc_init(struct drm_device *drm, struct mtk_crtc *mtk_crtc,
845 unsigned int pipe)
846{
847 struct drm_plane *primary = NULL;
848 struct drm_plane *cursor = NULL;
849 int i, ret;
850
851 for (i = 0; i < mtk_crtc->layer_nr; i++) {
852 if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_PRIMARY)
853 primary = &mtk_crtc->planes[i];
854 else if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_CURSOR)
855 cursor = &mtk_crtc->planes[i];
856 }
857
858 ret = drm_crtc_init_with_planes(drm, &mtk_crtc->base, primary, cursor,
859 &mtk_crtc_funcs, NULL);
860 if (ret)
861 goto err_cleanup_crtc;
862
863 drm_crtc_helper_add(&mtk_crtc->base, &mtk_crtc_helper_funcs);
864
865 return 0;
866
867err_cleanup_crtc:
868 drm_crtc_cleanup(&mtk_crtc->base);
869 return ret;
870}
871
872static int mtk_crtc_num_comp_planes(struct mtk_crtc *mtk_crtc, int comp_idx)
873{
874 struct mtk_ddp_comp *comp;
875
876 if (comp_idx > 1)
877 return 0;
878
879 comp = mtk_crtc->ddp_comp[comp_idx];
880 if (!comp->funcs)
881 return 0;
882
883 if (comp_idx == 1 && !comp->funcs->bgclr_in_on)
884 return 0;
885
886 return mtk_ddp_comp_layer_nr(comp);
887}
888
889static inline
890enum drm_plane_type mtk_crtc_plane_type(unsigned int plane_idx,
891 unsigned int num_planes)
892{
893 if (plane_idx == 0)
894 return DRM_PLANE_TYPE_PRIMARY;
895 else if (plane_idx == (num_planes - 1))
896 return DRM_PLANE_TYPE_CURSOR;
897 else
898 return DRM_PLANE_TYPE_OVERLAY;
899
900}
901
902static int mtk_crtc_init_comp_planes(struct drm_device *drm_dev,
903 struct mtk_crtc *mtk_crtc,
904 int comp_idx, int pipe)
905{
906 int num_planes = mtk_crtc_num_comp_planes(mtk_crtc, comp_idx);
907 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
908 int i, ret;
909
910 for (i = 0; i < num_planes; i++) {
911 ret = mtk_plane_init(drm_dev,
912 &mtk_crtc->planes[mtk_crtc->layer_nr],
913 BIT(pipe),
914 mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes),
915 mtk_ddp_comp_supported_rotations(comp),
916 mtk_ddp_comp_get_formats(comp),
917 mtk_ddp_comp_get_num_formats(comp), i);
918 if (ret)
919 return ret;
920
921 mtk_crtc->layer_nr++;
922 }
923 return 0;
924}
925
926struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc)
927{
928 struct mtk_crtc *mtk_crtc = NULL;
929
930 if (!crtc)
931 return NULL;
932
933 mtk_crtc = to_mtk_crtc(crtc);
934 if (!mtk_crtc)
935 return NULL;
936
937 return mtk_crtc->dma_dev;
938}
939
940int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
941 unsigned int path_len, int priv_data_index,
942 const struct mtk_drm_route *conn_routes,
943 unsigned int num_conn_routes)
944{
945 struct mtk_drm_private *priv = drm_dev->dev_private;
946 struct device *dev = drm_dev->dev;
947 struct mtk_crtc *mtk_crtc;
948 unsigned int num_comp_planes = 0;
949 int ret;
950 int i;
951 bool has_ctm = false;
952 uint gamma_lut_size = 0;
953 struct drm_crtc *tmp;
954 int crtc_i = 0;
955
956 if (!path)
957 return 0;
958
959 priv = priv->all_drm_private[priv_data_index];
960
961 drm_for_each_crtc(tmp, drm_dev)
962 crtc_i++;
963
964 for (i = 0; i < path_len; i++) {
965 enum mtk_ddp_comp_id comp_id = path[i];
966 struct device_node *node;
967 struct mtk_ddp_comp *comp;
968
969 node = priv->comp_node[comp_id];
970 comp = &priv->ddp_comp[comp_id];
971
972 /* Not all drm components have a DTS device node, such as ovl_adaptor,
973 * which is the drm bring up sub driver
974 */
975 if (!node && comp_id != DDP_COMPONENT_DRM_OVL_ADAPTOR) {
976 dev_info(dev,
977 "Not creating crtc %d because component %d is disabled or missing\n",
978 crtc_i, comp_id);
979 return 0;
980 }
981
982 if (!comp->dev) {
983 dev_err(dev, "Component %pOF not initialized\n", node);
984 return -ENODEV;
985 }
986 }
987
988 mtk_crtc = devm_kzalloc(dev, sizeof(*mtk_crtc), GFP_KERNEL);
989 if (!mtk_crtc)
990 return -ENOMEM;
991
992 mtk_crtc->mmsys_dev = priv->mmsys_dev;
993 mtk_crtc->ddp_comp_nr = path_len;
994 mtk_crtc->ddp_comp = devm_kcalloc(dev,
995 mtk_crtc->ddp_comp_nr + (conn_routes ? 1 : 0),
996 sizeof(*mtk_crtc->ddp_comp),
997 GFP_KERNEL);
998 if (!mtk_crtc->ddp_comp)
999 return -ENOMEM;
1000
1001 mtk_crtc->mutex = mtk_mutex_get(priv->mutex_dev);
1002 if (IS_ERR(mtk_crtc->mutex)) {
1003 ret = PTR_ERR(mtk_crtc->mutex);
1004 dev_err(dev, "Failed to get mutex: %d\n", ret);
1005 return ret;
1006 }
1007
1008 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
1009 unsigned int comp_id = path[i];
1010 struct mtk_ddp_comp *comp;
1011
1012 comp = &priv->ddp_comp[comp_id];
1013 mtk_crtc->ddp_comp[i] = comp;
1014
1015 if (comp->funcs) {
1016 if (comp->funcs->gamma_set && comp->funcs->gamma_get_lut_size) {
1017 unsigned int lut_sz = mtk_ddp_gamma_get_lut_size(comp);
1018
1019 if (lut_sz)
1020 gamma_lut_size = lut_sz;
1021 }
1022
1023 if (comp->funcs->ctm_set)
1024 has_ctm = true;
1025 }
1026
1027 mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
1028 &mtk_crtc->base);
1029 }
1030
1031 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
1032 num_comp_planes += mtk_crtc_num_comp_planes(mtk_crtc, i);
1033
1034 mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
1035 sizeof(struct drm_plane), GFP_KERNEL);
1036 if (!mtk_crtc->planes)
1037 return -ENOMEM;
1038
1039 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
1040 ret = mtk_crtc_init_comp_planes(drm_dev, mtk_crtc, i, crtc_i);
1041 if (ret)
1042 return ret;
1043 }
1044
1045 /*
1046 * Default to use the first component as the dma dev.
1047 * In the case of ovl_adaptor sub driver, it needs to use the
1048 * dma_dev_get function to get representative dma dev.
1049 */
1050 mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv->ddp_comp[path[0]]);
1051
1052 ret = mtk_crtc_init(drm_dev, mtk_crtc, crtc_i);
1053 if (ret < 0)
1054 return ret;
1055
1056 if (gamma_lut_size)
1057 drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
1058 drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
1059 mutex_init(&mtk_crtc->hw_lock);
1060 spin_lock_init(&mtk_crtc->config_lock);
1061
1062#if IS_REACHABLE(CONFIG_MTK_CMDQ)
1063 i = priv->mbox_index++;
1064 mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
1065 mtk_crtc->cmdq_client.client.tx_block = false;
1066 mtk_crtc->cmdq_client.client.knows_txdone = true;
1067 mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
1068 mtk_crtc->cmdq_client.chan =
1069 mbox_request_channel(&mtk_crtc->cmdq_client.client, i);
1070 if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
1071 dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
1072 drm_crtc_index(&mtk_crtc->base));
1073 mtk_crtc->cmdq_client.chan = NULL;
1074 }
1075
1076 if (mtk_crtc->cmdq_client.chan) {
1077 ret = of_property_read_u32_index(priv->mutex_node,
1078 "mediatek,gce-events",
1079 i,
1080 &mtk_crtc->cmdq_event);
1081 if (ret) {
1082 dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
1083 drm_crtc_index(&mtk_crtc->base));
1084 mbox_free_channel(mtk_crtc->cmdq_client.chan);
1085 mtk_crtc->cmdq_client.chan = NULL;
1086 } else {
1087 ret = cmdq_pkt_create(&mtk_crtc->cmdq_client,
1088 &mtk_crtc->cmdq_handle,
1089 PAGE_SIZE);
1090 if (ret) {
1091 dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
1092 drm_crtc_index(&mtk_crtc->base));
1093 mbox_free_channel(mtk_crtc->cmdq_client.chan);
1094 mtk_crtc->cmdq_client.chan = NULL;
1095 }
1096 }
1097
1098 /* for sending blocking cmd in crtc disable */
1099 init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
1100 }
1101#endif
1102
1103 if (conn_routes) {
1104 for (i = 0; i < num_conn_routes; i++) {
1105 unsigned int comp_id = conn_routes[i].route_ddp;
1106 struct device_node *node = priv->comp_node[comp_id];
1107 struct mtk_ddp_comp *comp = &priv->ddp_comp[comp_id];
1108
1109 if (!comp->dev) {
1110 dev_dbg(dev, "comp_id:%d, Component %pOF not initialized\n",
1111 comp_id, node);
1112 /* mark encoder_index to -1, if route comp device is not enabled */
1113 comp->encoder_index = -1;
1114 continue;
1115 }
1116
1117 mtk_ddp_comp_encoder_index_set(&priv->ddp_comp[comp_id]);
1118 }
1119
1120 mtk_crtc->num_conn_routes = num_conn_routes;
1121 mtk_crtc->conn_routes = conn_routes;
1122
1123 /* increase ddp_comp_nr at the end of mtk_crtc_create */
1124 mtk_crtc->ddp_comp_nr++;
1125 }
1126
1127 return 0;
1128}