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@xxxxxxxxxx> --- 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