mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v17 0/4] drm/msm/dpu: Support quad pipe with dual-interface
@ 2026-01-21  8:01 Jun Nie
  2026-01-21  8:01 ` [PATCH v17 1/4] drm/msm/dpu: Extract plane splitting into a dedicated function Jun Nie
                   ` (3 more replies)
  0 siblings, 4 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

2 or more SSPPs and dual-DSI interface are need for super wide panel.
And 4 DSC are preferred for power optimal in this case due to width
limitation of SSPP and MDP clock rate constrain. This patch set
extends number of pipes to 4 and revise related mixer blending logic
to support quad pipe. All these changes depends on the virtual plane
feature to split a super wide drm plane horizontally into 2 or more sub
clip. Thus DMA of multiple SSPPs can share the effort of fetching the
whole drm plane.

The first pipe pair co-work with the first mixer pair to cover the left
half of screen and 2nd pair of pipes and mixers are for the right half
of screen. If a plane is only for the right half of screen, only one
or two of pipes in the 2nd pipe pair are valid, and no SSPP or mixer is
assinged for invalid pipe.

For those panel that does not require quad-pipe, only 1 or 2 pipes in
the 1st pipe pair will be used. There is no concept of right half of
screen.

For legacy non virtual plane mode, the first 1 or 2 pipes are used for
the single SSPP and its multi-rect mode.

    Changes in v17:
    - Fix iommu warning on Hamoa.
    - Extract plane splitting into a dedicated function.
    - Defer plan splitting and SSPP allocation until CRTC check
      so that topology information is available.
    - Add virtual plane condition to quad-pipe topology so that
      legacy devices are not impacted.
    - Drop the merged 8 patches of v16, only the last 2 is revised
      and sent here.
    - Link to v16: https://lore.kernel.org/linux-arm-msm/20250918-v6-16-rc2-quad-pipe-upstream-4-v16-0-ff6232e3472f@linaro.org

    Changes in v16:
    - Rebase to latest branch msm-next-lumag.
    - Fix IGT test failures.
    - Drop patches that have been merged.
    - Link to v15: https://lore.kernel.org/r/20250819-v6-16-rc2-quad-pipe-upstream-v15-0-2c7a85089db8@linaro.org

    Changes in v15:
    - Polish logic in sspp check and assignment.
    - Link to v14: https://lore.kernel.org/r/20250801-v6-16-rc2-quad-pipe-upstream-v14-0-b626236f4c31@linaro.org

    Changes in v14:
    - Add patch to fix null pointer bug SSPP sharing, which is missed in
      the last version.
    - Polish single pipe check with removing loop.
    - Polish logic of SSPP sharing test in dpu_plane_virtual_assign_resources()
    - Polish argument of dpu_plane_virtual_assign_resources().
    - Link to v13: https://lore.kernel.org/r/20250728-v6-16-rc2-quad-pipe-upstream-v13-0-954e4917fe4f@linaro.org

    Changes in v13:
    - Modify the SSPP assignment patch for sharing SSPP among planes in
      quad-pipe case.
    - Link to v12: https://lore.kernel.org/r/20250707-v6-16-rc2-quad-pipe-upstream-v12-0-67e3721e7d83@linaro.org

    Changes in v12:
    - Polish single pipe case detection in a plane. Add stage index check when
      sharing SSPP with multi-rect mode in 2 planes.
    - Abstract SSPP assignment in a stage into a function.
    - Rebase to latest msm/msm-next.
    - Link to v11: https://lore.kernel.org/r/20250603-v6-15-quad-pipe-upstream-v11-0-c3af7190613d@linaro.org

    Changes in v11:
    - Change function name from dpu_plane_check_single_pipe to
      dpu_plane_get_single_pipe.
    - Abstract SSPP assignment in stage into a function.
    - Link to v10: https://lore.kernel.org/r/20250526-v6-15-quad-pipe-upstream-v10-0-5fed4f8897c4@linaro.org

    Changes in v10:
    - Drop changes in drm helper side, because num_lm == 0 does not lead to
      any issue in the first call to dpu_plane_atomic_check_nosspp() with
      latest repo. It is initialized properly right after the call in
      drm_atomic_helper_check_planes(), thus the later plane splitting works
      as expected.
    - Rebase to latest msm-next branch.
    - Fix PIPES_PER_STAGE to PIPES_PER_PLANE where handling all pipes, instead
      of stages.
    - Link to v9: https://lore.kernel.org/r/20250506-quad-pipe-upstream-v9-0-f7b273a8cc80@linaro.org

    Changes in v9:
    - Rebase to latest mainline and drop 3 patches as mainline already cover
      the logic.
      "Do not fix number of DSC"
      "configure DSC per number in use"
      "switch RM to use crtc_id rather than enc_id for allocation"
    - Add a patch to check crtc before checking plane in drm framework.
    - Add a patch to use dedicated WB number in an encoder to avoid regression.
    - Revise the condition to decide quad-pipe topology.
    - Link to v8: https://lore.kernel.org/r/20250303-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v8-0-eb5df105c807@linaro.org

    Changes in v8:
    - Fix looping pipes of a plane in _dpu_plane_color_fill()
    - Improve pipe assignment with deleting pipes loop in stage.
    - Define PIPES_PER_PLANE properly when it appears fisrt.
    - rename lms_in_pair to lms_in_stage to avoid confusion.
    - Add review tags.
    - Link to v7: https://lore.kernel.org/r/20250226-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v7-0-8d5f5f426eb2@linaro.org

    Changes in v7:
    - Improve pipe assignment to avoid point to invalid memory.
    - Define STAGES_PER_PLANE as 2 only when quad-pipe is introduced.
    - Polish LM number when blending pipes with min() and pull up to caller func.
    - Add review tags.
    - Link to v6: https://lore.kernel.org/r/20250217-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v6-0-c11402574367@linaro.org

    Changes in v6:
    - Replace LM number with PP number to calculate PP number per encoder.
    - Rebase to Linux v6.14-rc2.
    - Add review tags.
    - Link to v5: https://lore.kernel.org/r/20250118-sm8650-v6-13-hmd-deckard-mdss-quad-upstream-33-v5-0-9701a16340da@linaro.org

    Changes in v5:
    - Iterate SSPP flushing within the required mixer pair, instead of all
      active mixers or specific mixer.
    - Limit qaud-pipe usage case to SoC with 4 or more DSC engines and 2
      interfaces case.
    - Remove valid flag and use width for pipe validation.
    - Polish commit messages and code comments.
    - Link to v4: https://lore.kernel.org/r/20250116-sm8650-v6-13-hmd-deckard-mdss-quad-upstream-33-v4-0-74749c6eba33@linaro.org

    Changes in v4:
    - Restrict SSPP flushing to the required mixer, instead of all active mixers.
    - Polish commit messages and code comments.
    - Rebase to latest msm/drm-next branch.
    - Move pipe checking patch to the top of patch set.
    - Link to v3: https://lore.kernel.org/dri-devel/20241219-sm8650-v6-13-hmd-deckard-mdss-quad-upstream-32-v3-0-92c7c0a228e3@linaro.org

    Changes in v3:
    - Split change in trace into a separate patch.
    - Rebase to latest msm-next branch.
    - Reorder patch sequence to make sure valid flag is set in earlier patch
    - Rectify rewrite patch to move logic change into other patch
    - Polish commit messages and code comments.
    - Link to v2: https://lore.kernel.org/dri-devel/20241009-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-21-v2-0-76d4f5d413bf@linaro.org

    Changes in v2:
    - Revise the patch sequence with changing to 2 pipes topology first. Then
      prepare for quad-pipe setup, then enable quad-pipe at last.
    - Split DSI patches into other patch set.
    - Link to v1: https://lore.kernel.org/all/20240829-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-8-v1-0-bdb05b4b5a2e@linaro.org

To: Abhinav Kumar <abhinav.kumar@linux.dev>
To: Dmitry Baryshkov <lumag@kernel.org>
To: Sean Paul <sean@poorly.run>
To: Marijn Suijten <marijn.suijten@somainline.org>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
To: Rob Clark <robin.clark@oss.qualcomm.com>
To: Neil Armstrong <neil.armstrong@linaro.org>
Cc: linux-arm-msm@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedreno@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
Jun Nie (4):
      drm/msm/dpu: Extract plane splitting into a dedicated function
      drm/msm/dpu: Defer SSPP allocation until CRTC check
      drm/msm/dpu: support plane splitting in quad-pipe case
      drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c         |  42 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h         |   8 +-
 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 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c        | 270 ++++++++++++++++-------
 7 files changed, 237 insertions(+), 118 deletions(-)
---
base-commit: 837f96989da508a94e1db77e6c5ba36a60dd010b
change-id: 20260121-msm-next-quad-pipe-split-ab95b6e3ffd3

Best regards,
-- 
Jun Nie <jun.nie@linaro.org>


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [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

* [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

* [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

* 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 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 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

* 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

end of thread, other threads:[~2026-02-06 10:48 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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  9:28   ` Dmitry Baryshkov
2026-01-21  9:47     ` 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  9:30   ` Dmitry Baryshkov
2026-01-22  6:03     ` Jun Nie
2026-01-22 10:22       ` Dmitry Baryshkov
2026-01-26 10:06         ` Jun Nie
2026-01-26 10:13           ` Dmitry Baryshkov
2026-01-26 10:29             ` Jun Nie
2026-01-26 10:49               ` Dmitry Baryshkov
2026-01-26 12:01                 ` Jun Nie
2026-01-26 12:31                   ` Dmitry Baryshkov
2026-01-26 13:29                     ` Jun Nie
2026-01-26 19:06                       ` Dmitry Baryshkov
2026-02-02  7:15                         ` Jun Nie
2026-02-04  2:43                           ` Dmitry Baryshkov
2026-02-06 10:48                             ` Jun Nie
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®