[PATCH 17/21] drm/msm/dpu: setup pipes with 2 set of stage config

Jun Nie jun.nie at linaro.org
Thu Aug 29 10:17:46 UTC 2024


The first 2 fields in multirect_index and stage array are for the first
SSPP and its multi-rect. And the later 2 fields are for the 2nd SSPP
and its multi-rect.

Signed-off-by: Jun Nie <jun.nie at linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 76 +++++++++++++++++++++++---------
 1 file changed, 55 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 2c21a1e13d32f..3b3cd17976082 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -397,9 +397,8 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
 				       const struct msm_format *format,
 				       uint64_t modifier,
 				       struct dpu_sw_pipe *pipe,
-				       unsigned int stage_idx,
-				       struct dpu_hw_stage_cfg *stage_cfg
-				      )
+				       unsigned int pipe_idx,
+				       struct dpu_hw_stage_cfg *stage_cfg)
 {
 	uint32_t lm_idx;
 	enum dpu_sspp sspp_idx;
@@ -410,7 +409,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
 	state = plane->state;
 
 	trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-				   state, to_dpu_plane_state(state), stage_idx,
+				   state, to_dpu_plane_state(state), pipe_idx,
 				   format->pixel_format,
 				   modifier);
 
@@ -422,8 +421,14 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
 			 state->fb ? state->fb->base.id : -1,
 			 pipe->multirect_index);
 
-	stage_cfg->stage[stage][stage_idx] = sspp_idx;
-	stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
+	/* Mark sspp[sspp_idx] to be blended in stage[stage], pipe_idx decide
+	 * the SSPP is blended into which mixer. For example, SSPP 1 goes to
+	 * left half of screen, then pipe_idx 0 and 1 shall be set for sspp_idx
+	 * 1 in quad-pipe case.
+	 * The operation is done in dpu_hw_ctl_setup_blendstage()
+	 */
+	stage_cfg->stage[stage][pipe_idx] = sspp_idx;
+	stage_cfg->multirect_index[stage][pipe_idx] = pipe->multirect_index;
 
 	/* blend config update */
 	for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
@@ -441,8 +446,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_plane_state *pstate = NULL;
 	const struct msm_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
+	struct dpu_sw_pipe *pipe;
 
-	uint32_t lm_idx;
+	uint32_t lm_idx, i, c;
 	bool bg_alpha_enable = false;
 	DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
@@ -463,20 +469,48 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
 			bg_alpha_enable = true;
 
-		set_bit(pstate->pipe.sspp->idx, fetch_active);
-		_dpu_crtc_blend_setup_pipe(crtc, plane,
-					   mixer, cstate->num_mixers,
-					   pstate->stage,
-					   format, fb ? fb->modifier : 0,
-					   &pstate->pipe, 0, stage_cfg);
-
-		if (pstate->r_pipe.sspp) {
-			set_bit(pstate->r_pipe.sspp->idx, fetch_active);
-			_dpu_crtc_blend_setup_pipe(crtc, plane,
-						   mixer, cstate->num_mixers,
-						   pstate->stage,
-						   format, fb ? fb->modifier : 0,
-						   &pstate->r_pipe, 1, stage_cfg);
+		/*
+		 * Check whether the SSPP fall into left/right half of screen
+		 * via mxcfg_id. The left half is the default area with the
+		 * first config. And the right half is with the second config
+		 * in quad pipe case. The SSPP for the left half always come
+		 * first in pipe array.
+		 *
+		 * For example: there are one SSPP for left and another SSPP for
+		 * right with a super wide plane in quad-pipe case, with multi-
+		 * rect mode on both SSPP. The pipe index for the 1st SSPP are
+		 * 0/1 which goes to left half with the first 2 mixers. The pipe
+		 * index for the 2nd SSPP are 2/3 to indicate the SSPP will go
+		 * to the right half with 3rd/4th mixer in 4 mixers.
+		 *
+		 * If a small size plane is only on right half of screen in quad
+		 * pipe case, there shall be only one SSPP without multi-rect
+		 * mode. Then only the fisrt field of pipe array is valid with
+		 * the config id to be 1. The config id 1 indicates the SSPP go
+		 * to the 2nd half/rectangle of screen that clipping with the id
+		 * in dpu_plane_atomic_check_nopipe().
+		 */
+		for (c = 0; c < MIX_CFGS_IN_CRTC; c++) {
+			u32 pipe_idx = c * 2;
+
+			for (i = 0; i < PIPES_PER_STAGE; i++) {
+				DRM_DEBUG_ATOMIC("Checking pipe %d visible %d, pipe_cfg_id %d vs %d\n",
+					i, pstate->pipe_cfg[i].visible, pstate->pipe_cfg[i].mxcfg_id, c);
+				if (!pstate->pipe_cfg[i].visible)
+					break;
+				if (pstate->pipe_cfg[i].mxcfg_id != c)
+					continue;
+				pipe = &pstate->pipe[i];
+				if (!pipe->sspp)
+					continue;
+				set_bit(pipe->sspp->idx, fetch_active);
+				DRM_DEBUG_ATOMIC("blend pipe %d with sspp_%d\n", i, pipe->sspp->idx);
+				_dpu_crtc_blend_setup_pipe(crtc, plane,
+							   mixer, cstate->num_mixers,
+							   pstate->stage,
+							   format, fb ? fb->modifier : 0,
+							   pipe, pipe_idx++, stage_cfg);
+			}
 		}
 
 		/* blend config update */

-- 
2.34.1



More information about the Freedreno mailing list