forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/imx/ipuv3-plane.c
....@@ -1,27 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * i.MX IPUv3 DP Overlay Planes
34 *
45 * Copyright (C) 2013 Philipp Zabel, Pengutronix
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version 2
9
- * of the License, or (at your option) any later version.
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
146 */
157
16
-#include <drm/drmP.h>
178 #include <drm/drm_atomic.h>
189 #include <drm/drm_atomic_helper.h>
1910 #include <drm/drm_fb_cma_helper.h>
11
+#include <drm/drm_fourcc.h>
2012 #include <drm/drm_gem_cma_helper.h>
2113 #include <drm/drm_gem_framebuffer_helper.h>
2214 #include <drm/drm_plane_helper.h>
2315
24
-#include "video/imx-ipu-v3.h"
16
+#include <video/imx-ipu-v3.h>
17
+
2518 #include "imx-drm.h"
2619 #include "ipuv3-plane.h"
2720
....@@ -123,8 +116,8 @@
123116 cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
124117 BUG_ON(!cma_obj);
125118
126
- x /= drm_format_horz_chroma_subsampling(fb->format->format);
127
- y /= drm_format_vert_chroma_subsampling(fb->format->format);
119
+ x /= fb->format->hsub;
120
+ y /= fb->format->vsub;
128121
129122 return cma_obj->paddr + fb->offsets[1] + fb->pitches[1] * y +
130123 fb->format->cpp[1] * x - eba;
....@@ -142,8 +135,8 @@
142135 cma_obj = drm_fb_cma_get_gem_obj(fb, 2);
143136 BUG_ON(!cma_obj);
144137
145
- x /= drm_format_horz_chroma_subsampling(fb->format->format);
146
- y /= drm_format_vert_chroma_subsampling(fb->format->format);
138
+ x /= fb->format->hsub;
139
+ y /= fb->format->vsub;
147140
148141 return cma_obj->paddr + fb->offsets[2] + fb->pitches[2] * y +
149142 fb->format->cpp[2] * x - eba;
....@@ -236,9 +229,15 @@
236229
237230 void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel)
238231 {
232
+ int ret;
233
+
239234 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
240235
241
- ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
236
+ ret = ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
237
+ if (ret == -ETIMEDOUT) {
238
+ DRM_ERROR("[PLANE:%d] IDMAC timeout\n",
239
+ ipu_plane->base.base.id);
240
+ }
242241
243242 if (ipu_plane->dp && disable_dp_channel)
244243 ipu_dp_disable_channel(ipu_plane->dp, false);
....@@ -275,22 +274,23 @@
275274
276275 static void ipu_plane_state_reset(struct drm_plane *plane)
277276 {
277
+ unsigned int zpos = (plane->type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1;
278278 struct ipu_plane_state *ipu_state;
279279
280280 if (plane->state) {
281281 ipu_state = to_ipu_plane_state(plane->state);
282282 __drm_atomic_helper_plane_destroy_state(plane->state);
283283 kfree(ipu_state);
284
+ plane->state = NULL;
284285 }
285286
286287 ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL);
287288
288289 if (ipu_state) {
289
- ipu_state->base.plane = plane;
290
- ipu_state->base.rotation = DRM_MODE_ROTATE_0;
290
+ __drm_atomic_helper_plane_reset(plane, &ipu_state->base);
291
+ ipu_state->base.zpos = zpos;
292
+ ipu_state->base.normalized_zpos = zpos;
291293 }
292
-
293
- plane->state = &ipu_state->base;
294294 }
295295
296296 static struct drm_plane_state *
....@@ -353,14 +353,13 @@
353353 struct drm_framebuffer *old_fb = old_state->fb;
354354 unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba;
355355 bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
356
- int hsub, vsub;
357356 int ret;
358357
359358 /* Ok to disable */
360359 if (!fb)
361360 return 0;
362361
363
- if (!state->crtc)
362
+ if (WARN_ON(!state->crtc))
364363 return -EINVAL;
365364
366365 crtc_state =
....@@ -448,7 +447,7 @@
448447 if (fb->pitches[1] != fb->pitches[2])
449448 return -EINVAL;
450449
451
- /* fall-through */
450
+ fallthrough;
452451 case DRM_FORMAT_NV12:
453452 case DRM_FORMAT_NV16:
454453 ubo = drm_plane_state_to_ubo(state);
....@@ -472,10 +471,8 @@
472471 * The x/y offsets must be even in case of horizontal/vertical
473472 * chroma subsampling.
474473 */
475
- hsub = drm_format_horz_chroma_subsampling(fb->format->format);
476
- vsub = drm_format_vert_chroma_subsampling(fb->format->format);
477
- if (((state->src.x1 >> 16) & (hsub - 1)) ||
478
- ((state->src.y1 >> 16) & (vsub - 1)))
474
+ if (((state->src.x1 >> 16) & (fb->format->hsub - 1)) ||
475
+ ((state->src.y1 >> 16) & (fb->format->vsub - 1)))
479476 return -EINVAL;
480477 break;
481478 case DRM_FORMAT_RGB565_A8:
....@@ -565,6 +562,25 @@
565562 if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG)
566563 ipu_dp_set_window_pos(ipu_plane->dp, dst->x1, dst->y1);
567564
565
+ switch (ipu_plane->dp_flow) {
566
+ case IPU_DP_FLOW_SYNC_BG:
567
+ if (state->normalized_zpos == 1) {
568
+ ipu_dp_set_global_alpha(ipu_plane->dp,
569
+ !fb->format->has_alpha, 0xff,
570
+ true);
571
+ } else {
572
+ ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
573
+ }
574
+ break;
575
+ case IPU_DP_FLOW_SYNC_FG:
576
+ if (state->normalized_zpos == 1) {
577
+ ipu_dp_set_global_alpha(ipu_plane->dp,
578
+ !fb->format->has_alpha, 0xff,
579
+ false);
580
+ }
581
+ break;
582
+ }
583
+
568584 eba = drm_plane_state_to_eba(state, 0);
569585
570586 /*
....@@ -600,34 +616,11 @@
600616 switch (ipu_plane->dp_flow) {
601617 case IPU_DP_FLOW_SYNC_BG:
602618 ipu_dp_setup_channel(ipu_plane->dp, ics, IPUV3_COLORSPACE_RGB);
603
- ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
604619 break;
605620 case IPU_DP_FLOW_SYNC_FG:
606621 ipu_dp_setup_channel(ipu_plane->dp, ics,
607622 IPUV3_COLORSPACE_UNKNOWN);
608
- /* Enable local alpha on partial plane */
609
- switch (fb->format->format) {
610
- case DRM_FORMAT_ARGB1555:
611
- case DRM_FORMAT_ABGR1555:
612
- case DRM_FORMAT_RGBA5551:
613
- case DRM_FORMAT_BGRA5551:
614
- case DRM_FORMAT_ARGB4444:
615
- case DRM_FORMAT_ARGB8888:
616
- case DRM_FORMAT_ABGR8888:
617
- case DRM_FORMAT_RGBA8888:
618
- case DRM_FORMAT_BGRA8888:
619
- case DRM_FORMAT_RGB565_A8:
620
- case DRM_FORMAT_BGR565_A8:
621
- case DRM_FORMAT_RGB888_A8:
622
- case DRM_FORMAT_BGR888_A8:
623
- case DRM_FORMAT_RGBX8888_A8:
624
- case DRM_FORMAT_BGRX8888_A8:
625
- ipu_dp_set_global_alpha(ipu_plane->dp, false, 0, false);
626
- break;
627
- default:
628
- ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
629
- break;
630
- }
623
+ break;
631624 }
632625
633626 ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
....@@ -643,6 +636,7 @@
643636 ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->format->format);
644637 ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, burstsize);
645638 ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
639
+ ipu_idmac_enable_watermark(ipu_plane->ipu_ch, true);
646640 ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
647641 ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]);
648642 ipu_cpmem_set_axi_id(ipu_plane->ipu_ch, axi_id);
....@@ -723,6 +717,29 @@
723717 .atomic_update = ipu_plane_atomic_update,
724718 };
725719
720
+bool ipu_plane_atomic_update_pending(struct drm_plane *plane)
721
+{
722
+ struct ipu_plane *ipu_plane = to_ipu_plane(plane);
723
+ struct drm_plane_state *state = plane->state;
724
+ struct ipu_plane_state *ipu_state = to_ipu_plane_state(state);
725
+
726
+ /* disabled crtcs must not block the update */
727
+ if (!state->crtc)
728
+ return false;
729
+
730
+ if (ipu_state->use_pre)
731
+ return ipu_prg_channel_configure_pending(ipu_plane->ipu_ch);
732
+
733
+ /*
734
+ * Pretend no update is pending in the non-PRE/PRG case. For this to
735
+ * happen, an atomic update would have to be deferred until after the
736
+ * start of the next frame and simultaneously interrupt latency would
737
+ * have to be high enough to let the atomic update finish and issue an
738
+ * event before the previous end of frame interrupt handler can be
739
+ * executed.
740
+ */
741
+ return false;
742
+}
726743 int ipu_planes_assign_pre(struct drm_device *dev,
727744 struct drm_atomic_state *state)
728745 {
....@@ -811,6 +828,7 @@
811828 {
812829 struct ipu_plane *ipu_plane;
813830 const uint64_t *modifiers = ipu_format_modifiers;
831
+ unsigned int zpos = (type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1;
814832 int ret;
815833
816834 DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
....@@ -841,5 +859,10 @@
841859
842860 drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs);
843861
862
+ if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG)
863
+ drm_plane_create_zpos_property(&ipu_plane->base, zpos, 0, 1);
864
+ else
865
+ drm_plane_create_zpos_immutable_property(&ipu_plane->base, 0);
866
+
844867 return ipu_plane;
845868 }