* [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function
2026-01-21 8:01 [PATCH v17 0/4] drm/msm/dpu: Support quad pipe with dual-interface Jun Nie
@ 2026-01-21 8:01 ` Jun Nie
2026-01-21 9:28 ` Dmitry Baryshkov
2026-01-21 8:01 ` [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check Jun Nie
` (2 subsequent siblings)
3 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-21 8:01 UTC (permalink / raw)
To: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
dpu_plane_atomic_check_nosspp() currently handles both plane
validation and plane splitting. For better simplicity and to
facilitate future refactoring, move the splitting logic into
its own dedicated function.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 51 ++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9b7a8b46bfa91..66f240ce29d07 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -821,13 +821,8 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
{
int i, ret = 0, min_scale, max_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
- struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
- u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
- struct dpu_sw_pipe_cfg *pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg;
struct drm_rect fb_rect = { 0 };
- uint32_t max_linewidth;
min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO);
max_scale = MAX_DOWNSCALE_RATIO << 16;
@@ -850,14 +845,6 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
return -EINVAL;
}
- /* move the assignment here, to ease handling to another pairs later */
- pipe_cfg = &pstate->pipe_cfg[0];
- r_pipe_cfg = &pstate->pipe_cfg[1];
- /* state->src is 16.16, src_rect is not */
- drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
-
- pipe_cfg->dst_rect = new_plane_state->dst;
-
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
@@ -879,6 +866,34 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
if (pstate->layout.plane_pitch[i] > DPU_SSPP_MAX_PITCH_SIZE)
return -E2BIG;
+ pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
+
+ return 0;
+}
+
+static int dpu_plane_split(struct drm_plane *plane,
+ struct drm_plane_state *new_plane_state,
+ const struct drm_crtc_state *crtc_state)
+{
+ struct dpu_plane *pdpu = to_dpu_plane(plane);
+ struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+ u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
+ struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+ struct dpu_sw_pipe_cfg *pipe_cfg;
+ struct dpu_sw_pipe_cfg *r_pipe_cfg;
+ uint32_t max_linewidth;
+
+ if (!new_plane_state->visible)
+ return 0;
+
+ /* move the assignment here, to ease handling to another pairs later */
+ pipe_cfg = &pstate->pipe_cfg[0];
+ r_pipe_cfg = &pstate->pipe_cfg[1];
+ /* state->src is 16.16, src_rect is not */
+ drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
+
+ pipe_cfg->dst_rect = new_plane_state->dst;
+
max_linewidth = pdpu->catalog->caps->max_linewidth;
drm_rect_rotate(&pipe_cfg->src_rect,
@@ -910,8 +925,6 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
new_plane_state->fb->width, new_plane_state->fb->height,
new_plane_state->rotation);
- pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
-
return 0;
}
@@ -1129,6 +1142,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (ret)
return ret;
+ ret = dpu_plane_split(plane, new_plane_state, crtc_state);
+ if (ret)
+ return ret;
+
if (!new_plane_state->visible)
return 0;
@@ -1169,6 +1186,10 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
if (ret)
return ret;
+ ret = dpu_plane_split(plane, plane_state, crtc_state);
+ if (ret)
+ return ret;
+
if (!plane_state->visible) {
/*
* resources are freed by dpu_crtc_assign_plane_resources(),
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function
2026-01-21 8:01 ` [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function Jun Nie
@ 2026-01-21 9:28 ` Dmitry Baryshkov
2026-01-21 9:47 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-21 9:28 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On Wed, Jan 21, 2026 at 04:01:50PM +0800, Jun Nie wrote:
> dpu_plane_atomic_check_nosspp() currently handles both plane
> validation and plane splitting. For better simplicity and to
> facilitate future refactoring, move the splitting logic into
> its own dedicated function.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 51 ++++++++++++++++++++++---------
> 1 file changed, 36 insertions(+), 15 deletions(-)
>
> @@ -879,6 +866,34 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> if (pstate->layout.plane_pitch[i] > DPU_SSPP_MAX_PITCH_SIZE)
> return -E2BIG;
>
> + pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
> +
> + return 0;
> +}
> +
> +static int dpu_plane_split(struct drm_plane *plane,
> + struct drm_plane_state *new_plane_state,
> + const struct drm_crtc_state *crtc_state)
> +{
> + struct dpu_plane *pdpu = to_dpu_plane(plane);
> + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> + u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
> + struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> + struct dpu_sw_pipe_cfg *pipe_cfg;
> + struct dpu_sw_pipe_cfg *r_pipe_cfg;
> + uint32_t max_linewidth;
> +
> + if (!new_plane_state->visible)
> + return 0;
> +
> + /* move the assignment here, to ease handling to another pairs later */
> + pipe_cfg = &pstate->pipe_cfg[0];
> + r_pipe_cfg = &pstate->pipe_cfg[1];
> + /* state->src is 16.16, src_rect is not */
> + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
> +
> + pipe_cfg->dst_rect = new_plane_state->dst;
> +
> max_linewidth = pdpu->catalog->caps->max_linewidth;
>
> drm_rect_rotate(&pipe_cfg->src_rect,
> @@ -910,8 +925,6 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> new_plane_state->fb->width, new_plane_state->fb->height,
> new_plane_state->rotation);
>
> - pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
> -
> return 0;
> }
>
> @@ -1129,6 +1142,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> if (ret)
> return ret;
>
> + ret = dpu_plane_split(plane, new_plane_state, crtc_state);
> + if (ret)
> + return ret;
> +
> if (!new_plane_state->visible)
> return 0;
>
> @@ -1169,6 +1186,10 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> if (ret)
> return ret;
>
> + ret = dpu_plane_split(plane, plane_state, crtc_state);
> + if (ret)
> + return ret;
Why can't it be moved after !visible check? It's the first check in the
function code.
> +
> if (!plane_state->visible) {
> /*
> * resources are freed by dpu_crtc_assign_plane_resources(),
>
> --
> 2.43.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function
2026-01-21 9:28 ` Dmitry Baryshkov
@ 2026-01-21 9:47 ` Jun Nie
0 siblings, 0 replies; 21+ messages in thread
From: Jun Nie @ 2026-01-21 9:47 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:29写道:
>
> On Wed, Jan 21, 2026 at 04:01:50PM +0800, Jun Nie wrote:
> > dpu_plane_atomic_check_nosspp() currently handles both plane
> > validation and plane splitting. For better simplicity and to
> > facilitate future refactoring, move the splitting logic into
> > its own dedicated function.
> >
> > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > ---
> > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 51 ++++++++++++++++++++++---------
> > 1 file changed, 36 insertions(+), 15 deletions(-)
> >
> > @@ -879,6 +866,34 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> > if (pstate->layout.plane_pitch[i] > DPU_SSPP_MAX_PITCH_SIZE)
> > return -E2BIG;
> >
> > + pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
> > +
> > + return 0;
> > +}
> > +
> > +static int dpu_plane_split(struct drm_plane *plane,
> > + struct drm_plane_state *new_plane_state,
> > + const struct drm_crtc_state *crtc_state)
> > +{
> > + struct dpu_plane *pdpu = to_dpu_plane(plane);
> > + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> > + u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
> > + struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> > + struct dpu_sw_pipe_cfg *pipe_cfg;
> > + struct dpu_sw_pipe_cfg *r_pipe_cfg;
> > + uint32_t max_linewidth;
> > +
> > + if (!new_plane_state->visible)
> > + return 0;
> > +
> > + /* move the assignment here, to ease handling to another pairs later */
> > + pipe_cfg = &pstate->pipe_cfg[0];
> > + r_pipe_cfg = &pstate->pipe_cfg[1];
> > + /* state->src is 16.16, src_rect is not */
> > + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
> > +
> > + pipe_cfg->dst_rect = new_plane_state->dst;
> > +
> > max_linewidth = pdpu->catalog->caps->max_linewidth;
> >
> > drm_rect_rotate(&pipe_cfg->src_rect,
> > @@ -910,8 +925,6 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> > new_plane_state->fb->width, new_plane_state->fb->height,
> > new_plane_state->rotation);
> >
> > - pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
> > -
> > return 0;
> > }
> >
> > @@ -1129,6 +1142,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> > if (ret)
> > return ret;
> >
> > + ret = dpu_plane_split(plane, new_plane_state, crtc_state);
> > + if (ret)
> > + return ret;
> > +
> > if (!new_plane_state->visible)
> > return 0;
> >
> > @@ -1169,6 +1186,10 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> > if (ret)
> > return ret;
> >
> > + ret = dpu_plane_split(plane, plane_state, crtc_state);
> > + if (ret)
> > + return ret;
>
> Why can't it be moved after !visible check? It's the first check in the
> function code.
Surely it can be moved after !visible check and it is a better place. Placing
it just after dpu_plane_atomic_check_nosspp() is because
it is splitted from it. And it does not matter actually, because
dpu_plane_split() is moved to the deferred part
dpu_plane_virtual_assign_resources()
in the later patch. So that topology information is ready at that stage.
>
> > +
> > if (!plane_state->visible) {
> > /*
> > * resources are freed by dpu_crtc_assign_plane_resources(),
> >
> > --
> > 2.43.0
> >
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-21 8:01 [PATCH v17 0/4] drm/msm/dpu: Support quad pipe with dual-interface Jun Nie
2026-01-21 8:01 ` [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function Jun Nie
@ 2026-01-21 8:01 ` Jun Nie
2026-01-21 9:30 ` Dmitry Baryshkov
2026-01-21 8:01 ` [PATCH v17 3/4] drm/msm/dpu: support plane splitting in quad-pipe case Jun Nie
2026-01-21 8:01 ` [PATCH v17 4/4] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case Jun Nie
3 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-21 8:01 UTC (permalink / raw)
To: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Currently, plane splitting and SSPP allocation occur during the plane
check phase. Defer these operations until dpu_assign_plane_resources()
is called from the CRTC side to ensure the topology information from
the CRTC check is available.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 112 +++++++++++++++++++-----------
2 files changed, 71 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 2d06c950e8143..debdbbe6160dd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1484,8 +1484,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return rc;
}
- if (dpu_use_virtual_planes &&
- (crtc_state->planes_changed || crtc_state->zpos_changed)) {
+ if (crtc_state->planes_changed || crtc_state->zpos_changed) {
rc = dpu_crtc_reassign_planes(crtc, crtc_state);
if (rc < 0)
return rc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 66f240ce29d07..3c629f4df461d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1119,49 +1119,25 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
int ret = 0;
- 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[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;
- uint32_t max_linewidth = dpu_kms->catalog->caps->max_linewidth;
+ struct drm_crtc_state *crtc_state = NULL;
if (new_plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
new_plane_state->crtc);
- pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
-
- if (!pipe->sspp)
- return -EINVAL;
-
ret = dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state);
if (ret)
return ret;
- ret = dpu_plane_split(plane, new_plane_state, crtc_state);
- if (ret)
- return ret;
-
if (!new_plane_state->visible)
return 0;
- if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
- pipe->sspp,
- msm_framebuffer_format(new_plane_state->fb),
- max_linewidth)) {
- DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
- " max_line:%u, can't use split source\n",
- DRM_RECT_ARG(&pipe_cfg->src_rect),
- DRM_RECT_ARG(&r_pipe_cfg->src_rect),
- max_linewidth);
- return -E2BIG;
- }
-
- return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
+ /*
+ * To trigger the callback of dpu_assign_plane_resources() to
+ * finish the deferred sspp check
+ */
+ crtc_state->planes_changed = true;
+ return 0;
}
static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
@@ -1186,10 +1162,6 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
if (ret)
return ret;
- ret = dpu_plane_split(plane, plane_state, crtc_state);
- if (ret)
- return ret;
-
if (!plane_state->visible) {
/*
* resources are freed by dpu_crtc_assign_plane_resources(),
@@ -1261,9 +1233,9 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
struct dpu_global_state *global_state,
struct drm_atomic_state *state,
struct drm_plane_state *plane_state,
+ const struct drm_crtc_state *crtc_state,
struct drm_plane_state **prev_adjacent_plane_state)
{
- const struct drm_crtc_state *crtc_state = NULL;
struct drm_plane *plane = plane_state->plane;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
struct dpu_rm_sspp_requirements reqs;
@@ -1273,10 +1245,6 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
const struct msm_format *fmt;
int i, ret;
- if (plane_state->crtc)
- crtc_state = drm_atomic_get_new_crtc_state(state,
- plane_state->crtc);
-
pstate = to_dpu_plane_state(plane_state);
for (i = 0; i < STAGES_PER_PLANE; i++)
prev_adjacent_pstate[i] = prev_adjacent_plane_state[i] ?
@@ -1288,6 +1256,10 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
if (!plane_state->fb)
return -EINVAL;
+ ret = dpu_plane_split(plane, plane_state, crtc_state);
+ if (ret)
+ return ret;
+
fmt = msm_framebuffer_format(plane_state->fb);
reqs.yuv = MSM_FORMAT_IS_YUV(fmt);
reqs.scale = (plane_state->src_w >> 16 != plane_state->crtc_w) ||
@@ -1318,14 +1290,59 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
}
+static int dpu_plane_assign_resources(struct drm_crtc *crtc,
+ struct dpu_global_state *global_state,
+ struct drm_atomic_state *state,
+ struct drm_plane_state *plane_state,
+ const struct drm_crtc_state *crtc_state,
+ struct drm_plane_state **prev_adjacent_plane_state)
+{
+ struct drm_plane *plane = plane_state->plane;
+ struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+ struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
+ 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];
+ struct dpu_plane *pdpu = to_dpu_plane(plane);
+ int ret;
+
+ if (!plane_state->visible)
+ return 0;
+
+ pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+ if (!pipe->sspp)
+ return -EINVAL;
+
+ ret = dpu_plane_split(plane, plane_state, crtc_state);
+ if (ret)
+ return ret;
+
+ 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)) {
+ DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
+ " max_line:%u, can't use split source\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect),
+ DRM_RECT_ARG(&r_pipe_cfg->src_rect),
+ dpu_kms->catalog->caps->max_linewidth);
+ return -E2BIG;
+ }
+
+ return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
+}
+
int dpu_assign_plane_resources(struct dpu_global_state *global_state,
struct drm_atomic_state *state,
struct drm_crtc *crtc,
struct drm_plane_state **states,
unsigned int num_planes)
{
- unsigned int i;
struct drm_plane_state *prev_adjacent_plane_state[STAGES_PER_PLANE] = { NULL };
+ const struct drm_crtc_state *crtc_state = NULL;
+ unsigned int i;
+ int ret;
for (i = 0; i < num_planes; i++) {
struct drm_plane_state *plane_state = states[i];
@@ -1334,8 +1351,19 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
!plane_state->visible)
continue;
- int ret = dpu_plane_virtual_assign_resources(crtc, global_state,
+ if (plane_state->crtc)
+ crtc_state = drm_atomic_get_new_crtc_state(state,
+ plane_state->crtc);
+
+ if (!dpu_use_virtual_planes)
+ ret = dpu_plane_assign_resources(crtc, global_state,
+ state, plane_state,
+ crtc_state,
+ prev_adjacent_plane_state);
+ else
+ ret = dpu_plane_virtual_assign_resources(crtc, global_state,
state, plane_state,
+ crtc_state,
prev_adjacent_plane_state);
if (ret)
return ret;
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-21 8:01 ` [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check Jun Nie
@ 2026-01-21 9:30 ` Dmitry Baryshkov
2026-01-22 6:03 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-21 9:30 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> Currently, plane splitting and SSPP allocation occur during the plane
> check phase. Defer these operations until dpu_assign_plane_resources()
> is called from the CRTC side to ensure the topology information from
> the CRTC check is available.
Why is it important? What is broken otherwise?
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 112 +++++++++++++++++++-----------
> 2 files changed, 71 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 2d06c950e8143..debdbbe6160dd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1484,8 +1484,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> return rc;
> }
>
> - if (dpu_use_virtual_planes &&
> - (crtc_state->planes_changed || crtc_state->zpos_changed)) {
> + if (crtc_state->planes_changed || crtc_state->zpos_changed) {
> rc = dpu_crtc_reassign_planes(crtc, crtc_state);
> if (rc < 0)
> return rc;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 66f240ce29d07..3c629f4df461d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1119,49 +1119,25 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
> plane);
> int ret = 0;
> - 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[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;
> - uint32_t max_linewidth = dpu_kms->catalog->caps->max_linewidth;
> + struct drm_crtc_state *crtc_state = NULL;
>
> if (new_plane_state->crtc)
> crtc_state = drm_atomic_get_new_crtc_state(state,
> new_plane_state->crtc);
>
> - pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> -
> - if (!pipe->sspp)
> - return -EINVAL;
> -
> ret = dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state);
> if (ret)
> return ret;
>
> - ret = dpu_plane_split(plane, new_plane_state, crtc_state);
> - if (ret)
> - return ret;
> -
> if (!new_plane_state->visible)
> return 0;
>
> - if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
> - pipe->sspp,
> - msm_framebuffer_format(new_plane_state->fb),
> - max_linewidth)) {
> - DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
> - " max_line:%u, can't use split source\n",
> - DRM_RECT_ARG(&pipe_cfg->src_rect),
> - DRM_RECT_ARG(&r_pipe_cfg->src_rect),
> - max_linewidth);
> - return -E2BIG;
> - }
> -
> - return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
> + /*
> + * To trigger the callback of dpu_assign_plane_resources() to
> + * finish the deferred sspp check
> + */
> + crtc_state->planes_changed = true;
> + return 0;
> }
>
> static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> @@ -1186,10 +1162,6 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> if (ret)
> return ret;
>
> - ret = dpu_plane_split(plane, plane_state, crtc_state);
> - if (ret)
> - return ret;
> -
> if (!plane_state->visible) {
> /*
> * resources are freed by dpu_crtc_assign_plane_resources(),
> @@ -1261,9 +1233,9 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> struct dpu_global_state *global_state,
> struct drm_atomic_state *state,
> struct drm_plane_state *plane_state,
> + const struct drm_crtc_state *crtc_state,
> struct drm_plane_state **prev_adjacent_plane_state)
> {
> - const struct drm_crtc_state *crtc_state = NULL;
> struct drm_plane *plane = plane_state->plane;
> struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> struct dpu_rm_sspp_requirements reqs;
> @@ -1273,10 +1245,6 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> const struct msm_format *fmt;
> int i, ret;
>
> - if (plane_state->crtc)
> - crtc_state = drm_atomic_get_new_crtc_state(state,
> - plane_state->crtc);
> -
> pstate = to_dpu_plane_state(plane_state);
> for (i = 0; i < STAGES_PER_PLANE; i++)
> prev_adjacent_pstate[i] = prev_adjacent_plane_state[i] ?
> @@ -1288,6 +1256,10 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> if (!plane_state->fb)
> return -EINVAL;
>
> + ret = dpu_plane_split(plane, plane_state, crtc_state);
> + if (ret)
> + return ret;
> +
> fmt = msm_framebuffer_format(plane_state->fb);
> reqs.yuv = MSM_FORMAT_IS_YUV(fmt);
> reqs.scale = (plane_state->src_w >> 16 != plane_state->crtc_w) ||
> @@ -1318,14 +1290,59 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
> }
>
> +static int dpu_plane_assign_resources(struct drm_crtc *crtc,
> + struct dpu_global_state *global_state,
> + struct drm_atomic_state *state,
> + struct drm_plane_state *plane_state,
> + const struct drm_crtc_state *crtc_state,
> + struct drm_plane_state **prev_adjacent_plane_state)
> +{
> + struct drm_plane *plane = plane_state->plane;
> + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> + struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
> + 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];
> + struct dpu_plane *pdpu = to_dpu_plane(plane);
> + int ret;
> +
> + if (!plane_state->visible)
> + return 0;
> +
> + pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> + if (!pipe->sspp)
> + return -EINVAL;
> +
> + ret = dpu_plane_split(plane, plane_state, crtc_state);
> + if (ret)
> + return ret;
> +
> + 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)) {
> + DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
> + " max_line:%u, can't use split source\n",
> + DRM_RECT_ARG(&pipe_cfg->src_rect),
> + DRM_RECT_ARG(&r_pipe_cfg->src_rect),
> + dpu_kms->catalog->caps->max_linewidth);
> + return -E2BIG;
> + }
> +
> + return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
> +}
> +
> int dpu_assign_plane_resources(struct dpu_global_state *global_state,
> struct drm_atomic_state *state,
> struct drm_crtc *crtc,
> struct drm_plane_state **states,
> unsigned int num_planes)
> {
> - unsigned int i;
> struct drm_plane_state *prev_adjacent_plane_state[STAGES_PER_PLANE] = { NULL };
> + const struct drm_crtc_state *crtc_state = NULL;
> + unsigned int i;
> + int ret;
>
> for (i = 0; i < num_planes; i++) {
> struct drm_plane_state *plane_state = states[i];
> @@ -1334,8 +1351,19 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
> !plane_state->visible)
> continue;
>
> - int ret = dpu_plane_virtual_assign_resources(crtc, global_state,
> + if (plane_state->crtc)
> + crtc_state = drm_atomic_get_new_crtc_state(state,
> + plane_state->crtc);
> +
> + if (!dpu_use_virtual_planes)
> + ret = dpu_plane_assign_resources(crtc, global_state,
> + state, plane_state,
> + crtc_state,
> + prev_adjacent_plane_state);
> + else
> + ret = dpu_plane_virtual_assign_resources(crtc, global_state,
> state, plane_state,
> + crtc_state,
> prev_adjacent_plane_state);
> if (ret)
> return ret;
>
> --
> 2.43.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-21 9:30 ` Dmitry Baryshkov
@ 2026-01-22 6:03 ` Jun Nie
2026-01-22 10:22 ` Dmitry Baryshkov
0 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-22 6:03 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
>
> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > Currently, plane splitting and SSPP allocation occur during the plane
> > check phase. Defer these operations until dpu_assign_plane_resources()
> > is called from the CRTC side to ensure the topology information from
> > the CRTC check is available.
>
> Why is it important? What is broken otherwise?
I see. Thanks! Will add below lines in next version.
By default, the plane check occurs before the CRTC check.
Without topology information from the CRTC, plane splitting
cannot be properly executed. Consequently, the SSPP
engine starts without a valid memory address, which triggers
an IOMMU warning.
>
> >
> > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > ---
> > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 +-
> > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 112 +++++++++++++++++++-----------
> > 2 files changed, 71 insertions(+), 44 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 2d06c950e8143..debdbbe6160dd 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -1484,8 +1484,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> > return rc;
> > }
> >
> > - if (dpu_use_virtual_planes &&
> > - (crtc_state->planes_changed || crtc_state->zpos_changed)) {
> > + if (crtc_state->planes_changed || crtc_state->zpos_changed) {
> > rc = dpu_crtc_reassign_planes(crtc, crtc_state);
> > if (rc < 0)
> > return rc;
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 66f240ce29d07..3c629f4df461d 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -1119,49 +1119,25 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> > struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
> > plane);
> > int ret = 0;
> > - 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[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;
> > - uint32_t max_linewidth = dpu_kms->catalog->caps->max_linewidth;
> > + struct drm_crtc_state *crtc_state = NULL;
> >
> > if (new_plane_state->crtc)
> > crtc_state = drm_atomic_get_new_crtc_state(state,
> > new_plane_state->crtc);
> >
> > - pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> > -
> > - if (!pipe->sspp)
> > - return -EINVAL;
> > -
> > ret = dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state);
> > if (ret)
> > return ret;
> >
> > - ret = dpu_plane_split(plane, new_plane_state, crtc_state);
> > - if (ret)
> > - return ret;
> > -
> > if (!new_plane_state->visible)
> > return 0;
> >
> > - if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
> > - pipe->sspp,
> > - msm_framebuffer_format(new_plane_state->fb),
> > - max_linewidth)) {
> > - DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
> > - " max_line:%u, can't use split source\n",
> > - DRM_RECT_ARG(&pipe_cfg->src_rect),
> > - DRM_RECT_ARG(&r_pipe_cfg->src_rect),
> > - max_linewidth);
> > - return -E2BIG;
> > - }
> > -
> > - return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
> > + /*
> > + * To trigger the callback of dpu_assign_plane_resources() to
> > + * finish the deferred sspp check
> > + */
> > + crtc_state->planes_changed = true;
> > + return 0;
> > }
> >
> > static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> > @@ -1186,10 +1162,6 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> > if (ret)
> > return ret;
> >
> > - ret = dpu_plane_split(plane, plane_state, crtc_state);
> > - if (ret)
> > - return ret;
> > -
> > if (!plane_state->visible) {
> > /*
> > * resources are freed by dpu_crtc_assign_plane_resources(),
> > @@ -1261,9 +1233,9 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> > struct dpu_global_state *global_state,
> > struct drm_atomic_state *state,
> > struct drm_plane_state *plane_state,
> > + const struct drm_crtc_state *crtc_state,
> > struct drm_plane_state **prev_adjacent_plane_state)
> > {
> > - const struct drm_crtc_state *crtc_state = NULL;
> > struct drm_plane *plane = plane_state->plane;
> > struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> > struct dpu_rm_sspp_requirements reqs;
> > @@ -1273,10 +1245,6 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> > const struct msm_format *fmt;
> > int i, ret;
> >
> > - if (plane_state->crtc)
> > - crtc_state = drm_atomic_get_new_crtc_state(state,
> > - plane_state->crtc);
> > -
> > pstate = to_dpu_plane_state(plane_state);
> > for (i = 0; i < STAGES_PER_PLANE; i++)
> > prev_adjacent_pstate[i] = prev_adjacent_plane_state[i] ?
> > @@ -1288,6 +1256,10 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> > if (!plane_state->fb)
> > return -EINVAL;
> >
> > + ret = dpu_plane_split(plane, plane_state, crtc_state);
> > + if (ret)
> > + return ret;
> > +
> > fmt = msm_framebuffer_format(plane_state->fb);
> > reqs.yuv = MSM_FORMAT_IS_YUV(fmt);
> > reqs.scale = (plane_state->src_w >> 16 != plane_state->crtc_w) ||
> > @@ -1318,14 +1290,59 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> > return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
> > }
> >
> > +static int dpu_plane_assign_resources(struct drm_crtc *crtc,
> > + struct dpu_global_state *global_state,
> > + struct drm_atomic_state *state,
> > + struct drm_plane_state *plane_state,
> > + const struct drm_crtc_state *crtc_state,
> > + struct drm_plane_state **prev_adjacent_plane_state)
> > +{
> > + struct drm_plane *plane = plane_state->plane;
> > + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> > + struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
> > + 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];
> > + struct dpu_plane *pdpu = to_dpu_plane(plane);
> > + int ret;
> > +
> > + if (!plane_state->visible)
> > + return 0;
> > +
> > + pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> > + if (!pipe->sspp)
> > + return -EINVAL;
> > +
> > + ret = dpu_plane_split(plane, plane_state, crtc_state);
> > + if (ret)
> > + return ret;
> > +
> > + 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)) {
> > + DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
> > + " max_line:%u, can't use split source\n",
> > + DRM_RECT_ARG(&pipe_cfg->src_rect),
> > + DRM_RECT_ARG(&r_pipe_cfg->src_rect),
> > + dpu_kms->catalog->caps->max_linewidth);
> > + return -E2BIG;
> > + }
> > +
> > + return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
> > +}
> > +
> > int dpu_assign_plane_resources(struct dpu_global_state *global_state,
> > struct drm_atomic_state *state,
> > struct drm_crtc *crtc,
> > struct drm_plane_state **states,
> > unsigned int num_planes)
> > {
> > - unsigned int i;
> > struct drm_plane_state *prev_adjacent_plane_state[STAGES_PER_PLANE] = { NULL };
> > + const struct drm_crtc_state *crtc_state = NULL;
> > + unsigned int i;
> > + int ret;
> >
> > for (i = 0; i < num_planes; i++) {
> > struct drm_plane_state *plane_state = states[i];
> > @@ -1334,8 +1351,19 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
> > !plane_state->visible)
> > continue;
> >
> > - int ret = dpu_plane_virtual_assign_resources(crtc, global_state,
> > + if (plane_state->crtc)
> > + crtc_state = drm_atomic_get_new_crtc_state(state,
> > + plane_state->crtc);
> > +
> > + if (!dpu_use_virtual_planes)
> > + ret = dpu_plane_assign_resources(crtc, global_state,
> > + state, plane_state,
> > + crtc_state,
> > + prev_adjacent_plane_state);
> > + else
> > + ret = dpu_plane_virtual_assign_resources(crtc, global_state,
> > state, plane_state,
> > + crtc_state,
> > prev_adjacent_plane_state);
> > if (ret)
> > return ret;
> >
> > --
> > 2.43.0
> >
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-22 6:03 ` Jun Nie
@ 2026-01-22 10:22 ` Dmitry Baryshkov
2026-01-26 10:06 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-22 10:22 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> >
> > On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > Currently, plane splitting and SSPP allocation occur during the plane
> > > check phase. Defer these operations until dpu_assign_plane_resources()
> > > is called from the CRTC side to ensure the topology information from
> > > the CRTC check is available.
> >
> > Why is it important? What is broken otherwise?
>
> I see. Thanks! Will add below lines in next version.
>
> By default, the plane check occurs before the CRTC check.
> Without topology information from the CRTC, plane splitting
> cannot be properly executed. Consequently, the SSPP
> engine starts without a valid memory address, which triggers
> an IOMMU warning.
What is plane splitting? Write commit message for somebody who doesn't
exactly know what is going on.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-22 10:22 ` Dmitry Baryshkov
@ 2026-01-26 10:06 ` Jun Nie
2026-01-26 10:13 ` Dmitry Baryshkov
0 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-26 10:06 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
>
> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > >
> > > On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > > Currently, plane splitting and SSPP allocation occur during the plane
> > > > check phase. Defer these operations until dpu_assign_plane_resources()
> > > > is called from the CRTC side to ensure the topology information from
> > > > the CRTC check is available.
> > >
> > > Why is it important? What is broken otherwise?
> >
> > I see. Thanks! Will add below lines in next version.
> >
> > By default, the plane check occurs before the CRTC check.
> > Without topology information from the CRTC, plane splitting
> > cannot be properly executed. Consequently, the SSPP
> > engine starts without a valid memory address, which triggers
> > an IOMMU warning.
>
> What is plane splitting? Write commit message for somebody who doesn't
> exactly know what is going on.
Thanks for the suggestion! Any more revise is needed?
Currently, splitting plane into SSPP rectangles the allocation occur
during the plane check phase, so that a plane can be supported by
multiple hardware pipe. While pipe topology is decided in CRTC check.
By default, the plane check occurs before the CRTC check in DRM
framework. Without topology information from the CRTC, plane splitting
cannot be properly executed. Consequently, the SSPP engine starts
without a valid memory address, which triggers IOMMU warning.
Defer above plane operations until dpu_assign_plane_resources()
is called from the CRTC side to ensure the topology information from
the CRTC check is available.
Regards,
Jun
>
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 10:06 ` Jun Nie
@ 2026-01-26 10:13 ` Dmitry Baryshkov
2026-01-26 10:29 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-26 10:13 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On 26/01/2026 12:06, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
>>
>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
>>>>
>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
>>>>> Currently, plane splitting and SSPP allocation occur during the plane
>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
>>>>> is called from the CRTC side to ensure the topology information from
>>>>> the CRTC check is available.
>>>>
>>>> Why is it important? What is broken otherwise?
>>>
>>> I see. Thanks! Will add below lines in next version.
>>>
>>> By default, the plane check occurs before the CRTC check.
>>> Without topology information from the CRTC, plane splitting
>>> cannot be properly executed. Consequently, the SSPP
>>> engine starts without a valid memory address, which triggers
>>> an IOMMU warning.
>>
>> What is plane splitting? Write commit message for somebody who doesn't
>> exactly know what is going on.
>
> Thanks for the suggestion! Any more revise is needed?
Sadly enough the text below is not a significant improvement.
>
> Currently, splitting plane into SSPP rectangles the allocation occur
> during the plane check phase, so that a plane can be supported by
> multiple hardware pipe.
What does this mean? Without virtual planes in place, there are no
multiple hardware pipes.
> While pipe topology is decided in CRTC check.
?? What does it mean here?
> By default, the plane check occurs before the CRTC check in DRM
> framework. Without topology information from the CRTC, plane splitting
> cannot be properly executed.
What does 'properly' mean here? How is it executed? What happens?
> Consequently, the SSPP engine starts
> without a valid memory address, which triggers IOMMU warning.
IOMMU faults. There are no "warnings".
>
> Defer above plane operations until dpu_assign_plane_resources()
> is called from the CRTC side to ensure the topology information from
> the CRTC check is available.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 10:13 ` Dmitry Baryshkov
@ 2026-01-26 10:29 ` Jun Nie
2026-01-26 10:49 ` Dmitry Baryshkov
0 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-26 10:29 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
>
> On 26/01/2026 12:06, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> >>
> >> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> >>>>
> >>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> >>>>> Currently, plane splitting and SSPP allocation occur during the plane
> >>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> >>>>> is called from the CRTC side to ensure the topology information from
> >>>>> the CRTC check is available.
> >>>>
> >>>> Why is it important? What is broken otherwise?
> >>>
> >>> I see. Thanks! Will add below lines in next version.
> >>>
> >>> By default, the plane check occurs before the CRTC check.
> >>> Without topology information from the CRTC, plane splitting
> >>> cannot be properly executed. Consequently, the SSPP
> >>> engine starts without a valid memory address, which triggers
> >>> an IOMMU warning.
> >>
> >> What is plane splitting? Write commit message for somebody who doesn't
> >> exactly know what is going on.
> >
> > Thanks for the suggestion! Any more revise is needed?
>
> Sadly enough the text below is not a significant improvement.
>
> >
> > Currently, splitting plane into SSPP rectangles the allocation occur
> > during the plane check phase, so that a plane can be supported by
> > multiple hardware pipe.
>
> What does this mean? Without virtual planes in place, there are no
> multiple hardware pipes.
>
> > While pipe topology is decided in CRTC check.
>
> ?? What does it mean here?
>
> > By default, the plane check occurs before the CRTC check in DRM
> > framework. Without topology information from the CRTC, plane splitting
> > cannot be properly executed.
>
> What does 'properly' mean here? How is it executed? What happens?
>
> > Consequently, the SSPP engine starts
> > without a valid memory address, which triggers IOMMU warning.
>
> IOMMU faults. There are no "warnings".
>
> >
> > Defer above plane operations until dpu_assign_plane_resources()
> > is called from the CRTC side to ensure the topology information from
> > the CRTC check is available.
>
>
Thanks for the patience!
Currently, splitting plane into SSPP rectangles and allocation occur
during the plane check phase. When virtual plane is enabled to support
quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
a plane can be supported by 4 hardware pipes. And pipe number is
decided in CRTC check per interface number, resolution and hardware
feature.
By default, the plane check occurs before the CRTC check in DRM
framework. Without topology information from the CRTC, plane splitting
will be skipped for the first time as pipe number is 0. Consequently,
the SSPP engine starts without a valid memory address, which triggers
IOMMU fault.
Defer above plane related operations until dpu_assign_plane_resources()
is called from the CRTC side to ensure the topology information from
the CRTC check is available.
Regards,
Jun
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 10:29 ` Jun Nie
@ 2026-01-26 10:49 ` Dmitry Baryshkov
2026-01-26 12:01 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-26 10:49 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On 26/01/2026 12:29, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
>>
>> On 26/01/2026 12:06, Jun Nie wrote:
>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
>>>>
>>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
>>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
>>>>>>
>>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
>>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
>>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
>>>>>>> is called from the CRTC side to ensure the topology information from
>>>>>>> the CRTC check is available.
>>>>>>
>>>>>> Why is it important? What is broken otherwise?
>>>>>
>>>>> I see. Thanks! Will add below lines in next version.
>>>>>
>>>>> By default, the plane check occurs before the CRTC check.
>>>>> Without topology information from the CRTC, plane splitting
>>>>> cannot be properly executed. Consequently, the SSPP
>>>>> engine starts without a valid memory address, which triggers
>>>>> an IOMMU warning.
>>>>
>>>> What is plane splitting? Write commit message for somebody who doesn't
>>>> exactly know what is going on.
>>>
>>> Thanks for the suggestion! Any more revise is needed?
>>
>> Sadly enough the text below is not a significant improvement.
>>
>>>
>>> Currently, splitting plane into SSPP rectangles the allocation occur
>>> during the plane check phase, so that a plane can be supported by
>>> multiple hardware pipe.
>>
>> What does this mean? Without virtual planes in place, there are no
>> multiple hardware pipes.
>>
>>> While pipe topology is decided in CRTC check.
>>
>> ?? What does it mean here?
>>
>>> By default, the plane check occurs before the CRTC check in DRM
>>> framework. Without topology information from the CRTC, plane splitting
>>> cannot be properly executed.
>>
>> What does 'properly' mean here? How is it executed? What happens?
>>
>>> Consequently, the SSPP engine starts
>>> without a valid memory address, which triggers IOMMU warning.
>>
>> IOMMU faults. There are no "warnings".
>>
>>>
>>> Defer above plane operations until dpu_assign_plane_resources()
>>> is called from the CRTC side to ensure the topology information from
>>> the CRTC check is available.
>>
>>
> Thanks for the patience!
>
>
> Currently, splitting plane into SSPP rectangles and allocation occur
> during the plane check phase. When virtual plane is enabled to support
> quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> a plane can be supported by 4 hardware pipes. And pipe number is
number of pipes
> decided in CRTC check per interface number, resolution and hardware
> feature.
Okay, but IOMMU errors were reported with virtual planes being disabled.
So how is it relevant?
>
> By default, the plane check occurs before the CRTC check in DRM
> framework. Without topology information from the CRTC, plane splitting
WHat is plane splitting?
> will be skipped for the first time as pipe number is 0. Consequently,
> the SSPP engine starts without a valid memory address, which triggers
> IOMMU fault.
>
> Defer above plane related operations until dpu_assign_plane_resources()
> is called from the CRTC side to ensure the topology information from
> the CRTC check is available.
>
> Regards,
> Jun
>>
>> --
>> With best wishes
>> Dmitry
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 10:49 ` Dmitry Baryshkov
@ 2026-01-26 12:01 ` Jun Nie
2026-01-26 12:31 ` Dmitry Baryshkov
0 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-26 12:01 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
>
> On 26/01/2026 12:29, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> >>
> >> On 26/01/2026 12:06, Jun Nie wrote:
> >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> >>>>
> >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> >>>>>>
> >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> >>>>>>> is called from the CRTC side to ensure the topology information from
> >>>>>>> the CRTC check is available.
> >>>>>>
> >>>>>> Why is it important? What is broken otherwise?
> >>>>>
> >>>>> I see. Thanks! Will add below lines in next version.
> >>>>>
> >>>>> By default, the plane check occurs before the CRTC check.
> >>>>> Without topology information from the CRTC, plane splitting
> >>>>> cannot be properly executed. Consequently, the SSPP
> >>>>> engine starts without a valid memory address, which triggers
> >>>>> an IOMMU warning.
> >>>>
> >>>> What is plane splitting? Write commit message for somebody who doesn't
> >>>> exactly know what is going on.
> >>>
> >>> Thanks for the suggestion! Any more revise is needed?
> >>
> >> Sadly enough the text below is not a significant improvement.
> >>
> >>>
> >>> Currently, splitting plane into SSPP rectangles the allocation occur
> >>> during the plane check phase, so that a plane can be supported by
> >>> multiple hardware pipe.
> >>
> >> What does this mean? Without virtual planes in place, there are no
> >> multiple hardware pipes.
> >>
> >>> While pipe topology is decided in CRTC check.
> >>
> >> ?? What does it mean here?
> >>
> >>> By default, the plane check occurs before the CRTC check in DRM
> >>> framework. Without topology information from the CRTC, plane splitting
> >>> cannot be properly executed.
> >>
> >> What does 'properly' mean here? How is it executed? What happens?
> >>
> >>> Consequently, the SSPP engine starts
> >>> without a valid memory address, which triggers IOMMU warning.
> >>
> >> IOMMU faults. There are no "warnings".
> >>
> >>>
> >>> Defer above plane operations until dpu_assign_plane_resources()
> >>> is called from the CRTC side to ensure the topology information from
> >>> the CRTC check is available.
> >>
> >>
> > Thanks for the patience!
> >
> >
> > Currently, splitting plane into SSPP rectangles and allocation occur
> > during the plane check phase. When virtual plane is enabled to support
> > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > a plane can be supported by 4 hardware pipes. And pipe number is
>
> number of pipes
>
> > decided in CRTC check per interface number, resolution and hardware
> > feature.
>
> Okay, but IOMMU errors were reported with virtual planes being disabled.
> So how is it relevant?
After revise of splitting plane into pipes, the number of pipes will be decided
by CRTC check for both virtual plane and non-virtual plane case to unify the
plane handling, instead of assumption of 2 pipes at most.
>
> >
> > By default, the plane check occurs before the CRTC check in DRM
> > framework. Without topology information from the CRTC, plane splitting
>
> WHat is plane splitting?
How about: s/plane splitting/splitting plane into pipes ?
>
> > will be skipped for the first time as pipe number is 0. Consequently,
> > the SSPP engine starts without a valid memory address, which triggers
> > IOMMU fault.
> >
> > Defer above plane related operations until dpu_assign_plane_resources()
> > is called from the CRTC side to ensure the topology information from
> > the CRTC check is available.
> >
> > Regards,
> > Jun
> >>
> >> --
> >> With best wishes
> >> Dmitry
>
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 12:01 ` Jun Nie
@ 2026-01-26 12:31 ` Dmitry Baryshkov
2026-01-26 13:29 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-26 12:31 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On Mon, Jan 26, 2026 at 08:01:00PM +0800, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
> >
> > On 26/01/2026 12:29, Jun Nie wrote:
> > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> > >>
> > >> On 26/01/2026 12:06, Jun Nie wrote:
> > >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> > >>>>
> > >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > >>>>>>
> > >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> > >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> > >>>>>>> is called from the CRTC side to ensure the topology information from
> > >>>>>>> the CRTC check is available.
> > >>>>>>
> > >>>>>> Why is it important? What is broken otherwise?
> > >>>>>
> > >>>>> I see. Thanks! Will add below lines in next version.
> > >>>>>
> > >>>>> By default, the plane check occurs before the CRTC check.
> > >>>>> Without topology information from the CRTC, plane splitting
> > >>>>> cannot be properly executed. Consequently, the SSPP
> > >>>>> engine starts without a valid memory address, which triggers
> > >>>>> an IOMMU warning.
> > >>>>
> > >>>> What is plane splitting? Write commit message for somebody who doesn't
> > >>>> exactly know what is going on.
> > >>>
> > >>> Thanks for the suggestion! Any more revise is needed?
> > >>
> > >> Sadly enough the text below is not a significant improvement.
> > >>
> > >>>
> > >>> Currently, splitting plane into SSPP rectangles the allocation occur
> > >>> during the plane check phase, so that a plane can be supported by
> > >>> multiple hardware pipe.
> > >>
> > >> What does this mean? Without virtual planes in place, there are no
> > >> multiple hardware pipes.
> > >>
> > >>> While pipe topology is decided in CRTC check.
> > >>
> > >> ?? What does it mean here?
> > >>
> > >>> By default, the plane check occurs before the CRTC check in DRM
> > >>> framework. Without topology information from the CRTC, plane splitting
> > >>> cannot be properly executed.
> > >>
> > >> What does 'properly' mean here? How is it executed? What happens?
> > >>
> > >>> Consequently, the SSPP engine starts
> > >>> without a valid memory address, which triggers IOMMU warning.
> > >>
> > >> IOMMU faults. There are no "warnings".
> > >>
> > >>>
> > >>> Defer above plane operations until dpu_assign_plane_resources()
> > >>> is called from the CRTC side to ensure the topology information from
> > >>> the CRTC check is available.
> > >>
> > >>
> > > Thanks for the patience!
> > >
> > >
> > > Currently, splitting plane into SSPP rectangles and allocation occur
> > > during the plane check phase. When virtual plane is enabled to support
> > > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > > a plane can be supported by 4 hardware pipes. And pipe number is
> >
> > number of pipes
> >
> > > decided in CRTC check per interface number, resolution and hardware
> > > feature.
> >
> > Okay, but IOMMU errors were reported with virtual planes being disabled.
> > So how is it relevant?
>
> After revise of splitting plane into pipes, the number of pipes will be decided
> by CRTC check for both virtual plane and non-virtual plane case to unify the
> plane handling, instead of assumption of 2 pipes at most.
This needs to be explicitly written.
> >
> > >
> > > By default, the plane check occurs before the CRTC check in DRM
> > > framework. Without topology information from the CRTC, plane splitting
> >
> > WHat is plane splitting?
>
> How about: s/plane splitting/splitting plane into pipes ?
This plane is not being split into anything. It's being mapped onto hw
pipes. But before that, the number of necessary hw pipes is being determined
based on foo, bar an baz,
>
> >
> > > will be skipped for the first time as pipe number is 0. Consequently,
> > > the SSPP engine starts without a valid memory address, which triggers
> > > IOMMU fault.
> > >
> > > Defer above plane related operations until dpu_assign_plane_resources()
> > > is called from the CRTC side to ensure the topology information from
> > > the CRTC check is available.
> > >
> > > Regards,
> > > Jun
> > >>
> > >> --
> > >> With best wishes
> > >> Dmitry
> >
> >
> > --
> > With best wishes
> > Dmitry
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 12:31 ` Dmitry Baryshkov
@ 2026-01-26 13:29 ` Jun Nie
2026-01-26 19:06 ` Dmitry Baryshkov
0 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-01-26 13:29 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 20:31写道:
>
> On Mon, Jan 26, 2026 at 08:01:00PM +0800, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
> > >
> > > On 26/01/2026 12:29, Jun Nie wrote:
> > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> > > >>
> > > >> On 26/01/2026 12:06, Jun Nie wrote:
> > > >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> > > >>>>
> > > >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > > >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > > >>>>>>
> > > >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> > > >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> > > >>>>>>> is called from the CRTC side to ensure the topology information from
> > > >>>>>>> the CRTC check is available.
> > > >>>>>>
> > > >>>>>> Why is it important? What is broken otherwise?
> > > >>>>>
> > > >>>>> I see. Thanks! Will add below lines in next version.
> > > >>>>>
> > > >>>>> By default, the plane check occurs before the CRTC check.
> > > >>>>> Without topology information from the CRTC, plane splitting
> > > >>>>> cannot be properly executed. Consequently, the SSPP
> > > >>>>> engine starts without a valid memory address, which triggers
> > > >>>>> an IOMMU warning.
> > > >>>>
> > > >>>> What is plane splitting? Write commit message for somebody who doesn't
> > > >>>> exactly know what is going on.
> > > >>>
> > > >>> Thanks for the suggestion! Any more revise is needed?
> > > >>
> > > >> Sadly enough the text below is not a significant improvement.
> > > >>
> > > >>>
> > > >>> Currently, splitting plane into SSPP rectangles the allocation occur
> > > >>> during the plane check phase, so that a plane can be supported by
> > > >>> multiple hardware pipe.
> > > >>
> > > >> What does this mean? Without virtual planes in place, there are no
> > > >> multiple hardware pipes.
> > > >>
> > > >>> While pipe topology is decided in CRTC check.
> > > >>
> > > >> ?? What does it mean here?
> > > >>
> > > >>> By default, the plane check occurs before the CRTC check in DRM
> > > >>> framework. Without topology information from the CRTC, plane splitting
> > > >>> cannot be properly executed.
> > > >>
> > > >> What does 'properly' mean here? How is it executed? What happens?
> > > >>
> > > >>> Consequently, the SSPP engine starts
> > > >>> without a valid memory address, which triggers IOMMU warning.
> > > >>
> > > >> IOMMU faults. There are no "warnings".
> > > >>
> > > >>>
> > > >>> Defer above plane operations until dpu_assign_plane_resources()
> > > >>> is called from the CRTC side to ensure the topology information from
> > > >>> the CRTC check is available.
> > > >>
> > > >>
> > > > Thanks for the patience!
> > > >
> > > >
> > > > Currently, splitting plane into SSPP rectangles and allocation occur
> > > > during the plane check phase. When virtual plane is enabled to support
> > > > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > > > a plane can be supported by 4 hardware pipes. And pipe number is
> > >
> > > number of pipes
> > >
> > > > decided in CRTC check per interface number, resolution and hardware
> > > > feature.
> > >
> > > Okay, but IOMMU errors were reported with virtual planes being disabled.
> > > So how is it relevant?
> >
> > After revise of splitting plane into pipes, the number of pipes will be decided
> > by CRTC check for both virtual plane and non-virtual plane case to unify the
> > plane handling, instead of assumption of 2 pipes at most.
>
> This needs to be explicitly written.
>
> > >
> > > >
> > > > By default, the plane check occurs before the CRTC check in DRM
> > > > framework. Without topology information from the CRTC, plane splitting
> > >
> > > WHat is plane splitting?
> >
> > How about: s/plane splitting/splitting plane into pipes ?
>
> This plane is not being split into anything. It's being mapped onto hw
> pipes. But before that, the number of necessary hw pipes is being determined
> based on foo, bar an baz,
Thanks for the correction!
Currently, plane is mapped onto at most 2 hardware pipes and 1 SSPP
allocation occur during the plane check phase. When virtual plane is
enabled to support quad-pipe topology later, 2 SSPPs with 4 rect will
be needed, so that a plane can be supported by 4 hardware pipes.
After revise of quad-pipe, the number of pipes is decided in CRTC
check per number of interfaces, resolution, clock rate constrain,
hardware feature and virtual plane enablement. The decidsion of
number of pipes will happen in CRTC check for both virtual plane and
non-virtual plane case to unify the plane handling. Before that, the
the number of necessary hw pipes is being determined based on
resolution and clock rate constrain.
By default, the plane check occurs before the CRTC check in DRM
framework. Without topology information from the CRTC, plane mapping
will be skipped for the first time as number of pipe is 0.
Consequently, the SSPP engine starts without a valid memory address,
which triggers IOMMU fault.
Defer above plane related operations until dpu_assign_plane_resources()
is called from the CRTC side to ensure the topology information from
the CRTC check is available.
>
> >
> > >
> > > > will be skipped for the first time as pipe number is 0. Consequently,
> > > > the SSPP engine starts without a valid memory address, which triggers
> > > > IOMMU fault.
> > > >
> > > > Defer above plane related operations until dpu_assign_plane_resources()
> > > > is called from the CRTC side to ensure the topology information from
> > > > the CRTC check is available.
> > > >
> > > > Regards,
> > > > Jun
> > > >>
> > > >> --
> > > >> With best wishes
> > > >> Dmitry
> > >
> > >
> > > --
> > > With best wishes
> > > Dmitry
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 13:29 ` Jun Nie
@ 2026-01-26 19:06 ` Dmitry Baryshkov
2026-02-02 7:15 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-01-26 19:06 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On Mon, Jan 26, 2026 at 09:29:44PM +0800, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 20:31写道:
> >
> > On Mon, Jan 26, 2026 at 08:01:00PM +0800, Jun Nie wrote:
> > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
> > > >
> > > > On 26/01/2026 12:29, Jun Nie wrote:
> > > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> > > > >>
> > > > >> On 26/01/2026 12:06, Jun Nie wrote:
> > > > >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> > > > >>>>
> > > > >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > > > >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > > > >>>>>>
> > > > >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > > >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> > > > >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> > > > >>>>>>> is called from the CRTC side to ensure the topology information from
> > > > >>>>>>> the CRTC check is available.
> > > > >>>>>>
> > > > >>>>>> Why is it important? What is broken otherwise?
> > > > >>>>>
> > > > >>>>> I see. Thanks! Will add below lines in next version.
> > > > >>>>>
> > > > >>>>> By default, the plane check occurs before the CRTC check.
> > > > >>>>> Without topology information from the CRTC, plane splitting
> > > > >>>>> cannot be properly executed. Consequently, the SSPP
> > > > >>>>> engine starts without a valid memory address, which triggers
> > > > >>>>> an IOMMU warning.
> > > > >>>>
> > > > >>>> What is plane splitting? Write commit message for somebody who doesn't
> > > > >>>> exactly know what is going on.
> > > > >>>
> > > > >>> Thanks for the suggestion! Any more revise is needed?
> > > > >>
> > > > >> Sadly enough the text below is not a significant improvement.
> > > > >>
> > > > >>>
> > > > >>> Currently, splitting plane into SSPP rectangles the allocation occur
> > > > >>> during the plane check phase, so that a plane can be supported by
> > > > >>> multiple hardware pipe.
> > > > >>
> > > > >> What does this mean? Without virtual planes in place, there are no
> > > > >> multiple hardware pipes.
> > > > >>
> > > > >>> While pipe topology is decided in CRTC check.
> > > > >>
> > > > >> ?? What does it mean here?
> > > > >>
> > > > >>> By default, the plane check occurs before the CRTC check in DRM
> > > > >>> framework. Without topology information from the CRTC, plane splitting
> > > > >>> cannot be properly executed.
> > > > >>
> > > > >> What does 'properly' mean here? How is it executed? What happens?
> > > > >>
> > > > >>> Consequently, the SSPP engine starts
> > > > >>> without a valid memory address, which triggers IOMMU warning.
> > > > >>
> > > > >> IOMMU faults. There are no "warnings".
> > > > >>
> > > > >>>
> > > > >>> Defer above plane operations until dpu_assign_plane_resources()
> > > > >>> is called from the CRTC side to ensure the topology information from
> > > > >>> the CRTC check is available.
> > > > >>
> > > > >>
> > > > > Thanks for the patience!
> > > > >
> > > > >
> > > > > Currently, splitting plane into SSPP rectangles and allocation occur
> > > > > during the plane check phase. When virtual plane is enabled to support
> > > > > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > > > > a plane can be supported by 4 hardware pipes. And pipe number is
> > > >
> > > > number of pipes
> > > >
> > > > > decided in CRTC check per interface number, resolution and hardware
> > > > > feature.
> > > >
> > > > Okay, but IOMMU errors were reported with virtual planes being disabled.
> > > > So how is it relevant?
> > >
> > > After revise of splitting plane into pipes, the number of pipes will be decided
> > > by CRTC check for both virtual plane and non-virtual plane case to unify the
> > > plane handling, instead of assumption of 2 pipes at most.
> >
> > This needs to be explicitly written.
> >
> > > >
> > > > >
> > > > > By default, the plane check occurs before the CRTC check in DRM
> > > > > framework. Without topology information from the CRTC, plane splitting
> > > >
> > > > WHat is plane splitting?
> > >
> > > How about: s/plane splitting/splitting plane into pipes ?
> >
> > This plane is not being split into anything. It's being mapped onto hw
> > pipes. But before that, the number of necessary hw pipes is being determined
> > based on foo, bar an baz,
>
> Thanks for the correction!
>
> Currently, plane is mapped onto at most 2 hardware pipes and 1 SSPP
> allocation occur during the plane check phase. When virtual plane is
> enabled to support quad-pipe topology later, 2 SSPPs with 4 rect will
> be needed, so that a plane can be supported by 4 hardware pipes.
>
> After revise of quad-pipe, the number of pipes is decided in CRTC
> check per number of interfaces, resolution, clock rate constrain,
Where?
> hardware feature and virtual plane enablement. The decidsion of
decision
> number of pipes will happen in CRTC check for both virtual plane and
> non-virtual plane case to unify the plane handling. Before that, the
will? Do you mean, after this patch? If so, please use imperative
language. See Documentation/process/submitting-patches.rst
> the number of necessary hw pipes is being determined based on
> resolution and clock rate constrain.
>
> By default, the plane check occurs before the CRTC check in DRM
> framework. Without topology information from the CRTC, plane mapping
> will be skipped for the first time as number of pipe is 0.
> Consequently, the SSPP engine starts without a valid memory address,
> which triggers IOMMU fault.
>
> Defer above plane related operations until dpu_assign_plane_resources()
> is called from the CRTC side to ensure the topology information from
> the CRTC check is available.
>
> >
> > >
> > > >
> > > > > will be skipped for the first time as pipe number is 0. Consequently,
> > > > > the SSPP engine starts without a valid memory address, which triggers
> > > > > IOMMU fault.
> > > > >
> > > > > Defer above plane related operations until dpu_assign_plane_resources()
> > > > > is called from the CRTC side to ensure the topology information from
> > > > > the CRTC check is available.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-01-26 19:06 ` Dmitry Baryshkov
@ 2026-02-02 7:15 ` Jun Nie
2026-02-04 2:43 ` Dmitry Baryshkov
0 siblings, 1 reply; 21+ messages in thread
From: Jun Nie @ 2026-02-02 7:15 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月27日周二 03:06写道:
>
> On Mon, Jan 26, 2026 at 09:29:44PM +0800, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 20:31写道:
> > >
> > > On Mon, Jan 26, 2026 at 08:01:00PM +0800, Jun Nie wrote:
> > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
> > > > >
> > > > > On 26/01/2026 12:29, Jun Nie wrote:
> > > > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> > > > > >>
> > > > > >> On 26/01/2026 12:06, Jun Nie wrote:
> > > > > >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> > > > > >>>>
> > > > > >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > > > > >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > > > > >>>>>>
> > > > > >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > > > >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> > > > > >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> > > > > >>>>>>> is called from the CRTC side to ensure the topology information from
> > > > > >>>>>>> the CRTC check is available.
> > > > > >>>>>>
> > > > > >>>>>> Why is it important? What is broken otherwise?
> > > > > >>>>>
> > > > > >>>>> I see. Thanks! Will add below lines in next version.
> > > > > >>>>>
> > > > > >>>>> By default, the plane check occurs before the CRTC check.
> > > > > >>>>> Without topology information from the CRTC, plane splitting
> > > > > >>>>> cannot be properly executed. Consequently, the SSPP
> > > > > >>>>> engine starts without a valid memory address, which triggers
> > > > > >>>>> an IOMMU warning.
> > > > > >>>>
> > > > > >>>> What is plane splitting? Write commit message for somebody who doesn't
> > > > > >>>> exactly know what is going on.
> > > > > >>>
> > > > > >>> Thanks for the suggestion! Any more revise is needed?
> > > > > >>
> > > > > >> Sadly enough the text below is not a significant improvement.
> > > > > >>
> > > > > >>>
> > > > > >>> Currently, splitting plane into SSPP rectangles the allocation occur
> > > > > >>> during the plane check phase, so that a plane can be supported by
> > > > > >>> multiple hardware pipe.
> > > > > >>
> > > > > >> What does this mean? Without virtual planes in place, there are no
> > > > > >> multiple hardware pipes.
> > > > > >>
> > > > > >>> While pipe topology is decided in CRTC check.
> > > > > >>
> > > > > >> ?? What does it mean here?
> > > > > >>
> > > > > >>> By default, the plane check occurs before the CRTC check in DRM
> > > > > >>> framework. Without topology information from the CRTC, plane splitting
> > > > > >>> cannot be properly executed.
> > > > > >>
> > > > > >> What does 'properly' mean here? How is it executed? What happens?
> > > > > >>
> > > > > >>> Consequently, the SSPP engine starts
> > > > > >>> without a valid memory address, which triggers IOMMU warning.
> > > > > >>
> > > > > >> IOMMU faults. There are no "warnings".
> > > > > >>
> > > > > >>>
> > > > > >>> Defer above plane operations until dpu_assign_plane_resources()
> > > > > >>> is called from the CRTC side to ensure the topology information from
> > > > > >>> the CRTC check is available.
> > > > > >>
> > > > > >>
> > > > > > Thanks for the patience!
> > > > > >
> > > > > >
> > > > > > Currently, splitting plane into SSPP rectangles and allocation occur
> > > > > > during the plane check phase. When virtual plane is enabled to support
> > > > > > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > > > > > a plane can be supported by 4 hardware pipes. And pipe number is
> > > > >
> > > > > number of pipes
> > > > >
> > > > > > decided in CRTC check per interface number, resolution and hardware
> > > > > > feature.
> > > > >
> > > > > Okay, but IOMMU errors were reported with virtual planes being disabled.
> > > > > So how is it relevant?
> > > >
> > > > After revise of splitting plane into pipes, the number of pipes will be decided
> > > > by CRTC check for both virtual plane and non-virtual plane case to unify the
> > > > plane handling, instead of assumption of 2 pipes at most.
> > >
> > > This needs to be explicitly written.
> > >
> > > > >
> > > > > >
> > > > > > By default, the plane check occurs before the CRTC check in DRM
> > > > > > framework. Without topology information from the CRTC, plane splitting
> > > > >
> > > > > WHat is plane splitting?
> > > >
> > > > How about: s/plane splitting/splitting plane into pipes ?
> > >
> > > This plane is not being split into anything. It's being mapped onto hw
> > > pipes. But before that, the number of necessary hw pipes is being determined
> > > based on foo, bar an baz,
> >
> > Thanks for the correction!
> >
> > Currently, plane is mapped onto at most 2 hardware pipes and 1 SSPP
> > allocation occur during the plane check phase. When virtual plane is
> > enabled to support quad-pipe topology later, 2 SSPPs with 4 rect will
> > be needed, so that a plane can be supported by 4 hardware pipes.
> >
> > After revise of quad-pipe, the number of pipes is decided in CRTC
> > check per number of interfaces, resolution, clock rate constrain,
>
> Where?
The pipe is decided in dpu_crtc_get_topology(). Change to quad-pipe
is made in later patch. So I drop this in this patch message below.
>
> > hardware feature and virtual plane enablement. The decidsion of
>
> decision
>
> > number of pipes will happen in CRTC check for both virtual plane and
> > non-virtual plane case to unify the plane handling. Before that, the
>
> will? Do you mean, after this patch? If so, please use imperative
> language. See Documentation/process/submitting-patches.rst
Yes, it is in later patch. So drop it in this patch message.
It is possible to keep plane check unchanged, and rely on re-allocation
in later stage to support quad-pipe, if quad-pipe use case is detected.
But to unify the allocation logic for both non-virtual and virtual plane
use cases, and to centralize resource management, we'd better defer
the allocation.
>
> > the number of necessary hw pipes is being determined based on
> > resolution and clock rate constrain.
> >
> > By default, the plane check occurs before the CRTC check in DRM
> > framework. Without topology information from the CRTC, plane mapping
> > will be skipped for the first time as number of pipe is 0.
> > Consequently, the SSPP engine starts without a valid memory address,
> > which triggers IOMMU fault.
> >
> > Defer above plane related operations until dpu_assign_plane_resources()
> > is called from the CRTC side to ensure the topology information from
> > the CRTC check is available.
> >
> > >
> > > >
> > > > >
> > > > > > will be skipped for the first time as pipe number is 0. Consequently,
> > > > > > the SSPP engine starts without a valid memory address, which triggers
> > > > > > IOMMU fault.
> > > > > >
> > > > > > Defer above plane related operations until dpu_assign_plane_resources()
> > > > > > is called from the CRTC side to ensure the topology information from
> > > > > > the CRTC check is available.
>
How about this commit message? It is more coherent with the change
in this patch.
Currently, a plane maps to at most two hardware pipes, and SSPP
allocation occurs during the plane check phase. However, when virtual
planes are enabled, SSPP re-allocation can occur within
dpu_assign_plane_resources() during the CRTC check.
To support future quad-pipe topologies, which require allocating two
SSPPs with four rectangles by default, it is more efficient to perform
the primary allocation in a single pass rather than relying on later
re-allocations. So defer the allocation to CRTC check phase by default.
Allocation logic for both non-virtual and virtual plane use cases is
unified in this way.
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-02-02 7:15 ` Jun Nie
@ 2026-02-04 2:43 ` Dmitry Baryshkov
2026-02-06 10:48 ` Jun Nie
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-02-04 2:43 UTC (permalink / raw)
To: Jun Nie
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
On Mon, Feb 02, 2026 at 03:15:14PM +0800, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月27日周二 03:06写道:
> >
> > On Mon, Jan 26, 2026 at 09:29:44PM +0800, Jun Nie wrote:
> > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 20:31写道:
> > > >
> > > > On Mon, Jan 26, 2026 at 08:01:00PM +0800, Jun Nie wrote:
> > > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
> > > > > >
> > > > > > On 26/01/2026 12:29, Jun Nie wrote:
> > > > > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> > > > > > >>
> > > > > > >> On 26/01/2026 12:06, Jun Nie wrote:
> > > > > > >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> > > > > > >>>>
> > > > > > >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > > > > > >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > > > > > >>>>>>
> > > > > > >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > > > > >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> > > > > > >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> > > > > > >>>>>>> is called from the CRTC side to ensure the topology information from
> > > > > > >>>>>>> the CRTC check is available.
> > > > > > >>>>>>
> > > > > > >>>>>> Why is it important? What is broken otherwise?
> > > > > > >>>>>
> > > > > > >>>>> I see. Thanks! Will add below lines in next version.
> > > > > > >>>>>
> > > > > > >>>>> By default, the plane check occurs before the CRTC check.
> > > > > > >>>>> Without topology information from the CRTC, plane splitting
> > > > > > >>>>> cannot be properly executed. Consequently, the SSPP
> > > > > > >>>>> engine starts without a valid memory address, which triggers
> > > > > > >>>>> an IOMMU warning.
> > > > > > >>>>
> > > > > > >>>> What is plane splitting? Write commit message for somebody who doesn't
> > > > > > >>>> exactly know what is going on.
> > > > > > >>>
> > > > > > >>> Thanks for the suggestion! Any more revise is needed?
> > > > > > >>
> > > > > > >> Sadly enough the text below is not a significant improvement.
> > > > > > >>
> > > > > > >>>
> > > > > > >>> Currently, splitting plane into SSPP rectangles the allocation occur
> > > > > > >>> during the plane check phase, so that a plane can be supported by
> > > > > > >>> multiple hardware pipe.
> > > > > > >>
> > > > > > >> What does this mean? Without virtual planes in place, there are no
> > > > > > >> multiple hardware pipes.
> > > > > > >>
> > > > > > >>> While pipe topology is decided in CRTC check.
> > > > > > >>
> > > > > > >> ?? What does it mean here?
> > > > > > >>
> > > > > > >>> By default, the plane check occurs before the CRTC check in DRM
> > > > > > >>> framework. Without topology information from the CRTC, plane splitting
> > > > > > >>> cannot be properly executed.
> > > > > > >>
> > > > > > >> What does 'properly' mean here? How is it executed? What happens?
> > > > > > >>
> > > > > > >>> Consequently, the SSPP engine starts
> > > > > > >>> without a valid memory address, which triggers IOMMU warning.
> > > > > > >>
> > > > > > >> IOMMU faults. There are no "warnings".
> > > > > > >>
> > > > > > >>>
> > > > > > >>> Defer above plane operations until dpu_assign_plane_resources()
> > > > > > >>> is called from the CRTC side to ensure the topology information from
> > > > > > >>> the CRTC check is available.
> > > > > > >>
> > > > > > >>
> > > > > > > Thanks for the patience!
> > > > > > >
> > > > > > >
> > > > > > > Currently, splitting plane into SSPP rectangles and allocation occur
> > > > > > > during the plane check phase. When virtual plane is enabled to support
> > > > > > > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > > > > > > a plane can be supported by 4 hardware pipes. And pipe number is
> > > > > >
> > > > > > number of pipes
> > > > > >
> > > > > > > decided in CRTC check per interface number, resolution and hardware
> > > > > > > feature.
> > > > > >
> > > > > > Okay, but IOMMU errors were reported with virtual planes being disabled.
> > > > > > So how is it relevant?
> > > > >
> > > > > After revise of splitting plane into pipes, the number of pipes will be decided
> > > > > by CRTC check for both virtual plane and non-virtual plane case to unify the
> > > > > plane handling, instead of assumption of 2 pipes at most.
> > > >
> > > > This needs to be explicitly written.
> > > >
> > > > > >
> > > > > > >
> > > > > > > By default, the plane check occurs before the CRTC check in DRM
> > > > > > > framework. Without topology information from the CRTC, plane splitting
> > > > > >
> > > > > > WHat is plane splitting?
> > > > >
> > > > > How about: s/plane splitting/splitting plane into pipes ?
> > > >
> > > > This plane is not being split into anything. It's being mapped onto hw
> > > > pipes. But before that, the number of necessary hw pipes is being determined
> > > > based on foo, bar an baz,
> > >
> > > Thanks for the correction!
> > >
> > > Currently, plane is mapped onto at most 2 hardware pipes and 1 SSPP
> > > allocation occur during the plane check phase. When virtual plane is
> > > enabled to support quad-pipe topology later, 2 SSPPs with 4 rect will
> > > be needed, so that a plane can be supported by 4 hardware pipes.
> > >
> > > After revise of quad-pipe, the number of pipes is decided in CRTC
> > > check per number of interfaces, resolution, clock rate constrain,
> >
> > Where?
>
> The pipe is decided in dpu_crtc_get_topology(). Change to quad-pipe
> is made in later patch. So I drop this in this patch message below.
The pipe isn't decides in that function.
> >
> > > hardware feature and virtual plane enablement. The decidsion of
> >
> > decision
> >
> > > number of pipes will happen in CRTC check for both virtual plane and
> > > non-virtual plane case to unify the plane handling. Before that, the
> >
> > will? Do you mean, after this patch? If so, please use imperative
> > language. See Documentation/process/submitting-patches.rst
>
> Yes, it is in later patch. So drop it in this patch message.
>
> It is possible to keep plane check unchanged, and rely on re-allocation
> in later stage to support quad-pipe, if quad-pipe use case is detected.
> But to unify the allocation logic for both non-virtual and virtual plane
> use cases, and to centralize resource management, we'd better defer
> the allocation.
Which allocation? The non-virtual-planes case is more or less static.
>
>
> >
> > > the number of necessary hw pipes is being determined based on
> > > resolution and clock rate constrain.
> > >
> > > By default, the plane check occurs before the CRTC check in DRM
> > > framework. Without topology information from the CRTC, plane mapping
> > > will be skipped for the first time as number of pipe is 0.
> > > Consequently, the SSPP engine starts without a valid memory address,
> > > which triggers IOMMU fault.
> > >
> > > Defer above plane related operations until dpu_assign_plane_resources()
> > > is called from the CRTC side to ensure the topology information from
> > > the CRTC check is available.
> > >
> > > >
> > > > >
> > > > > >
> > > > > > > will be skipped for the first time as pipe number is 0. Consequently,
> > > > > > > the SSPP engine starts without a valid memory address, which triggers
> > > > > > > IOMMU fault.
> > > > > > >
> > > > > > > Defer above plane related operations until dpu_assign_plane_resources()
> > > > > > > is called from the CRTC side to ensure the topology information from
> > > > > > > the CRTC check is available.
> >
> How about this commit message? It is more coherent with the change
> in this patch.
>
>
> Currently, a plane maps to at most two hardware pipes, and SSPP
> allocation occurs during the plane check phase. However, when virtual
> planes are enabled, SSPP re-allocation can occur within
> dpu_assign_plane_resources() during the CRTC check.
There is no _allocation_ for non-virtual-plane case. The SSPP are
statically assigned to the planes.
>
> To support future quad-pipe topologies, which require allocating two
> SSPPs with four rectangles by default, it is more efficient to perform
> the primary allocation in a single pass rather than relying on later
> re-allocations. So defer the allocation to CRTC check phase by default.
> Allocation logic for both non-virtual and virtual plane use cases is
> unified in this way.
>
> > --
> > With best wishes
> > Dmitry
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check
2026-02-04 2:43 ` Dmitry Baryshkov
@ 2026-02-06 10:48 ` Jun Nie
0 siblings, 0 replies; 21+ messages in thread
From: Jun Nie @ 2026-02-06 10:48 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong,
linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年2月4日周三 10:44写道:
>
> On Mon, Feb 02, 2026 at 03:15:14PM +0800, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月27日周二 03:06写道:
> > >
> > > On Mon, Jan 26, 2026 at 09:29:44PM +0800, Jun Nie wrote:
> > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 20:31写道:
> > > > >
> > > > > On Mon, Jan 26, 2026 at 08:01:00PM +0800, Jun Nie wrote:
> > > > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:49写道:
> > > > > > >
> > > > > > > On 26/01/2026 12:29, Jun Nie wrote:
> > > > > > > > Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月26日周一 18:13写道:
> > > > > > > >>
> > > > > > > >> On 26/01/2026 12:06, Jun Nie wrote:
> > > > > > > >>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月22日周四 18:22写道:
> > > > > > > >>>>
> > > > > > > >>>> On Thu, Jan 22, 2026 at 02:03:25PM +0800, Jun Nie wrote:
> > > > > > > >>>>> Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 于2026年1月21日周三 17:30写道:
> > > > > > > >>>>>>
> > > > > > > >>>>>> On Wed, Jan 21, 2026 at 04:01:51PM +0800, Jun Nie wrote:
> > > > > > > >>>>>>> Currently, plane splitting and SSPP allocation occur during the plane
> > > > > > > >>>>>>> check phase. Defer these operations until dpu_assign_plane_resources()
> > > > > > > >>>>>>> is called from the CRTC side to ensure the topology information from
> > > > > > > >>>>>>> the CRTC check is available.
> > > > > > > >>>>>>
> > > > > > > >>>>>> Why is it important? What is broken otherwise?
> > > > > > > >>>>>
> > > > > > > >>>>> I see. Thanks! Will add below lines in next version.
> > > > > > > >>>>>
> > > > > > > >>>>> By default, the plane check occurs before the CRTC check.
> > > > > > > >>>>> Without topology information from the CRTC, plane splitting
> > > > > > > >>>>> cannot be properly executed. Consequently, the SSPP
> > > > > > > >>>>> engine starts without a valid memory address, which triggers
> > > > > > > >>>>> an IOMMU warning.
> > > > > > > >>>>
> > > > > > > >>>> What is plane splitting? Write commit message for somebody who doesn't
> > > > > > > >>>> exactly know what is going on.
> > > > > > > >>>
> > > > > > > >>> Thanks for the suggestion! Any more revise is needed?
> > > > > > > >>
> > > > > > > >> Sadly enough the text below is not a significant improvement.
> > > > > > > >>
> > > > > > > >>>
> > > > > > > >>> Currently, splitting plane into SSPP rectangles the allocation occur
> > > > > > > >>> during the plane check phase, so that a plane can be supported by
> > > > > > > >>> multiple hardware pipe.
> > > > > > > >>
> > > > > > > >> What does this mean? Without virtual planes in place, there are no
> > > > > > > >> multiple hardware pipes.
> > > > > > > >>
> > > > > > > >>> While pipe topology is decided in CRTC check.
> > > > > > > >>
> > > > > > > >> ?? What does it mean here?
> > > > > > > >>
> > > > > > > >>> By default, the plane check occurs before the CRTC check in DRM
> > > > > > > >>> framework. Without topology information from the CRTC, plane splitting
> > > > > > > >>> cannot be properly executed.
> > > > > > > >>
> > > > > > > >> What does 'properly' mean here? How is it executed? What happens?
> > > > > > > >>
> > > > > > > >>> Consequently, the SSPP engine starts
> > > > > > > >>> without a valid memory address, which triggers IOMMU warning.
> > > > > > > >>
> > > > > > > >> IOMMU faults. There are no "warnings".
> > > > > > > >>
> > > > > > > >>>
> > > > > > > >>> Defer above plane operations until dpu_assign_plane_resources()
> > > > > > > >>> is called from the CRTC side to ensure the topology information from
> > > > > > > >>> the CRTC check is available.
> > > > > > > >>
> > > > > > > >>
> > > > > > > > Thanks for the patience!
> > > > > > > >
> > > > > > > >
> > > > > > > > Currently, splitting plane into SSPP rectangles and allocation occur
> > > > > > > > during the plane check phase. When virtual plane is enabled to support
> > > > > > > > quad-pipe topology later, 2 SSPPs with 4 rect will be needed, so that
> > > > > > > > a plane can be supported by 4 hardware pipes. And pipe number is
> > > > > > >
> > > > > > > number of pipes
> > > > > > >
> > > > > > > > decided in CRTC check per interface number, resolution and hardware
> > > > > > > > feature.
> > > > > > >
> > > > > > > Okay, but IOMMU errors were reported with virtual planes being disabled.
> > > > > > > So how is it relevant?
> > > > > >
> > > > > > After revise of splitting plane into pipes, the number of pipes will be decided
> > > > > > by CRTC check for both virtual plane and non-virtual plane case to unify the
> > > > > > plane handling, instead of assumption of 2 pipes at most.
> > > > >
> > > > > This needs to be explicitly written.
> > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > By default, the plane check occurs before the CRTC check in DRM
> > > > > > > > framework. Without topology information from the CRTC, plane splitting
> > > > > > >
> > > > > > > WHat is plane splitting?
> > > > > >
> > > > > > How about: s/plane splitting/splitting plane into pipes ?
> > > > >
> > > > > This plane is not being split into anything. It's being mapped onto hw
> > > > > pipes. But before that, the number of necessary hw pipes is being determined
> > > > > based on foo, bar an baz,
> > > >
> > > > Thanks for the correction!
> > > >
> > > > Currently, plane is mapped onto at most 2 hardware pipes and 1 SSPP
> > > > allocation occur during the plane check phase. When virtual plane is
> > > > enabled to support quad-pipe topology later, 2 SSPPs with 4 rect will
> > > > be needed, so that a plane can be supported by 4 hardware pipes.
> > > >
> > > > After revise of quad-pipe, the number of pipes is decided in CRTC
> > > > check per number of interfaces, resolution, clock rate constrain,
> > >
> > > Where?
> >
> > The pipe is decided in dpu_crtc_get_topology(). Change to quad-pipe
> > is made in later patch. So I drop this in this patch message below.
>
> The pipe isn't decides in that function.
Sorry for the inaccurate word. I mean the number of pipes is decided in
dpu_crtc_get_topology(), is it correct? Of course, the number of pipe may
be increased from 1 to 2 with filling r_pipe_cfg in
dpu_plane_atomic_check_nosspp()
due to width or clock rate constrain in non-virtual-plane case. So the code
logic allows 2 mixers co-work with 1 SSPP rect, mixer number is decided in
topology and pipe is decided in plane side, though it is not very reasonable.
Does DPU support such topology? If not, the number of pipe shall be aliged
with the number of mixers info from topology side. Please help teach me
on the relation number of mixers and SSPP rectangles. Thanks!
>
> > >
> > > > hardware feature and virtual plane enablement. The decidsion of
> > >
> > > decision
> > >
> > > > number of pipes will happen in CRTC check for both virtual plane and
> > > > non-virtual plane case to unify the plane handling. Before that, the
> > >
> > > will? Do you mean, after this patch? If so, please use imperative
> > > language. See Documentation/process/submitting-patches.rst
> >
> > Yes, it is in later patch. So drop it in this patch message.
> >
> > It is possible to keep plane check unchanged, and rely on re-allocation
> > in later stage to support quad-pipe, if quad-pipe use case is detected.
> > But to unify the allocation logic for both non-virtual and virtual plane
> > use cases, and to centralize resource management, we'd better defer
> > the allocation.
>
> Which allocation? The non-virtual-planes case is more or less static.
You are right. The SSPP is assigned to plane in non-virtual-planes case
statically. The plane may be re-mapped to other SSPP only in virtual-plane
case. Just got your point here. I will try to keep the SSPP assignment
unchanged for non-virtual-plane case, avoiding mixing assignment with
allocation.
>
> >
> >
> > >
> > > > the number of necessary hw pipes is being determined based on
> > > > resolution and clock rate constrain.
> > > >
> > > > By default, the plane check occurs before the CRTC check in DRM
> > > > framework. Without topology information from the CRTC, plane mapping
> > > > will be skipped for the first time as number of pipe is 0.
> > > > Consequently, the SSPP engine starts without a valid memory address,
> > > > which triggers IOMMU fault.
> > > >
> > > > Defer above plane related operations until dpu_assign_plane_resources()
> > > > is called from the CRTC side to ensure the topology information from
> > > > the CRTC check is available.
> > > >
> > > > >
> > > > > >
> > > > > > >
> > > > > > > > will be skipped for the first time as pipe number is 0. Consequently,
> > > > > > > > the SSPP engine starts without a valid memory address, which triggers
> > > > > > > > IOMMU fault.
> > > > > > > >
> > > > > > > > Defer above plane related operations until dpu_assign_plane_resources()
> > > > > > > > is called from the CRTC side to ensure the topology information from
> > > > > > > > the CRTC check is available.
> > >
> > How about this commit message? It is more coherent with the change
> > in this patch.
> >
> >
> > Currently, a plane maps to at most two hardware pipes, and SSPP
> > allocation occurs during the plane check phase. However, when virtual
> > planes are enabled, SSPP re-allocation can occur within
> > dpu_assign_plane_resources() during the CRTC check.
>
> There is no _allocation_ for non-virtual-plane case. The SSPP are
> statically assigned to the planes.
>
> >
> > To support future quad-pipe topologies, which require allocating two
> > SSPPs with four rectangles by default, it is more efficient to perform
> > the primary allocation in a single pass rather than relying on later
> > re-allocations. So defer the allocation to CRTC check phase by default.
> > Allocation logic for both non-virtual and virtual plane use cases is
> > unified in this way.
> >
> > > --
> > > With best wishes
> > > Dmitry
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v17 3/4] drm/msm/dpu: support plane splitting in quad-pipe case
2026-01-21 8:01 [PATCH v17 0/4] drm/msm/dpu: Support quad pipe with dual-interface Jun Nie
2026-01-21 8:01 ` [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function Jun Nie
2026-01-21 8:01 ` [PATCH v17 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check Jun Nie
@ 2026-01-21 8:01 ` Jun Nie
2026-01-21 8:01 ` [PATCH v17 4/4] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case Jun Nie
3 siblings, 0 replies; 21+ messages in thread
From: Jun Nie @ 2026-01-21 8:01 UTC (permalink / raw)
To: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie,
Dmitry Baryshkov
The content of every half of screen is sent out via one interface in
dual-DSI case. The content for every interface is blended by a LM
pair in quad-pipe case, thus a LM pair should not blend any content
that cross the half of screen in this case. Clip plane into pipes per
left and right half screen ROI if topology is quad pipe case.
The clipped rectangle on every half of screen is futher handled by two
pipes if its width exceeds a limit for a single pipe.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/675416/
Link: https://lore.kernel.org/r/20250918-v6-16-rc2-quad-pipe-upstream-4-v16-9-ff6232e3472f@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 11 +++
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 +
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 139 +++++++++++++++++++++---------
3 files changed, 110 insertions(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index debdbbe6160dd..87a934e3801f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1606,6 +1606,17 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
return 0;
}
+/**
+ * dpu_crtc_get_num_lm - Get mixer number in this CRTC pipeline
+ * @state: Pointer to drm crtc state object
+ */
+unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state)
+{
+ struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
+
+ return cstate->num_mixers;
+}
+
#ifdef CONFIG_DEBUG_FS
static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
{
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 94392b9b92454..6eaba5696e8e6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -267,4 +267,6 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type(
void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
+unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state);
+
#endif /* _DPU_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3c629f4df461d..2637abefe2602 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -881,50 +881,107 @@ static int dpu_plane_split(struct drm_plane *plane,
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
struct dpu_sw_pipe_cfg *pipe_cfg;
struct dpu_sw_pipe_cfg *r_pipe_cfg;
+ const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
uint32_t max_linewidth;
+ u32 num_lm;
+ int stage_id, num_stages;
if (!new_plane_state->visible)
return 0;
- /* move the assignment here, to ease handling to another pairs later */
- pipe_cfg = &pstate->pipe_cfg[0];
- r_pipe_cfg = &pstate->pipe_cfg[1];
- /* state->src is 16.16, src_rect is not */
- drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
-
- pipe_cfg->dst_rect = new_plane_state->dst;
+ num_lm = dpu_crtc_get_num_lm(crtc_state);
max_linewidth = pdpu->catalog->caps->max_linewidth;
- drm_rect_rotate(&pipe_cfg->src_rect,
- new_plane_state->fb->width, new_plane_state->fb->height,
- new_plane_state->rotation);
+ /*
+ * We have 1 mixer pair cfg for 1:1:1 and 2:2:1 topology, 2 mixer pair
+ * configs for left and right half screen in case of 4:4:2 topology.
+ * But we may have 2 rect to split wide plane that exceeds limit with 1
+ * config for 2:2:1. So need to handle both wide plane splitting, and
+ * two halves of screen splitting for quad-pipe case. Check dest
+ * rectangle left/right clipping first, then check wide rectangle
+ * splitting in every half next.
+ */
+ num_stages = (num_lm + 1) / 2;
+ /* iterate mixer configs for this plane, to separate left/right with the id */
+ for (stage_id = 0; stage_id < num_stages; stage_id++) {
+ struct drm_rect mixer_rect = {
+ .x1 = stage_id * mode->hdisplay / num_stages,
+ .y1 = 0,
+ .x2 = (stage_id + 1) * mode->hdisplay / num_stages,
+ .y2 = mode->vdisplay
+ };
+ int cfg_idx = stage_id * PIPES_PER_STAGE;
+
+ pipe_cfg = &pstate->pipe_cfg[cfg_idx];
+ r_pipe_cfg = &pstate->pipe_cfg[cfg_idx + 1];
+
+ drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
+
+ drm_rect_rotate(&pipe_cfg->src_rect,
+ new_plane_state->fb->width, new_plane_state->fb->height,
+ new_plane_state->rotation);
+
+ pipe_cfg->dst_rect = new_plane_state->dst;
+
+ DPU_DEBUG_PLANE(pdpu, "checking src " DRM_RECT_FMT
+ " vs clip window " DRM_RECT_FMT "\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect),
+ DRM_RECT_ARG(&mixer_rect));
+
+ /*
+ * If this plane does not fall into mixer rect, check next
+ * mixer rect.
+ */
+ if (!drm_rect_clip_scaled(&pipe_cfg->src_rect,
+ &pipe_cfg->dst_rect,
+ &mixer_rect)) {
+ memset(pipe_cfg, 0, 2 * sizeof(struct dpu_sw_pipe_cfg));
- if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
- _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
- if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
- DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
- DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
- return -E2BIG;
+ continue;
}
- *r_pipe_cfg = *pipe_cfg;
- pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
- pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
- r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
- r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
- } else {
- memset(r_pipe_cfg, 0, sizeof(*r_pipe_cfg));
- }
+ pipe_cfg->dst_rect.x1 -= mixer_rect.x1;
+ pipe_cfg->dst_rect.x2 -= mixer_rect.x1;
+
+ DPU_DEBUG_PLANE(pdpu, "Got clip src:" DRM_RECT_FMT " dst: " DRM_RECT_FMT "\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect), DRM_RECT_ARG(&pipe_cfg->dst_rect));
+
+ /* Split wide rect into 2 rect */
+ if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
+ _dpu_plane_calc_clk(mode, pipe_cfg) > max_mdp_clk_rate) {
+
+ if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
+ DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+ return -E2BIG;
+ }
+
+ memcpy(r_pipe_cfg, pipe_cfg, sizeof(struct dpu_sw_pipe_cfg));
+ pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
+ pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
+ r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
+ r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
+ DPU_DEBUG_PLANE(pdpu, "Split wide plane into:"
+ DRM_RECT_FMT " and " DRM_RECT_FMT "\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect),
+ DRM_RECT_ARG(&r_pipe_cfg->src_rect));
+ } else {
+ memset(r_pipe_cfg, 0, sizeof(struct dpu_sw_pipe_cfg));
+ }
- drm_rect_rotate_inv(&pipe_cfg->src_rect,
- new_plane_state->fb->width, new_plane_state->fb->height,
- new_plane_state->rotation);
- if (drm_rect_width(&r_pipe_cfg->src_rect) != 0)
- drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
- new_plane_state->fb->width, new_plane_state->fb->height,
+ drm_rect_rotate_inv(&pipe_cfg->src_rect,
+ new_plane_state->fb->width,
+ new_plane_state->fb->height,
new_plane_state->rotation);
+ if (drm_rect_width(&r_pipe_cfg->src_rect) != 0)
+ drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
+ new_plane_state->fb->width,
+ new_plane_state->fb->height,
+ new_plane_state->rotation);
+ }
+
return 0;
}
@@ -998,20 +1055,18 @@ static int dpu_plane_atomic_check_sspp(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[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];
- int ret = 0;
- ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg,
- &crtc_state->adjusted_mode,
- new_plane_state);
- 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,
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
+ pipe = &pstate->pipe[i];
+ pipe_cfg = &pstate->pipe_cfg[i];
+ if (!drm_rect_width(&pipe_cfg->src_rect))
+ continue;
+ 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)
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH v17 4/4] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2026-01-21 8:01 [PATCH v17 0/4] drm/msm/dpu: Support quad pipe with dual-interface Jun Nie
` (2 preceding siblings ...)
2026-01-21 8:01 ` [PATCH v17 3/4] drm/msm/dpu: support plane splitting in quad-pipe case Jun Nie
@ 2026-01-21 8:01 ` Jun Nie
3 siblings, 0 replies; 21+ messages in thread
From: Jun Nie @ 2026-01-21 8:01 UTC (permalink / raw)
To: Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Simona Vetter, Rob Clark, Neil Armstrong
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie,
Dmitry Baryshkov
To support high-resolution cases that exceed the width limitation of
a pair of SSPPs, or scenarios that surpass the maximum MDP clock rate,
additional pipes are necessary to enable parallel data processing
within the SSPP width constraints and MDP clock rate.
Pipe array is extended to 4. Request 4 mixers and 4 DSCs for
high-resolution cases where both DSC and dual interfaces are enabled
for virtual plane case. More use cases can be incorporated later if
quad-pipe capabilities are required.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/675418/
Link: https://lore.kernel.org/r/20250918-v6-16-rc2-quad-pipe-upstream-4-v16-10-ff6232e3472f@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 28 +++++++++++++++++------
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 29 ++++++++----------------
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +-
6 files changed, 36 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 87a934e3801f3..a7ca79564c523 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
struct dpu_crtc_state *crtc_state)
{
struct dpu_crtc_mixer *m;
- u32 crcs[CRTC_DUAL_MIXERS];
+ u32 crcs[CRTC_QUAD_MIXERS];
int rc = 0;
int i;
@@ -1328,6 +1328,7 @@ static struct msm_display_topology dpu_crtc_get_topology(
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
struct msm_display_topology topology = {0};
struct drm_encoder *drm_enc;
+ u32 num_rt_intf;
drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask)
dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state,
@@ -1341,11 +1342,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
* Dual display
* 2 LM, 2 INTF ( Split display using 2 interfaces)
*
+ * If DSC is enabled, try to use 4:4:2 topology if there is enough
+ * resource and virtual plane is enabled. Otherwise, use 2:2:2 topology.
+ *
* Single display
* 1 LM, 1 INTF
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
*
- * If DSC is enabled, use 2 LMs for 2:2:1 topology
+ * If DSC is enabled, use 2:2:1 topology
*
* Add dspps to the reservation requirements if ctm is requested
*
@@ -1357,14 +1361,24 @@ static struct msm_display_topology dpu_crtc_get_topology(
* (mode->hdisplay > MAX_HDISPLAY_SPLIT) check.
*/
- if (topology.num_intf == 2 && !topology.cwb_enabled)
- topology.num_lm = 2;
- else if (topology.num_dsc == 2)
+ num_rt_intf = topology.num_intf;
+ if (topology.cwb_enabled)
+ num_rt_intf--;
+
+ if (topology.num_dsc) {
+ if (dpu_use_virtual_planes &&
+ dpu_kms->catalog->dsc_count >= num_rt_intf * 2)
+ topology.num_dsc = num_rt_intf * 2;
+ else
+ topology.num_dsc = num_rt_intf;
+ topology.num_lm = topology.num_dsc;
+ } else if (num_rt_intf == 2) {
topology.num_lm = 2;
- else if (dpu_kms->catalog->caps->has_3d_merge)
+ } else if (dpu_kms->catalog->caps->has_3d_merge) {
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
- else
+ } else {
topology.num_lm = 1;
+ }
if (crtc_state->ctm)
topology.num_dspp = topology.num_lm;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 6eaba5696e8e6..455073c7025b0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -210,7 +210,7 @@ struct dpu_crtc_state {
bool bw_control;
bool bw_split_vote;
- struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
+ struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
uint64_t input_fence_timeout_ns;
@@ -218,10 +218,10 @@ struct dpu_crtc_state {
/* HW Resources reserved for the crtc */
u32 num_mixers;
- struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
+ struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
u32 num_ctls;
- struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
+ struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
enum dpu_crtc_crc_source crc_source;
int crc_frame_skip_count;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index eba1d52211f68..058a7c8727f7c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -55,7 +55,7 @@
#define MAX_PHYS_ENCODERS_PER_VIRTUAL \
(MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
-#define MAX_CHANNELS_PER_ENC 2
+#define MAX_CHANNELS_PER_ENC 4
#define MAX_CWB_PER_ENC 2
#define IDLE_SHORT_TIMEOUT 1
@@ -661,7 +661,6 @@ void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
struct msm_drm_private *priv = dpu_enc->base.dev->dev_private;
struct msm_display_info *disp_info = &dpu_enc->disp_info;
- struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
struct drm_connector *connector;
struct drm_connector_state *conn_state;
struct drm_framebuffer *fb;
@@ -675,22 +674,12 @@ void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
dsc = dpu_encoder_get_dsc_config(drm_enc);
- /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
- if (dsc) {
- /*
- * Use 2 DSC encoders, 2 layer mixers and 1 or 2 interfaces
- * when Display Stream Compression (DSC) is enabled,
- * and when enough DSC blocks are available.
- * This is power-optimal and can drive up to (including) 4k
- * screens.
- */
- WARN(topology->num_intf > 2,
- "DSC topology cannot support more than 2 interfaces\n");
- if (topology->num_intf >= 2 || dpu_kms->catalog->dsc_count >= 2)
- topology->num_dsc = 2;
- else
- topology->num_dsc = 1;
- }
+ /*
+ * Set DSC number as 1 to mark the enabled status, will be adjusted
+ * in dpu_crtc_get_topology()
+ */
+ if (dsc)
+ topology->num_dsc = 1;
connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
if (!connector)
@@ -2180,8 +2169,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
{
int i, num_lm;
struct dpu_global_state *global_state;
- struct dpu_hw_blk *hw_lm[2];
- struct dpu_hw_mixer *hw_mixer[2];
+ struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+ struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
/* reset all mixers for this encoder */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 61b22d9494546..09395d7910ac8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -302,7 +302,7 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
/* Use merge_3d unless DSC MERGE topology is used */
if (phys_enc->split_role == ENC_ROLE_SOLO &&
- dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
+ (dpu_cstate->num_mixers != 1) &&
!dpu_encoder_use_dsc_merge(phys_enc->parent))
return BLEND_3D_H_ROW_INT;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 4964e70610d1b..336757103b5af 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -24,7 +24,7 @@
#define DPU_MAX_IMG_WIDTH 0x3fff
#define DPU_MAX_IMG_HEIGHT 0x3fff
-#define CRTC_DUAL_MIXERS 2
+#define CRTC_QUAD_MIXERS 4
#define MAX_XIN_COUNT 16
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 046b683d4c66d..31451241f0839 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -34,7 +34,7 @@
#define DPU_MAX_PLANES 4
#endif
-#define STAGES_PER_PLANE 1
+#define STAGES_PER_PLANE 2
#define PIPES_PER_STAGE 2
#define PIPES_PER_PLANE (PIPES_PER_STAGE * STAGES_PER_PLANE)
#ifndef DPU_MAX_DE_CURVES
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread