drm/vc4: hvs: Support zpos on all planes
authorDave Stevenson <dave.stevenson@raspberrypi.com>
Wed, 7 Dec 2022 11:53:16 +0000 (12:53 +0100)
committerMaxime Ripard <maxime@cerno.tech>
Mon, 9 Jan 2023 14:21:31 +0000 (15:21 +0100)
Adds the zpos property to all planes, and creates the dlist
by placing the fragments in the correct order based on zpos.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-5-1f8e0770798b@cerno.tech
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
drivers/gpu/drm/vc4/vc4_hvs.c
drivers/gpu/drm/vc4/vc4_kms.c
drivers/gpu/drm/vc4/vc4_plane.c

index 56a0a1d..260efd4 100644 (file)
@@ -570,6 +570,8 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
        bool enable_bg_fill = false;
        u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
        u32 __iomem *dlist_next = dlist_start;
+       unsigned int zpos = 0;
+       bool found = false;
        int idx;
 
        if (!drm_dev_enter(dev, &idx)) {
@@ -583,23 +585,34 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
        }
 
        /* Copy all the active planes' dlist contents to the hardware dlist. */
-       drm_atomic_crtc_for_each_plane(plane, crtc) {
-               /* Is this the first active plane? */
-               if (dlist_next == dlist_start) {
-                       /* We need to enable background fill when a plane
-                        * could be alpha blending from the background, i.e.
-                        * where no other plane is underneath. It suffices to
-                        * consider the first active plane here since we set
-                        * needs_bg_fill such that either the first plane
-                        * already needs it or all planes on top blend from
-                        * the first or a lower plane.
-                        */
-                       vc4_plane_state = to_vc4_plane_state(plane->state);
-                       enable_bg_fill = vc4_plane_state->needs_bg_fill;
+       do {
+               found = false;
+
+               drm_atomic_crtc_for_each_plane(plane, crtc) {
+                       if (plane->state->normalized_zpos != zpos)
+                               continue;
+
+                       /* Is this the first active plane? */
+                       if (dlist_next == dlist_start) {
+                               /* We need to enable background fill when a plane
+                                * could be alpha blending from the background, i.e.
+                                * where no other plane is underneath. It suffices to
+                                * consider the first active plane here since we set
+                                * needs_bg_fill such that either the first plane
+                                * already needs it or all planes on top blend from
+                                * the first or a lower plane.
+                                */
+                               vc4_plane_state = to_vc4_plane_state(plane->state);
+                               enable_bg_fill = vc4_plane_state->needs_bg_fill;
+                       }
+
+                       dlist_next += vc4_plane_write_dlist(plane, dlist_next);
+
+                       found = true;
                }
 
-               dlist_next += vc4_plane_write_dlist(plane, dlist_next);
-       }
+               zpos++;
+       } while (found);
 
        writel(SCALER_CTL0_END, dlist_next);
        dlist_next++;
index 53d9f30..a7e3d47 100644 (file)
@@ -1074,6 +1074,7 @@ int vc4_kms_load(struct drm_device *dev)
        dev->mode_config.helper_private = &vc4_mode_config_helpers;
        dev->mode_config.preferred_depth = 24;
        dev->mode_config.async_page_flip = true;
+       dev->mode_config.normalize_zpos = true;
 
        ret = vc4_ctm_obj_init(vc4);
        if (ret)
index 8b92a45..c212f8c 100644 (file)
@@ -1568,9 +1568,14 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
                                          DRM_COLOR_YCBCR_BT709,
                                          DRM_COLOR_YCBCR_LIMITED_RANGE);
 
+       if (type == DRM_PLANE_TYPE_PRIMARY)
+               drm_plane_create_zpos_immutable_property(plane, 0);
+
        return plane;
 }
 
+#define VC4_NUM_OVERLAY_PLANES 16
+
 int vc4_plane_create_additional_planes(struct drm_device *drm)
 {
        struct drm_plane *cursor_plane;
@@ -1586,24 +1591,35 @@ int vc4_plane_create_additional_planes(struct drm_device *drm)
         * modest number of planes to expose, that should hopefully
         * still cover any sane usecase.
         */
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < VC4_NUM_OVERLAY_PLANES; i++) {
                struct drm_plane *plane =
                        vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
                                       GENMASK(drm->mode_config.num_crtc - 1, 0));
 
                if (IS_ERR(plane))
                        continue;
+
+               /* Create zpos property. Max of all the overlays + 1 primary +
+                * 1 cursor plane on a crtc.
+                */
+               drm_plane_create_zpos_property(plane, i + 1, 1,
+                                              VC4_NUM_OVERLAY_PLANES + 1);
        }
 
        drm_for_each_crtc(crtc, drm) {
                /* Set up the legacy cursor after overlay initialization,
-                * since we overlay planes on the CRTC in the order they were
-                * initialized.
+                * since the zpos fallback is that planes are rendered by plane
+                * ID order, and that then puts the cursor on top.
                 */
                cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR,
                                              drm_crtc_mask(crtc));
                if (!IS_ERR(cursor_plane)) {
                        crtc->cursor = cursor_plane;
+
+                       drm_plane_create_zpos_property(cursor_plane,
+                                                      VC4_NUM_OVERLAY_PLANES + 1,
+                                                      1,
+                                                      VC4_NUM_OVERLAY_PLANES + 1);
                }
        }