On Thu, 29 Aug 2024 at 13:21, Jun Nie <jun.nie@xxxxxxxxxx> wrote: > > Support quad-pipe in SSPP checking with unified method > > Signed-off-by: Jun Nie <jun.nie@xxxxxxxxxx> > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 108 ++++++++++++++---------------- > 1 file changed, 51 insertions(+), 57 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > index 4df7cfed4d230..78bf8f0292f62 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > @@ -738,12 +738,40 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, > static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, > struct dpu_sw_pipe *pipe, > struct dpu_sw_pipe_cfg *pipe_cfg, > - const struct msm_format *fmt, > - const struct drm_display_mode *mode) > + const struct drm_display_mode *mode, > + struct drm_plane_state *new_plane_state) > { > uint32_t min_src_size; > struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); > int ret; > + const struct msm_format *fmt; > + uint32_t supported_rotations; > + const struct dpu_sspp_cfg *pipe_hw_caps; > + const struct dpu_sspp_sub_blks *sblk; > + > + pipe_hw_caps = pipe->sspp->cap; > + sblk = pipe->sspp->cap->sblk; > + > + /* > + * We already have verified scaling against platform limitations. > + * Now check if the SSPP supports scaling at all. > + */ > + if (!sblk->scaler_blk.len && > + ((drm_rect_width(&new_plane_state->src) >> 16 != > + drm_rect_width(&new_plane_state->dst)) || > + (drm_rect_height(&new_plane_state->src) >> 16 != > + drm_rect_height(&new_plane_state->dst)))) > + return -ERANGE; > + > + fmt = msm_framebuffer_format(new_plane_state->fb); > + > + supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; > + > + if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) > + supported_rotations |= DRM_MODE_ROTATE_90; > + > + pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation, > + supported_rotations); > > min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1; > > @@ -886,8 +914,7 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane *plane, > return 0; > } > > -static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe, > - struct dpu_sw_pipe_cfg *pipe_cfg, > +static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg, > const struct msm_format *fmt, > uint32_t max_linewidth) > { > @@ -916,49 +943,19 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, > drm_atomic_get_new_plane_state(state, plane); > struct dpu_plane *pdpu = to_dpu_plane(plane); > struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); > - struct dpu_sw_pipe *pipe = &pstate->pipe; > - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; > - const struct msm_format *fmt; > - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; > - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; > - uint32_t supported_rotations; > - const struct dpu_sspp_cfg *pipe_hw_caps; > - const struct dpu_sspp_sub_blks *sblk; > - int ret = 0; > - > - pipe_hw_caps = pipe->sspp->cap; > - sblk = pipe->sspp->cap->sblk; > - > - /* > - * We already have verified scaling against platform limitations. > - * Now check if the SSPP supports scaling at all. > - */ > - if (!sblk->scaler_blk.len && > - ((drm_rect_width(&new_plane_state->src) >> 16 != > - drm_rect_width(&new_plane_state->dst)) || > - (drm_rect_height(&new_plane_state->src) >> 16 != > - drm_rect_height(&new_plane_state->dst)))) > - return -ERANGE; > - > - fmt = msm_framebuffer_format(new_plane_state->fb); > - > - supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; > - > - if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) > - supported_rotations |= DRM_MODE_ROTATE_90; > - > - pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation, > - supported_rotations); > - r_pipe_cfg->rotation = pipe_cfg->rotation; > - > - ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, > - &crtc_state->adjusted_mode); > - if (ret) > - return ret; > + struct dpu_sw_pipe *pipe; > + struct dpu_sw_pipe_cfg *pipe_cfg; > + int ret = 0, i; > > - if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) { > - ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt, > - &crtc_state->adjusted_mode); > + for (i = 0; i < PIPES_PER_STAGE; i++) { > + pipe = &pstate->pipe[i]; > + pipe_cfg = &pstate->pipe_cfg[i]; > + if (!pipe_cfg->visible || !pipe->sspp) > + break; > + DPU_DEBUG_PLANE(pdpu, "pipe %d is in use, validate it\n", i); > + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, > + &crtc_state->adjusted_mode, > + new_plane_state); > if (ret) > return ret; > } > @@ -975,10 +972,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, > struct dpu_plane *pdpu = to_dpu_plane(plane); > struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); > struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); > - struct dpu_sw_pipe *pipe = &pstate->pipe; > - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; > - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; > - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; > + struct dpu_sw_pipe *pipe = &pstate->pipe[0]; > + struct dpu_sw_pipe *r_pipe = &pstate->pipe[1]; > + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0]; > + struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1]; > const struct drm_crtc_state *crtc_state = NULL; > > if (new_plane_state->crtc) > @@ -1033,13 +1030,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, > return -E2BIG; > } > > - /* > - * Use multirect for wide plane. We do not support dynamic > - * assignment of SSPPs, so we know the configuration. > - */ > pipe->multirect_index = DPU_SSPP_RECT_0; > pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; > > + r_pipe->sspp = pipe->sspp; NAK > r_pipe->multirect_index = DPU_SSPP_RECT_1; > r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; > } > @@ -1056,7 +1050,7 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane, > drm_atomic_get_old_plane_state(state, plane); > struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state); > struct drm_crtc_state *crtc_state; > - int ret; > + int ret, i; > > if (plane_state->crtc) > crtc_state = drm_atomic_get_new_crtc_state(state, > @@ -1071,8 +1065,8 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane, > * resources are freed by dpu_crtc_assign_plane_resources(), > * but clean them here. > */ > - pstate->pipe.sspp = NULL; > - pstate->r_pipe.sspp = NULL; > + for (i = 0; i < PIPES_PER_STAGE; i++) > + pstate->pipe[i].sspp = NULL; > > return 0; > } > > -- > 2.34.1 > -- With best wishes Dmitry