OSDN Git Service

drm/komeda: Adds zorder support
authorLowry Li (Arm Technology China) <Lowry.Li@arm.com>
Mon, 20 May 2019 03:33:19 +0000 (04:33 +0100)
committerLiviu Dudau <Liviu.Dudau@arm.com>
Wed, 19 Jun 2019 10:42:17 +0000 (11:42 +0100)
- Creates the zpos property.
- Implement komeda_crtc_normalize_zpos to replace
drm_atomic_normalize_zpos, reasons as the following:

1. The drm_atomic_normalize_zpos allows to configure same zpos for
different planes, but komeda doesn't support such configuration.
2. For further slave pipline case, Komeda need to calculate the
max_slave_zorder, we will merge such calculation into
komed_crtc_normalize_zpos to save a separated plane_state loop.
3. For feature none-scaling layer_split, which a plane_state will be
assigned to two individual layers(left/right), which requires two
normalize_zpos for this plane, plane_st->normalize_zpos will be used
by left layer, normalize_zpos + 1 for right_layer.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59747/
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/60083/
- https://patchwork.freedesktop.org/series/60698/

Signed-off-by: Lowry Li (Arm Technology China) <lowry.li@arm.com>
Reviewed-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
drivers/gpu/drm/arm/display/komeda/komeda_kms.c
drivers/gpu/drm/arm/display/komeda/komeda_kms.h
drivers/gpu/drm/arm/display/komeda/komeda_plane.c

index 306ea06..0ec7665 100644 (file)
@@ -100,6 +100,90 @@ static const struct drm_mode_config_helper_funcs komeda_mode_config_helpers = {
        .atomic_commit_tail = komeda_kms_commit_tail,
 };
 
+static int komeda_plane_state_list_add(struct drm_plane_state *plane_st,
+                                      struct list_head *zorder_list)
+{
+       struct komeda_plane_state *new = to_kplane_st(plane_st);
+       struct komeda_plane_state *node, *last;
+
+       last = list_empty(zorder_list) ?
+              NULL : list_last_entry(zorder_list, typeof(*last), zlist_node);
+
+       /* Considering the list sequence is zpos increasing, so if list is empty
+        * or the zpos of new node bigger than the last node in list, no need
+        * loop and just insert the new one to the tail of the list.
+        */
+       if (!last || (new->base.zpos > last->base.zpos)) {
+               list_add_tail(&new->zlist_node, zorder_list);
+               return 0;
+       }
+
+       /* Build the list by zpos increasing */
+       list_for_each_entry(node, zorder_list, zlist_node) {
+               if (new->base.zpos < node->base.zpos) {
+                       list_add_tail(&new->zlist_node, &node->zlist_node);
+                       break;
+               } else if (node->base.zpos == new->base.zpos) {
+                       struct drm_plane *a = node->base.plane;
+                       struct drm_plane *b = new->base.plane;
+
+                       /* Komeda doesn't support setting a same zpos for
+                        * different planes.
+                        */
+                       DRM_DEBUG_ATOMIC("PLANE: %s and PLANE: %s are configured same zpos: %d.\n",
+                                        a->name, b->name, node->base.zpos);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
+                                     struct drm_crtc_state *crtc_st)
+{
+       struct drm_atomic_state *state = crtc_st->state;
+       struct komeda_plane_state *kplane_st;
+       struct drm_plane_state *plane_st;
+       struct drm_framebuffer *fb;
+       struct drm_plane *plane;
+       struct list_head zorder_list;
+       int order = 0, err;
+
+       DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
+                        crtc->base.id, crtc->name);
+
+       INIT_LIST_HEAD(&zorder_list);
+
+       /* This loop also added all effected planes into the new state */
+       drm_for_each_plane_mask(plane, crtc->dev, crtc_st->plane_mask) {
+               plane_st = drm_atomic_get_plane_state(state, plane);
+               if (IS_ERR(plane_st))
+                       return PTR_ERR(plane_st);
+
+               /* Build a list by zpos increasing */
+               err = komeda_plane_state_list_add(plane_st, &zorder_list);
+               if (err)
+                       return err;
+       }
+
+       list_for_each_entry(kplane_st, &zorder_list, zlist_node) {
+               plane_st = &kplane_st->base;
+               fb = plane_st->fb;
+               plane = plane_st->plane;
+
+               plane_st->normalized_zpos = order++;
+
+               DRM_DEBUG_ATOMIC("[PLANE:%d:%s] zpos:%d, normalized zpos: %d\n",
+                                plane->base.id, plane->name,
+                                plane_st->zpos, plane_st->normalized_zpos);
+       }
+
+       crtc_st->zpos_changed = true;
+
+       return 0;
+}
+
 static int komeda_kms_check(struct drm_device *dev,
                            struct drm_atomic_state *state)
 {
@@ -111,7 +195,7 @@ static int komeda_kms_check(struct drm_device *dev,
        if (err)
                return err;
 
-       /* komeda need to re-calculate resource assumption in every commit
+       /* Komeda need to re-calculate resource assumption in every commit
         * so need to add all affected_planes (even unchanged) to
         * drm_atomic_state.
         */
@@ -119,6 +203,10 @@ static int komeda_kms_check(struct drm_device *dev,
                err = drm_atomic_add_affected_planes(state, crtc);
                if (err)
                        return err;
+
+               err = komeda_crtc_normalize_zpos(crtc, new_crtc_st);
+               if (err)
+                       return err;
        }
 
        err = drm_atomic_helper_check_planes(dev, state);
index e6e059f..c07b4ab 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef _KOMEDA_KMS_H_
 #define _KOMEDA_KMS_H_
 
+#include <linux/list.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
@@ -46,6 +47,8 @@ struct komeda_plane {
 struct komeda_plane_state {
        /** @base: &drm_plane_state */
        struct drm_plane_state base;
+       /** @zlist_node: zorder list node */
+       struct list_head zlist_node;
 
        /* @img_enhancement: on/off image enhancement */
        u8 img_enhancement : 1;
index 9e049ee..c0e381c 100644 (file)
@@ -22,7 +22,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 
        memset(dflow, 0, sizeof(*dflow));
 
-       dflow->blending_zorder = st->zpos;
+       dflow->blending_zorder = st->normalized_zpos;
 
        /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */
        dflow->pixel_blend_mode = fb->format->has_alpha ?
@@ -345,6 +345,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
        if (err)
                goto cleanup;
 
+       err = drm_plane_create_zpos_property(plane, layer->base.id, 0, 8);
+       if (err)
+               goto cleanup;
+
        return 0;
 cleanup:
        komeda_plane_destroy(plane);