[PATCH 2/4] drm/msm/dpu: add SSPP op to program the source split order

From: Mahadevan P

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


DPU 5.0 introduced SRC_SPLIT_ORDER in bit 4 of SSPP_SRC_OP_MODE and
SSPP_SRC_OP_MODE_REC1. For source-split pairs using legacy CTL routing,
this field identifies the left source with 0 and the right source with 1.

Add a setup_src_split_order() operation for the SSPP register layout
used on DPU 5.0 through 12.x. Select SSPP_SRC_OP_MODE for SOLO or RECT0
and SSPP_SRC_OP_MODE_REC1 for RECT1, and update only the ordering bit.

Assisted-by: LLM
Signed-off-by: Mahadevan P <mahadevan.p@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 35 +++++++++++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 11 +++++++++
2 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index b5e50fc1916f..f6ec883f9066 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -84,6 +84,7 @@
#define MDSS_MDP_OP_IGC_EN BIT(16)
#define MDSS_MDP_OP_FLIP_UD BIT(14)
#define MDSS_MDP_OP_FLIP_LR BIT(13)
+#define MDSS_MDP_OP_SRC_SPLIT_ORDER BIT(4)
#define MDSS_MDP_OP_BWC_EN BIT(0)
#define MDSS_MDP_OP_PE_OVERRIDE BIT(31)
#define MDSS_MDP_OP_BWC_LOSSLESS (0 << 1)
@@ -260,6 +261,38 @@ static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
ubwc_ctrl_off, ubwc_error_off);
}

+void dpu_hw_setup_src_split_order_impl(struct dpu_hw_sspp *ctx,
+ u32 op_mode_off, bool right)
+{
+ u32 opmode;
+
+ opmode = DPU_REG_READ(&ctx->hw, op_mode_off);
+ if (right)
+ opmode |= MDSS_MDP_OP_SRC_SPLIT_ORDER;
+ else
+ opmode &= ~MDSS_MDP_OP_SRC_SPLIT_ORDER;
+
+ DPU_REG_WRITE(&ctx->hw, op_mode_off, opmode);
+}
+
+static void dpu_hw_sspp_setup_src_split_order(struct dpu_sw_pipe *pipe,
+ bool right)
+{
+ struct dpu_hw_sspp *ctx = pipe->sspp;
+ u32 op_mode_off;
+
+ if (!ctx)
+ return;
+
+ if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+ pipe->multirect_index == DPU_SSPP_RECT_0)
+ op_mode_off = SSPP_SRC_OP_MODE;
+ else
+ op_mode_off = SSPP_SRC_OP_MODE_REC1;
+
+ dpu_hw_setup_src_split_order_impl(ctx, op_mode_off, right);
+}
+
void dpu_hw_setup_format_impl(struct dpu_sw_pipe *pipe, const struct msm_format *fmt,
u32 flags, struct dpu_hw_sspp *ctx, u32 op_mode_off,
u32 unpack_pat_off, u32 format_off, u32 ubwc_ctrl_off,
@@ -636,6 +669,8 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c,
c->ops.setup_sourceaddress = dpu_hw_sspp_setup_sourceaddress;
c->ops.setup_solidfill = dpu_hw_sspp_setup_solidfill;
c->ops.setup_pe = dpu_hw_sspp_setup_pe_config;
+ if (mdss_rev->core_major_ver >= 5)
+ c->ops.setup_src_split_order = dpu_hw_sspp_setup_src_split_order;

if (test_bit(DPU_SSPP_QOS, &features)) {
c->ops.setup_qos_lut = dpu_hw_sspp_setup_qos_lut;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 69d68cc916b2..9b9ea2e00a00 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -236,6 +236,14 @@ struct dpu_hw_sspp_ops {

void (*setup_multirect)(struct dpu_sw_pipe *pipe);

+ /**
+ * @setup_src_split_order: program the position of the pipe within
+ * a source split pair
+ * @pipe: Pointer to pipe context
+ * @right: true if the pipe fetches the right half of the pair
+ */
+ void (*setup_src_split_order)(struct dpu_sw_pipe *pipe, bool right);
+
/**
* @setup_sharpening: setup sharpening
* @ctx: Pointer to pipe context
@@ -349,6 +357,9 @@ void dpu_hw_setup_multirect_impl(struct dpu_sw_pipe *pipe,
struct dpu_hw_sspp *ctx,
u32 op_mode_off);

+void dpu_hw_setup_src_split_order_impl(struct dpu_hw_sspp *ctx,
+ u32 op_mode_off, bool right);
+
void dpu_hw_setup_format_impl(struct dpu_sw_pipe *pipe, const struct msm_format *fmt,
u32 flags, struct dpu_hw_sspp *ctx,
u32 op_mode_off, u32 unpack_pat_off, u32 format_off,

--
2.34.1