On 5/6/2025 8:47 AM, Jun Nie wrote:
Currently, SSPPs are assigned to a maximum of two pipes. However,
quad-pipe usage scenarios require four pipes and involve configuring
two stages. In quad-pipe case, the first two pipes share a set of
mixer configurations and enable multi-rect mode when certain
conditions are met. The same applies to the subsequent two pipes.
Assign SSPPs to the pipes in each stage using a unified method and
to loop the stages accordingly.
Signed-off-by: Jun Nie <jun....@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 68 +++++++++++++++++++------------
1 file changed, 42 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index
ea7e3fdf52f726737941ad33218a843dca17280b..de3f52d743e1d1f11ae8721a316b9872d4139069
100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1112,11 +1112,10 @@ static int dpu_plane_virtual_assign_resources(struct
drm_crtc *crtc,
struct dpu_rm_sspp_requirements reqs;
struct dpu_plane_state *pstate;
struct dpu_sw_pipe *pipe;
- struct dpu_sw_pipe *r_pipe;
struct dpu_sw_pipe_cfg *pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg;
+ struct dpu_plane *pdpu = to_dpu_plane(plane);
const struct msm_format *fmt;
- int i;
+ int i, num_lm, stage_id, num_stages;
if (plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1124,11 +1123,6 @@ static int dpu_plane_virtual_assign_resources(struct
drm_crtc *crtc,
pstate = to_dpu_plane_state(plane_state);
- pipe = &pstate->pipe[0];
- r_pipe = &pstate->pipe[1];
- pipe_cfg = &pstate->pipe_cfg[0];
- r_pipe_cfg = &pstate->pipe_cfg[1];
-
for (i = 0; i < PIPES_PER_PLANE; i++)
pstate->pipe[i].sspp = NULL;
@@ -1142,24 +1136,46 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation);
- pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
- if (!pipe->sspp)
- return -ENODEV;
-
- if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe,
r_pipe_cfg,
- pipe->sspp,
-
msm_framebuffer_format(plane_state->fb),
-
dpu_kms->catalog->caps->max_linewidth)) {
- /* multirect is not possible, use two SSPP blocks */
- r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state,
crtc, &reqs);
- if (!r_pipe->sspp)
- return -ENODEV;
-
- pipe->multirect_index = DPU_SSPP_RECT_SOLO;
- pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-
- r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
- r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+ num_lm = dpu_crtc_get_num_lm(crtc_state);
Hi Jun,
I think there might be some patch ordering issue here since
`dpu_crtc_get_num_lm()` is only declared/defined in the next patch. This
will break compilation upon partial application of the series.
Also, can you rebase this on top of the latest msm-next? The changes
here will conflict with commit 3ed12a36 ("drm/msm/dpu: allow sharing
SSPP between planes").
Thanks,
Jessica Zhang
+ num_stages = (num_lm + 1) / 2;
+ for (stage_id = 0; stage_id < num_stages; stage_id++) {
+ for (i = stage_id * PIPES_PER_STAGE; i < (stage_id + 1) *
PIPES_PER_STAGE; i++) {
+ struct dpu_sw_pipe *r_pipe;
+ struct dpu_sw_pipe_cfg *r_pipe_cfg;
+
+ pipe = &pstate->pipe[i];
+ pipe_cfg = &pstate->pipe_cfg[i];
+
+ if (drm_rect_width(&pipe_cfg->src_rect) == 0)
+ break;
+
+ pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm,
global_state, crtc, &reqs);
+ if (!pipe->sspp)
+ return -ENODEV;
+
+ r_pipe = &pstate->pipe[i + 1];
+ r_pipe_cfg = &pstate->pipe_cfg[i + 1];
+
+ /*
+ * If current pipe is the first pipe in pipe pair, check
+ * multi-rect opportunity for the 2nd pipe in the pair.
+ * SSPP multi-rect mode cross mixer pairs is not
supported.
+ */
+ if ((i % PIPES_PER_STAGE == 0) &&
+ drm_rect_width(&r_pipe_cfg->src_rect) != 0 &&
+ dpu_plane_try_multirect_parallel(pipe, pipe_cfg,
r_pipe, r_pipe_cfg,
+ pipe->sspp,
+
msm_framebuffer_format(plane_state->fb),
+
dpu_kms->catalog->caps->max_linewidth)) {
+ i++;
+ } else {
+ /* multirect is not possible, use two SSPP
blocks */
+ pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+ pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+ DPU_DEBUG_PLANE(pdpu, "allocating sspp_%d for pipe
%d.\n",
+ pipe->sspp->idx - SSPP_NONE, i);
+ }
+ }
}
return dpu_plane_atomic_check_sspp(plane, state, crtc_state);