From: Andy Yan <andy....@rock-chips.com>

In the upcoming VOP of rk3576, a Window cannot attach to all Video Ports,
so make sure all VP find it's suitable primary plane, then register the
remain windows as overlay plane will make code easier.

Signed-off-by: Andy Yan <andy....@rock-chips.com>
Tested-by: Michael Riesch <michael.rie...@wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casan...@collabora.com>

---

(no changes since v3)

Changes in v3:
- Add comments for why we should treat rk3566 with special care.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 100 +++++++++++--------
 1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index c8c8da63db0f..2c84bac9d88a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2247,22 +2247,29 @@ static int vop2_plane_init(struct vop2 *vop2, struct 
vop2_win *win,
        return 0;
 }
 
-static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
+/*
+ * On RK3566 these windows don't have an independent
+ * framebuffer. They can only share/mirror the framebuffer
+ * with smart0, esmart0 and cluster0 respectively.
+ * And RK3566 share the same vop version with Rk3568, so we
+ * need to use soc_id for identification here.
+ */
+static bool vop2_is_mirror_win(struct vop2_win *win)
 {
-       int i;
-
-       for (i = 0; i < vop2->data->nr_vps; i++) {
-               struct vop2_video_port *vp = &vop2->vps[i];
-
-               if (!vp->crtc.port)
-                       continue;
-               if (vp->primary_plane)
-                       continue;
+       struct vop2 *vop2 = win->vop2;
 
-               return vp;
+       if (vop2->data->soc_id == 3566) {
+               switch (win->data->phys_id) {
+               case ROCKCHIP_VOP2_SMART1:
+               case ROCKCHIP_VOP2_ESMART1:
+               case ROCKCHIP_VOP2_CLUSTER1:
+                       return true;
+               default:
+                       return false;
+               }
+       } else {
+               return false;
        }
-
-       return NULL;
 }
 
 static int vop2_create_crtcs(struct vop2 *vop2)
@@ -2273,7 +2280,9 @@ static int vop2_create_crtcs(struct vop2 *vop2)
        struct drm_plane *plane;
        struct device_node *port;
        struct vop2_video_port *vp;
-       int i, nvp, nvps = 0;
+       struct vop2_win *win;
+       u32 possible_crtcs;
+       int i, j, nvp, nvps = 0;
        int ret;
 
        for (i = 0; i < vop2_data->nr_vps; i++) {
@@ -2312,42 +2321,55 @@ static int vop2_create_crtcs(struct vop2 *vop2)
        }
 
        nvp = 0;
-       for (i = 0; i < vop2->registered_num_wins; i++) {
-               struct vop2_win *win = &vop2->win[i];
-               u32 possible_crtcs = 0;
-
-               if (vop2->data->soc_id == 3566) {
-                       /*
-                        * On RK3566 these windows don't have an independent
-                        * framebuffer. They share the framebuffer with smart0,
-                        * esmart0 and cluster0 respectively.
-                        */
-                       switch (win->data->phys_id) {
-                       case ROCKCHIP_VOP2_SMART1:
-                       case ROCKCHIP_VOP2_ESMART1:
-                       case ROCKCHIP_VOP2_CLUSTER1:
+       /* Register a primary plane for every crtc */
+       for (i = 0; i < vop2_data->nr_vps; i++) {
+               vp = &vop2->vps[i];
+
+               if (!vp->crtc.port)
+                       continue;
+
+               for (j = 0; j < vop2->registered_num_wins; j++) {
+                       win = &vop2->win[j];
+
+                       /* Aready registered as primary plane */
+                       if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
                                continue;
-                       }
-               }
 
-               if (win->type == DRM_PLANE_TYPE_PRIMARY) {
-                       vp = find_vp_without_primary(vop2);
-                       if (vp) {
+                       if (vop2_is_mirror_win(win))
+                               continue;
+
+                       if (win->type == DRM_PLANE_TYPE_PRIMARY) {
                                possible_crtcs = BIT(nvp);
                                vp->primary_plane = win;
+                               ret = vop2_plane_init(vop2, win, 
possible_crtcs);
+                               if (ret) {
+                                       drm_err(vop2->drm, "failed to init 
primary plane %s: %d\n",
+                                               win->data->name, ret);
+                                       return ret;
+                               }
                                nvp++;
-                       } else {
-                               /* change the unused primary window to overlay 
window */
-                               win->type = DRM_PLANE_TYPE_OVERLAY;
+                               break;
                        }
                }
+       }
+
+       /* Register all unused window as overlay plane */
+       for (i = 0; i < vop2->registered_num_wins; i++) {
+               win = &vop2->win[i];
+
+               /* Aready registered as primary plane */
+               if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+                       continue;
+
+               if (vop2_is_mirror_win(win))
+                       continue;
 
-               if (win->type == DRM_PLANE_TYPE_OVERLAY)
-                       possible_crtcs = (1 << nvps) - 1;
+               win->type = DRM_PLANE_TYPE_OVERLAY;
 
+               possible_crtcs = (1 << nvps) - 1;
                ret = vop2_plane_init(vop2, win, possible_crtcs);
                if (ret) {
-                       drm_err(vop2->drm, "failed to init plane %s: %d\n",
+                       drm_err(vop2->drm, "failed to init overlay plane %s: 
%d\n",
                                win->data->name, ret);
                        return ret;
                }
-- 
2.34.1

Reply via email to