forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
....@@ -1,24 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015 MediaTek Inc.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
14
-#include <asm/barrier.h>
15
-#include <drm/drmP.h>
16
-#include <drm/drm_atomic_helper.h>
17
-#include <drm/drm_crtc_helper.h>
18
-#include <drm/drm_plane_helper.h>
196 #include <linux/clk.h>
207 #include <linux/pm_runtime.h>
8
+#include <linux/soc/mediatek/mtk-cmdq.h>
9
+#include <linux/soc/mediatek/mtk-mmsys.h>
10
+
11
+#include <asm/barrier.h>
2112 #include <soc/mediatek/smi.h>
13
+
14
+#include <drm/drm_atomic_helper.h>
15
+#include <drm/drm_plane_helper.h>
16
+#include <drm/drm_probe_helper.h>
17
+#include <drm/drm_vblank.h>
2218
2319 #include "mtk_drm_drv.h"
2420 #include "mtk_drm_crtc.h"
....@@ -33,7 +29,7 @@
3329 * @enabled: records whether crtc_enable succeeded
3430 * @planes: array of 4 drm_plane structures, one for each overlay plane
3531 * @pending_planes: whether any plane has pending changes to be applied
36
- * @config_regs: memory mapped mmsys configuration register space
32
+ * @mmsys_dev: pointer to the mmsys device for configuration registers
3733 * @mutex: handle to one of the ten disp_mutex streams
3834 * @ddp_comp_nr: number of components in ddp_comp
3935 * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
....@@ -48,11 +44,20 @@
4844 struct drm_plane *planes;
4945 unsigned int layer_nr;
5046 bool pending_planes;
47
+ bool pending_async_planes;
5148
52
- void __iomem *config_regs;
49
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
50
+ struct cmdq_client *cmdq_client;
51
+ u32 cmdq_event;
52
+#endif
53
+
54
+ struct device *mmsys_dev;
5355 struct mtk_disp_mutex *mutex;
5456 unsigned int ddp_comp_nr;
5557 struct mtk_ddp_comp **ddp_comp;
58
+
59
+ /* lock for display hardware access */
60
+ struct mutex hw_lock;
5661 };
5762
5863 struct mtk_crtc_state {
....@@ -98,10 +103,6 @@
98103 static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
99104 {
100105 struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
101
- int i;
102
-
103
- for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
104
- clk_unprepare(mtk_crtc->ddp_comp[i]->clk);
105106
106107 mtk_disp_mutex_put(mtk_crtc->mutex);
107108
....@@ -112,19 +113,15 @@
112113 {
113114 struct mtk_crtc_state *state;
114115
115
- if (crtc->state) {
116
+ if (crtc->state)
116117 __drm_atomic_helper_crtc_destroy_state(crtc->state);
117118
118
- state = to_mtk_crtc_state(crtc->state);
119
- memset(state, 0, sizeof(*state));
120
- } else {
121
- state = kzalloc(sizeof(*state), GFP_KERNEL);
122
- if (!state)
123
- return;
124
- crtc->state = &state->base;
125
- }
119
+ kfree(to_mtk_crtc_state(crtc->state));
120
+ crtc->state = NULL;
126121
127
- state->base.crtc = crtc;
122
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
123
+ if (state)
124
+ __drm_atomic_helper_crtc_reset(crtc, &state->base);
128125 }
129126
130127 static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc)
....@@ -164,7 +161,7 @@
164161
165162 state->pending_width = crtc->mode.hdisplay;
166163 state->pending_height = crtc->mode.vdisplay;
167
- state->pending_vrefresh = crtc->mode.vrefresh;
164
+ state->pending_vrefresh = drm_mode_vrefresh(&crtc->mode);
168165 wmb(); /* Make sure the above parameters are set before update */
169166 state->pending_config = true;
170167 }
....@@ -192,9 +189,8 @@
192189 int ret;
193190 int i;
194191
195
- DRM_DEBUG_DRIVER("%s\n", __func__);
196192 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
197
- ret = clk_enable(mtk_crtc->ddp_comp[i]->clk);
193
+ ret = clk_prepare_enable(mtk_crtc->ddp_comp[i]->clk);
198194 if (ret) {
199195 DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
200196 goto err;
....@@ -204,7 +200,7 @@
204200 return 0;
205201 err:
206202 while (--i >= 0)
207
- clk_disable(mtk_crtc->ddp_comp[i]->clk);
203
+ clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
208204 return ret;
209205 }
210206
....@@ -212,10 +208,39 @@
212208 {
213209 int i;
214210
215
- DRM_DEBUG_DRIVER("%s\n", __func__);
216211 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
217
- clk_disable(mtk_crtc->ddp_comp[i]->clk);
212
+ clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
218213 }
214
+
215
+static
216
+struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
217
+ struct drm_plane *plane,
218
+ unsigned int *local_layer)
219
+{
220
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
221
+ struct mtk_ddp_comp *comp;
222
+ int i, count = 0;
223
+ unsigned int local_index = plane - mtk_crtc->planes;
224
+
225
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
226
+ comp = mtk_crtc->ddp_comp[i];
227
+ if (local_index < (count + mtk_ddp_comp_layer_nr(comp))) {
228
+ *local_layer = local_index - count;
229
+ return comp;
230
+ }
231
+ count += mtk_ddp_comp_layer_nr(comp);
232
+ }
233
+
234
+ WARN(1, "Failed to find component for plane %d\n", plane->index);
235
+ return NULL;
236
+}
237
+
238
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
239
+static void ddp_cmdq_cb(struct cmdq_cb_data data)
240
+{
241
+ cmdq_pkt_destroy(data.data);
242
+}
243
+#endif
219244
220245 static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
221246 {
....@@ -227,13 +252,12 @@
227252 int ret;
228253 int i;
229254
230
- DRM_DEBUG_DRIVER("%s\n", __func__);
231255 if (WARN_ON(!crtc->state))
232256 return -EINVAL;
233257
234258 width = crtc->state->adjusted_mode.hdisplay;
235259 height = crtc->state->adjusted_mode.vdisplay;
236
- vrefresh = crtc->state->adjusted_mode.vrefresh;
260
+ vrefresh = drm_mode_vrefresh(&crtc->state->adjusted_mode);
237261
238262 drm_for_each_encoder(encoder, crtc->dev) {
239263 if (encoder->crtc != crtc)
....@@ -250,7 +274,7 @@
250274 drm_connector_list_iter_end(&conn_iter);
251275 }
252276
253
- ret = pm_runtime_get_sync(crtc->dev->dev);
277
+ ret = pm_runtime_resume_and_get(crtc->dev->dev);
254278 if (ret < 0) {
255279 DRM_ERROR("Failed to enable power domain: %d\n", ret);
256280 return ret;
....@@ -268,11 +292,10 @@
268292 goto err_mutex_unprepare;
269293 }
270294
271
- DRM_DEBUG_DRIVER("mediatek_ddp_ddp_path_setup\n");
272295 for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
273
- mtk_ddp_add_comp_to_path(mtk_crtc->config_regs,
274
- mtk_crtc->ddp_comp[i]->id,
275
- mtk_crtc->ddp_comp[i + 1]->id);
296
+ mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
297
+ mtk_crtc->ddp_comp[i]->id,
298
+ mtk_crtc->ddp_comp[i + 1]->id);
276299 mtk_disp_mutex_add_comp(mtk_crtc->mutex,
277300 mtk_crtc->ddp_comp[i]->id);
278301 }
....@@ -282,7 +305,10 @@
282305 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
283306 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
284307
285
- mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
308
+ if (i == 1)
309
+ mtk_ddp_comp_bgclr_in_on(comp);
310
+
311
+ mtk_ddp_comp_config(comp, width, height, vrefresh, bpc, NULL);
286312 mtk_ddp_comp_start(comp);
287313 }
288314
....@@ -290,10 +316,14 @@
290316 for (i = 0; i < mtk_crtc->layer_nr; i++) {
291317 struct drm_plane *plane = &mtk_crtc->planes[i];
292318 struct mtk_plane_state *plane_state;
319
+ struct mtk_ddp_comp *comp;
320
+ unsigned int local_layer;
293321
294322 plane_state = to_mtk_plane_state(plane->state);
295
- mtk_ddp_comp_layer_config(mtk_crtc->ddp_comp[0], i,
296
- plane_state);
323
+ comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
324
+ if (comp)
325
+ mtk_ddp_comp_layer_config(comp, local_layer,
326
+ plane_state, NULL);
297327 }
298328
299329 return 0;
....@@ -311,17 +341,20 @@
311341 struct drm_crtc *crtc = &mtk_crtc->base;
312342 int i;
313343
314
- DRM_DEBUG_DRIVER("%s\n", __func__);
315
- for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
344
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
316345 mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]);
346
+ if (i == 1)
347
+ mtk_ddp_comp_bgclr_in_off(mtk_crtc->ddp_comp[i]);
348
+ }
349
+
317350 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
318351 mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
319352 mtk_crtc->ddp_comp[i]->id);
320353 mtk_disp_mutex_disable(mtk_crtc->mutex);
321354 for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
322
- mtk_ddp_remove_comp_from_path(mtk_crtc->config_regs,
323
- mtk_crtc->ddp_comp[i]->id,
324
- mtk_crtc->ddp_comp[i + 1]->id);
355
+ mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
356
+ mtk_crtc->ddp_comp[i]->id,
357
+ mtk_crtc->ddp_comp[i + 1]->id);
325358 mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
326359 mtk_crtc->ddp_comp[i]->id);
327360 }
....@@ -339,12 +372,14 @@
339372 }
340373 }
341374
342
-static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
375
+static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
376
+ struct cmdq_pkt *cmdq_handle)
343377 {
344378 struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
345379 struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
346380 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
347381 unsigned int i;
382
+ unsigned int local_layer;
348383
349384 /*
350385 * TODO: instead of updating the registers here, we should prepare
....@@ -354,7 +389,8 @@
354389 if (state->pending_config) {
355390 mtk_ddp_comp_config(comp, state->pending_width,
356391 state->pending_height,
357
- state->pending_vrefresh, 0);
392
+ state->pending_vrefresh, 0,
393
+ cmdq_handle);
358394
359395 state->pending_config = false;
360396 }
....@@ -366,13 +402,118 @@
366402
367403 plane_state = to_mtk_plane_state(plane->state);
368404
369
- if (plane_state->pending.config) {
370
- mtk_ddp_comp_layer_config(comp, i, plane_state);
371
- plane_state->pending.config = false;
372
- }
405
+ if (!plane_state->pending.config)
406
+ continue;
407
+
408
+ comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
409
+ &local_layer);
410
+
411
+ if (comp)
412
+ mtk_ddp_comp_layer_config(comp, local_layer,
413
+ plane_state,
414
+ cmdq_handle);
415
+ plane_state->pending.config = false;
373416 }
374417 mtk_crtc->pending_planes = false;
375418 }
419
+
420
+ if (mtk_crtc->pending_async_planes) {
421
+ for (i = 0; i < mtk_crtc->layer_nr; i++) {
422
+ struct drm_plane *plane = &mtk_crtc->planes[i];
423
+ struct mtk_plane_state *plane_state;
424
+
425
+ plane_state = to_mtk_plane_state(plane->state);
426
+
427
+ if (!plane_state->pending.async_config)
428
+ continue;
429
+
430
+ comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
431
+ &local_layer);
432
+
433
+ if (comp)
434
+ mtk_ddp_comp_layer_config(comp, local_layer,
435
+ plane_state,
436
+ cmdq_handle);
437
+ plane_state->pending.async_config = false;
438
+ }
439
+ mtk_crtc->pending_async_planes = false;
440
+ }
441
+}
442
+
443
+static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)
444
+{
445
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
446
+ struct cmdq_pkt *cmdq_handle;
447
+#endif
448
+ struct drm_crtc *crtc = &mtk_crtc->base;
449
+ struct mtk_drm_private *priv = crtc->dev->dev_private;
450
+ unsigned int pending_planes = 0, pending_async_planes = 0;
451
+ int i;
452
+
453
+ mutex_lock(&mtk_crtc->hw_lock);
454
+ for (i = 0; i < mtk_crtc->layer_nr; i++) {
455
+ struct drm_plane *plane = &mtk_crtc->planes[i];
456
+ struct mtk_plane_state *plane_state;
457
+
458
+ plane_state = to_mtk_plane_state(plane->state);
459
+ if (plane_state->pending.dirty) {
460
+ plane_state->pending.config = true;
461
+ plane_state->pending.dirty = false;
462
+ pending_planes |= BIT(i);
463
+ } else if (plane_state->pending.async_dirty) {
464
+ plane_state->pending.async_config = true;
465
+ plane_state->pending.async_dirty = false;
466
+ pending_async_planes |= BIT(i);
467
+ }
468
+ }
469
+ if (pending_planes)
470
+ mtk_crtc->pending_planes = true;
471
+ if (pending_async_planes)
472
+ mtk_crtc->pending_async_planes = true;
473
+
474
+ if (priv->data->shadow_register) {
475
+ mtk_disp_mutex_acquire(mtk_crtc->mutex);
476
+ mtk_crtc_ddp_config(crtc, NULL);
477
+ mtk_disp_mutex_release(mtk_crtc->mutex);
478
+ }
479
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
480
+ if (mtk_crtc->cmdq_client) {
481
+ mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
482
+ cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
483
+ cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
484
+ cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
485
+ mtk_crtc_ddp_config(crtc, cmdq_handle);
486
+ cmdq_pkt_finalize(cmdq_handle);
487
+ cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
488
+ }
489
+#endif
490
+ mutex_unlock(&mtk_crtc->hw_lock);
491
+}
492
+
493
+int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
494
+ struct mtk_plane_state *state)
495
+{
496
+ unsigned int local_layer;
497
+ struct mtk_ddp_comp *comp;
498
+
499
+ comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
500
+ if (comp)
501
+ return mtk_ddp_comp_layer_check(comp, local_layer, state);
502
+ return 0;
503
+}
504
+
505
+void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
506
+ struct drm_plane_state *new_state)
507
+{
508
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
509
+ const struct drm_plane_helper_funcs *plane_helper_funcs =
510
+ plane->helper_private;
511
+
512
+ if (!mtk_crtc->enabled)
513
+ return;
514
+
515
+ plane_helper_funcs->atomic_update(plane, new_state);
516
+ mtk_drm_crtc_hw_config(mtk_crtc);
376517 }
377518
378519 static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
....@@ -422,6 +563,7 @@
422563 }
423564 mtk_crtc->pending_planes = true;
424565
566
+ mtk_drm_crtc_hw_config(mtk_crtc);
425567 /* Wait for planes to be disabled */
426568 drm_crtc_wait_one_vblank(crtc);
427569
....@@ -453,34 +595,16 @@
453595 struct drm_crtc_state *old_crtc_state)
454596 {
455597 struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
456
- struct mtk_drm_private *priv = crtc->dev->dev_private;
457
- unsigned int pending_planes = 0;
458598 int i;
459599
460600 if (mtk_crtc->event)
461601 mtk_crtc->pending_needs_vblank = true;
462
- for (i = 0; i < mtk_crtc->layer_nr; i++) {
463
- struct drm_plane *plane = &mtk_crtc->planes[i];
464
- struct mtk_plane_state *plane_state;
465
-
466
- plane_state = to_mtk_plane_state(plane->state);
467
- if (plane_state->pending.dirty) {
468
- plane_state->pending.config = true;
469
- plane_state->pending.dirty = false;
470
- pending_planes |= BIT(i);
471
- }
472
- }
473
- if (pending_planes)
474
- mtk_crtc->pending_planes = true;
475602 if (crtc->state->color_mgmt_changed)
476
- for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
603
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
477604 mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
478
-
479
- if (priv->data->shadow_register) {
480
- mtk_disp_mutex_acquire(mtk_crtc->mutex);
481
- mtk_crtc_ddp_config(crtc);
482
- mtk_disp_mutex_release(mtk_crtc->mutex);
483
- }
605
+ mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);
606
+ }
607
+ mtk_drm_crtc_hw_config(mtk_crtc);
484608 }
485609
486610 static const struct drm_crtc_funcs mtk_crtc_funcs = {
....@@ -538,10 +662,68 @@
538662 struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
539663 struct mtk_drm_private *priv = crtc->dev->dev_private;
540664
665
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
666
+ if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
667
+#else
541668 if (!priv->data->shadow_register)
542
- mtk_crtc_ddp_config(crtc);
669
+#endif
670
+ mtk_crtc_ddp_config(crtc, NULL);
543671
544672 mtk_drm_finish_page_flip(mtk_crtc);
673
+}
674
+
675
+static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
676
+ int comp_idx)
677
+{
678
+ struct mtk_ddp_comp *comp;
679
+
680
+ if (comp_idx > 1)
681
+ return 0;
682
+
683
+ comp = mtk_crtc->ddp_comp[comp_idx];
684
+ if (!comp->funcs)
685
+ return 0;
686
+
687
+ if (comp_idx == 1 && !comp->funcs->bgclr_in_on)
688
+ return 0;
689
+
690
+ return mtk_ddp_comp_layer_nr(comp);
691
+}
692
+
693
+static inline
694
+enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx,
695
+ unsigned int num_planes)
696
+{
697
+ if (plane_idx == 0)
698
+ return DRM_PLANE_TYPE_PRIMARY;
699
+ else if (plane_idx == (num_planes - 1))
700
+ return DRM_PLANE_TYPE_CURSOR;
701
+ else
702
+ return DRM_PLANE_TYPE_OVERLAY;
703
+
704
+}
705
+
706
+static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
707
+ struct mtk_drm_crtc *mtk_crtc,
708
+ int comp_idx, int pipe)
709
+{
710
+ int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
711
+ struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
712
+ int i, ret;
713
+
714
+ for (i = 0; i < num_planes; i++) {
715
+ ret = mtk_plane_init(drm_dev,
716
+ &mtk_crtc->planes[mtk_crtc->layer_nr],
717
+ BIT(pipe),
718
+ mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,
719
+ num_planes),
720
+ mtk_ddp_comp_supported_rotations(comp));
721
+ if (ret)
722
+ return ret;
723
+
724
+ mtk_crtc->layer_nr++;
725
+ }
726
+ return 0;
545727 }
546728
547729 int mtk_drm_crtc_create(struct drm_device *drm_dev,
....@@ -550,11 +732,12 @@
550732 struct mtk_drm_private *priv = drm_dev->dev_private;
551733 struct device *dev = drm_dev->dev;
552734 struct mtk_drm_crtc *mtk_crtc;
553
- enum drm_plane_type type;
554
- unsigned int zpos;
735
+ unsigned int num_comp_planes = 0;
555736 int pipe = priv->num_pipes;
556737 int ret;
557738 int i;
739
+ bool has_ctm = false;
740
+ uint gamma_lut_size = 0;
558741
559742 if (!path)
560743 return 0;
....@@ -576,7 +759,7 @@
576759 if (!mtk_crtc)
577760 return -ENOMEM;
578761
579
- mtk_crtc->config_regs = priv->config_regs;
762
+ mtk_crtc->mmsys_dev = priv->mmsys_dev;
580763 mtk_crtc->ddp_comp_nr = path_len;
581764 mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
582765 sizeof(*mtk_crtc->ddp_comp),
....@@ -601,47 +784,66 @@
601784 if (!comp) {
602785 dev_err(dev, "Component %pOF not initialized\n", node);
603786 ret = -ENODEV;
604
- goto unprepare;
605
- }
606
-
607
- ret = clk_prepare(comp->clk);
608
- if (ret) {
609
- dev_err(dev,
610
- "Failed to prepare clock for component %pOF: %d\n",
611
- node, ret);
612
- goto unprepare;
787
+ return ret;
613788 }
614789
615790 mtk_crtc->ddp_comp[i] = comp;
791
+
792
+ if (comp->funcs) {
793
+ if (comp->funcs->gamma_set)
794
+ gamma_lut_size = MTK_LUT_SIZE;
795
+
796
+ if (comp->funcs->ctm_set)
797
+ has_ctm = true;
798
+ }
616799 }
617800
618
- mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
619
- mtk_crtc->planes = devm_kcalloc(dev, mtk_crtc->layer_nr,
620
- sizeof(struct drm_plane),
621
- GFP_KERNEL);
801
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
802
+ num_comp_planes += mtk_drm_crtc_num_comp_planes(mtk_crtc, i);
622803
623
- for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
624
- type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
625
- (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
626
- DRM_PLANE_TYPE_OVERLAY;
627
- ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos],
628
- BIT(pipe), type);
804
+ mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
805
+ sizeof(struct drm_plane), GFP_KERNEL);
806
+
807
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
808
+ ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
809
+ pipe);
629810 if (ret)
630
- goto unprepare;
811
+ return ret;
631812 }
632813
633814 ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
634815 if (ret < 0)
635
- goto unprepare;
636
- drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);
637
- drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE);
816
+ return ret;
817
+
818
+ if (gamma_lut_size)
819
+ drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
820
+ drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
638821 priv->num_pipes++;
822
+ mutex_init(&mtk_crtc->hw_lock);
639823
824
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
825
+ mtk_crtc->cmdq_client =
826
+ cmdq_mbox_create(mtk_crtc->mmsys_dev,
827
+ drm_crtc_index(&mtk_crtc->base),
828
+ 2000);
829
+ if (IS_ERR(mtk_crtc->cmdq_client)) {
830
+ dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
831
+ drm_crtc_index(&mtk_crtc->base));
832
+ mtk_crtc->cmdq_client = NULL;
833
+ }
834
+
835
+ if (mtk_crtc->cmdq_client) {
836
+ ret = of_property_read_u32_index(priv->mutex_node,
837
+ "mediatek,gce-events",
838
+ drm_crtc_index(&mtk_crtc->base),
839
+ &mtk_crtc->cmdq_event);
840
+ if (ret) {
841
+ dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
842
+ drm_crtc_index(&mtk_crtc->base));
843
+ cmdq_mbox_destroy(mtk_crtc->cmdq_client);
844
+ mtk_crtc->cmdq_client = NULL;
845
+ }
846
+ }
847
+#endif
640848 return 0;
641
-
642
-unprepare:
643
- while (--i >= 0)
644
- clk_unprepare(mtk_crtc->ddp_comp[i]->clk);
645
-
646
- return ret;
647849 }