drm/komeda: Adds zorder support

james qian wang (Arm Technology China) james.qian.wang at arm.com
Mon May 20 06:05:00 UTC 2019


On Mon, May 20, 2019 at 03:33:19AM +0000, Lowry Li (Arm Technology China) wrote:
> - 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 at arm.com>
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c   | 90 ++++++++++++++++++++++-
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.h   |  3 +
>  drivers/gpu/drm/arm/display/komeda/komeda_plane.c |  6 +-
>  3 files changed, 97 insertions(+), 2 deletions(-)
> 
> -- 
> 1.9.1
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index 306ea06..0ec7665 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -100,6 +100,90 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
>  	.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);
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
> index 178bee6..d1cef46 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
> @@ -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;
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> index bcf30a7..aad7663 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> @@ -21,7 +21,7 @@
>  
>  	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 ?
> @@ -343,6 +343,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);

Looks good to me.

Reviewed-by: James Qian Wang (Arm Technology China) <james.qian.wang at arm.com>


More information about the dri-devel mailing list