[Freedreno] [PATCH 06/11] drm/msm/dpu: support cursor sspp hw blocks

Arnaud Vrac avrac at freebox.fr
Wed Apr 19 14:41:13 UTC 2023


Cursor SSPP must be assigned to the last mixer stage, so we assign an
immutable zpos property with a value higher than primary/overlay planes,
to ensure it will always be on top.

Signed-off-by: Arnaud Vrac <avrac at freebox.fr>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 19 ++++++++++++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 26 +++++++++++++++++++++++---
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 0e7a68714e9e1..6cce0f6cfcb01 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -738,13 +738,22 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 	for (i = 0; i < catalog->sspp_count; i++) {
 		enum drm_plane_type type;
 
-		if ((catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR))
-			&& cursor_planes_idx < max_crtc_count)
-			type = DRM_PLANE_TYPE_CURSOR;
-		else if (primary_planes_idx < max_crtc_count)
+		if (catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR)) {
+			if (cursor_planes_idx < max_crtc_count) {
+				type = DRM_PLANE_TYPE_CURSOR;
+			} else if (catalog->sspp[i].type == SSPP_TYPE_CURSOR) {
+				/* Cursor SSPP can only be used in the last
+				 * mixer stage, so it doesn't make sense to
+				 * assign two of those to the same CRTC */
+				continue;
+			} else {
+				type = DRM_PLANE_TYPE_OVERLAY;
+			}
+		} else if (primary_planes_idx < max_crtc_count) {
 			type = DRM_PLANE_TYPE_PRIMARY;
-		else
+		} else {
 			type = DRM_PLANE_TYPE_OVERLAY;
+		}
 
 		DPU_DEBUG("Create plane type %d with features %lx (cur %lx)\n",
 			  type, catalog->sspp[i].features,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 128ecdc145260..5a7bb8543866c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -881,7 +881,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
 	r_pipe->sspp = NULL;
 
-	pstate->stage = DPU_STAGE_BASE + pstate->base.normalized_zpos;
+	if (pipe_hw_caps->type == SSPP_TYPE_CURSOR) {
+		/* enforce cursor sspp to use the last mixer stage */
+		pstate->stage = DPU_STAGE_BASE +
+			pdpu->catalog->caps->max_mixer_blendstages;
+	} else {
+		pstate->stage = DPU_STAGE_BASE + pstate->base.normalized_zpos;
+	}
+
 	if (pstate->stage > DPU_STAGE_BASE + pdpu->catalog->caps->max_mixer_blendstages) {
 		DPU_ERROR("> %d plane mixer stages assigned\n",
 			  pdpu->catalog->caps->max_mixer_blendstages);
@@ -1463,6 +1470,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
 	struct dpu_hw_sspp *pipe_hw;
+	const uint64_t *format_modifiers;
 	uint32_t num_formats;
 	uint32_t supported_rotations;
 	int ret = -EINVAL;
@@ -1489,15 +1497,27 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	format_list = pipe_hw->cap->sblk->format_list;
 	num_formats = pipe_hw->cap->sblk->num_formats;
 
+	if (pipe_hw->cap->type == SSPP_TYPE_CURSOR)
+		format_modifiers = NULL;
+	else
+		format_modifiers = supported_format_modifiers;
+
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
-				supported_format_modifiers, type, NULL);
+				format_modifiers, type, NULL);
 	if (ret)
 		goto clean_plane;
 
 	pdpu->catalog = kms->catalog;
 
-	ret = drm_plane_create_zpos_property(plane, 0, 0, DPU_ZPOS_MAX);
+	if (pipe_hw->cap->type == SSPP_TYPE_CURSOR) {
+		/* cursor SSPP can only be used in the last mixer stage,
+		 * enforce it by maxing out the cursor plane zpos */
+		ret = drm_plane_create_zpos_immutable_property(plane, DPU_ZPOS_MAX);
+	} else {
+		ret = drm_plane_create_zpos_property(plane, 0, 0, DPU_ZPOS_MAX - 1);
+	}
+
 	if (ret)
 		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
 

-- 
2.40.0



More information about the Freedreno mailing list