[PATCH 3/4] drm/msm/dpu: program the source split order for split planes

From: Mahadevan P

Date: Sat Oct 10 2026 - 09:40:38 EST


Virtual planes can use two SSPPs when a plane exceeds the single-pipe
width or clock limit and parallel multirect cannot be used.

Program SRC_SPLIT_ORDER during mixer setup from the pipes' destination
X positions. Set the bit for the right source and clear it for the
left source or a source without a sibling.

Fixes: 8c62a31607f6 ("drm/msm/dpu: allow using two SSPP blocks for a single plane")
Assisted-by: LLM
Signed-off-by: Mahadevan P <mahadevan.p@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 77a2d1f6700d..91152d937ba3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -434,6 +434,18 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
}

+static bool _dpu_crtc_pipe_is_right(const struct dpu_plane_state *pstate,
+ unsigned int pipe_idx)
+{
+ unsigned int other_idx = pipe_idx ^ 1;
+
+ if (!pstate->pipe[other_idx].sspp)
+ return false;
+
+ return pstate->pipe_cfg[pipe_idx].dst_rect.x1 >
+ pstate->pipe_cfg[other_idx].dst_rect.x1;
+}
+
static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
struct dpu_hw_stage_cfg *stage_cfg)
@@ -443,10 +455,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
struct drm_plane_state *state;
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
struct dpu_plane_state *pstate = NULL;
+ struct dpu_sw_pipe *pipe;
const struct msm_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
u32 lm_idx, stage, i, pipe_idx, head_pipe_in_stage, lms_in_pair;
bool bg_alpha_enable = false;
+ bool src_split = test_bit(DPU_MIXER_SOURCESPLIT,
+ &mixer->hw_lm->cap->features);
DECLARE_BITMAP(active_fetch, SSPP_MAX);
DECLARE_BITMAP(active_pipes, SSPP_MAX);

@@ -475,6 +490,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
pipe_idx = i + head_pipe_in_stage;
if (!pstate->pipe[pipe_idx].sspp)
continue;
+ pipe = &pstate->pipe[pipe_idx];
+ if (src_split && pipe->sspp->ops.setup_src_split_order)
+ pipe->sspp->ops.setup_src_split_order(pipe,
+ _dpu_crtc_pipe_is_right(pstate, pipe_idx));
lms_in_pair = min(cstate->num_mixers - (stage * PIPES_PER_STAGE),
PIPES_PER_STAGE);
set_bit(pstate->pipe[pipe_idx].sspp->idx, active_fetch);

--
2.34.1